• Martin KaFai Lau's avatar
    bpf: Stop caching subprog index in the bpf_pseudo_func insn · 3990ed4c
    Martin KaFai Lau authored
    This patch is to fix an out-of-bound access issue when jit-ing the
    bpf_pseudo_func insn (i.e. ld_imm64 with src_reg == BPF_PSEUDO_FUNC)
    
    In jit_subprog(), it currently reuses the subprog index cached in
    insn[1].imm.  This subprog index is an index into a few array related
    to subprogs.  For example, in jit_subprog(), it is an index to the newly
    allocated 'struct bpf_prog **func' array.
    
    The subprog index was cached in insn[1].imm after add_subprog().  However,
    this could become outdated (and too big in this case) if some subprogs
    are completely removed during dead code elimination (in
    adjust_subprog_starts_after_remove).  The cached index in insn[1].imm
    is not updated accordingly and causing out-of-bound issue in the later
    jit_subprog().
    
    Unlike bpf_pseudo_'func' insn, the current bpf_pseudo_'call' insn
    is handling the DCE properly by calling find_subprog(insn->imm) to
    figure out the index instead of caching the subprog index.
    The existing bpf_adj_branches() will adjust the insn->imm
    whenever insn is added or removed.
    
    Instead of having two ways handling subprog index,
    this patch is to make bpf_pseudo_func works more like
    bpf_pseudo_call.
    
    First change is to stop caching the subprog index result
    in insn[1].imm after add_subprog().  The verification
    process will use find_subprog(insn->imm) to figure
    out the subprog index.
    
    Second change is in bpf_adj_branches() and have it to
    adjust the insn->imm for the bpf_pseudo_func insn also
    whenever insn is added or removed.
    
    Third change is in jit_subprog().  Like the bpf_pseudo_call handling,
    bpf_pseudo_func temporarily stores the find_subprog() result
    in insn->off.  It is fine because the prog's insn has been finalized
    at this point.  insn->off will be reset back to 0 later to avoid
    confusing the userspace prog dump tool.
    
    Fixes: 69c087ba ("bpf: Add bpf_for_each_map_elem() helper")
    Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Link: https://lore.kernel.org/bpf/20211106014014.651018-1-kafai@fb.com
    3990ed4c
verifier.c 401 KB