bpf: Discover subprogs described by func_info

add_subprogs() finds subprogs by scanning insns for calls and ld_imm64
BPF_PSEUDO_FUNC. A function that is called via callx through a pointer
in data only, e.g. a vtable, is not referenced by any insn, but it must
be known before check_cfg() and the main pass.

func_info describes all functions of the program and libbpf provides it
for every function it puts into the prog. bpf_prepare_btf_info() reads
it before add_subprogs(). Register every function from func_info as
a subprog.

func_info had to match the subprogs found in insns exactly, so existing
programs are not affected. A function that is listed in func_info and
not referenced by anything is still rejected by check_cfg() as
unreachable.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260924031042.1690890-10-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-09-24 03:10:34 +00:00
parent 11a516144d
commit 3a03595510
No known key found for this signature in database

View File

@ -3023,6 +3023,22 @@ static int add_subprogs(struct bpf_verifier_env *env)
return ret;
}
/*
* func_info describes all functions of the program. Those that are
* referenced only from data, e.g. from a table of functions to be
* called via callx, are not seen by the loop above. They are possible
* callees that have to be known upfront as well.
*/
if (env->bpf_capable) {
struct bpf_prog_aux *aux = env->prog->aux;
for (i = 1; i < aux->func_info_cnt; i++) {
ret = add_subprog(env, aux->func_info[i].insn_off);
if (ret < 0)
return ret;
}
}
ret = bpf_find_exception_callback_insn_off(env);
if (ret < 0)
return ret;