Re: [PATCH bpf-next v5 11/14] bpf: Report Call Type Safety argument errors
Eduard Zingerman <[email protected]>
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
On Sat, 2026-08-15 at 07:49 +0000, [email protected] wrote: > > diff --git a/kernel/bpf/diagnostics.c b/kernel/bpf/diagnostics.c > > index 5d20ea9e470e..99784d465881 100644 > > --- a/kernel/bpf/diagnostics.c > > +++ b/kernel/bpf/diagnostics.c > > [ ... ] > > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > > index f5bf8cf644b8..2c067be53106 100644 > > --- a/kernel/bpf/verifier.c > > +++ b/kernel/bpf/verifier.c > > [ ... ] > > > @@ -12417,29 +12552,43 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me > > > > t = btf_type_skip_modifiers(btf, args[i].type, NULL); > > > > - if (btf_type_is_ptr(t) && (bpf_register_is_null(reg) || type_may_be_null(reg->type)) && > > + if (btf_type_is_ptr(t)) { > > + ref_t = btf_type_skip_modifiers(btf, t->type, &ref_id); > > + ref_tname = btf_name_by_offset(btf, ref_t->name_off); > > + } > > + > > + if (btf_type_is_ptr(t) && > > + (bpf_register_is_null(reg) || type_may_be_null(reg->type)) && > > !type_may_be_null(kf_arg_type)) { > > + const char *expected_type; > > + > > + expected_type = bpf_diag_fmt_btf_type(env, btf, ref_id); > > verbose(env, "Possibly NULL pointer passed to trusted %s\n", > > reg_arg_name(env, argno)); > > + bpf_diag_call_arg_fmt(env, insn_idx, argno, func_name, > > + "Add a NULL check and call the kfunc only on the non-NULL path.", > > + "the pointer may be NULL, but this kfunc requires a non-NULL pointer to %s", > > + expected_type); > > return -EACCES; > > } > > > > if (regno == meta->release_regno && !is_kfunc_arg_dynptr(meta->btf, &args[i]) && > > !reg_is_referenced(env, reg) && !bpf_register_is_null(reg)) { > > + const char *expected_type; > > + > > + expected_type = bpf_diag_fmt_btf_type(env, btf, ref_id); > > verbose(env, "release kfunc %s expects referenced PTR_TO_BTF_ID passed to %s\n", > > func_name, reg_arg_name(env, argno)); > > + bpf_diag_call_arg_fmt(env, insn_idx, argno, func_name, > > + "Pass the resource-owning pointer returned by the matching acquire kfunc, and avoid calling the release kfunc after ownership has already been transferred or released.", > > + "release kfuncs require a resource-owning value of type %s returned by a matching acquire kfunc", > > + expected_type); > > return -EINVAL; > > } > > When the kfunc parameter is a plain void*, will bpf_diag_fmt_btf_type() > format it correctly? For a void* parameter, ref_id becomes 0 after > btf_type_skip_modifiers() and bpf_diag_fmt_btf_type() produces the > literal string "()" for type ID 0. This is legit btf.c:btf_show_name() needs a fix: --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -1172,9 +1172,9 @@ static const char *btf_show_name(struct btf_show *show) id = 0; break; } + t = btf_type_skip_qualifiers(show->btf, id); if (!id) break; - t = btf_type_skip_qualifiers(show->btf, id); } /* We may not be able to represent this type; bail to be safe */ if (i == BTF_SHOW_MAX_ITER) ...