Skip to content

Commit 4c7e27e

Browse files
Amery Hungjfvogel
authored andcommitted
bpf: Search and add kfuncs in struct_ops prologue and epilogue
[ Upstream commit d519594ee2445d7cd1ad51f4db4cee58f8213400 ] Currently, add_kfunc_call() is only invoked once before the main verification loop. Therefore, the verifier could not find the bpf_kfunc_btf_tab of a new kfunc call which is not seen in user defined struct_ops operators but introduced in gen_prologue or gen_epilogue during do_misc_fixup(). Fix this by searching kfuncs in the patching instruction buffer and add them to prog->aux->kfunc_tab. Signed-off-by: Amery Hung <[email protected]> Acked-by: Eduard Zingerman <[email protected]> Acked-by: Martin KaFai Lau <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 673dde8d3c3ec97d10312caced2143194873de6f) Signed-off-by: Jack Vogel <[email protected]>
1 parent 40d7394 commit 4c7e27e

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

kernel/bpf/verifier.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2987,6 +2987,21 @@ bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
29872987
return res ? &res->func_model : NULL;
29882988
}
29892989

2990+
static int add_kfunc_in_insns(struct bpf_verifier_env *env,
2991+
struct bpf_insn *insn, int cnt)
2992+
{
2993+
int i, ret;
2994+
2995+
for (i = 0; i < cnt; i++, insn++) {
2996+
if (bpf_pseudo_kfunc_call(insn)) {
2997+
ret = add_kfunc_call(env, insn->imm, insn->off);
2998+
if (ret < 0)
2999+
return ret;
3000+
}
3001+
}
3002+
return 0;
3003+
}
3004+
29903005
static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
29913006
{
29923007
struct bpf_subprog_info *subprog = env->subprog_info;
@@ -19768,7 +19783,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
1976819783
{
1976919784
struct bpf_subprog_info *subprogs = env->subprog_info;
1977019785
const struct bpf_verifier_ops *ops = env->ops;
19771-
int i, cnt, size, ctx_field_size, delta = 0, epilogue_cnt = 0;
19786+
int i, cnt, size, ctx_field_size, ret, delta = 0, epilogue_cnt = 0;
1977219787
const int insn_cnt = env->prog->len;
1977319788
struct bpf_insn *epilogue_buf = env->epilogue_buf;
1977419789
struct bpf_insn *insn_buf = env->insn_buf;
@@ -19797,6 +19812,10 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
1979719812
return -ENOMEM;
1979819813
env->prog = new_prog;
1979919814
delta += cnt - 1;
19815+
19816+
ret = add_kfunc_in_insns(env, epilogue_buf, epilogue_cnt - 1);
19817+
if (ret < 0)
19818+
return ret;
1980019819
}
1980119820
}
1980219821

@@ -19817,6 +19836,10 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
1981719836

1981819837
env->prog = new_prog;
1981919838
delta += cnt - 1;
19839+
19840+
ret = add_kfunc_in_insns(env, insn_buf, cnt - 1);
19841+
if (ret < 0)
19842+
return ret;
1982019843
}
1982119844
}
1982219845

0 commit comments

Comments
 (0)