diff options
| author | Amery Hung <ameryhung@gmail.com> | 2026-09-11 15:04:01 -0700 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-09-11 20:16:03 -0700 |
| commit | 57e181cde7e6bfbb90fcd60d1e96153f529ffe2e (patch) | |
| tree | 36cd2dc95a5b61a72fd1ee5ed31f10e79eea8cc5 /kernel | |
| parent | 0cc91f0e72415cbd17697e2f8fd0cd8de5c7aae9 (diff) | |
| download | linux-next-57e181cde7e6bfbb90fcd60d1e96153f529ffe2e.tar.gz linux-next-57e181cde7e6bfbb90fcd60d1e96153f529ffe2e.zip | |
bpf: Set OBJ_RELEASE when generating kfunc argument types
check_kfunc_args() ORs OBJ_RELEASE into arg_type on every verification
of every argument of every call, from a comparison against
meta->release_regno. Neither side of that comparison depends on the
call site. bpf_fetch_kfunc_arg_meta() sets release_regno to BPF_REG_1
when the kfunc is KF_RELEASE and leaves it zero otherwise, and regno
is derived from the argument index, so the test is true exactly for
argument 0 of a KF_RELEASE kfunc.
Set the flag in get_kfunc_arg_type() instead, where the rest
of the classification is built, and drop the comparison. The release
handling in check_func_proto() is helper-only, so an OBJ_RELEASE in a
generated kfunc prototype does not feed back into meta->release_regno.
meta->release_regno itself stays: it is still what tells the referenced
PTR_TO_BTF_ID check and release_reg() which register to act on.
No functional change.
Signed-off-by: Amery Hung <ameryhung@gmail.com>
Link: https://lore.kernel.org/r/20260911220415.1396439-10-ameryhung@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/verifier.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c7822addfc64..20e7da6674a1 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -12311,6 +12311,13 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta, if (is_kfunc_arg_nullable(meta->btf, &args[arg])) arg_type |= PTR_MAYBE_NULL; + /* + * Only the first argument of a KF_RELEASE kfunc releases anything, and + * bpf_fetch_kfunc_arg_meta() only ever records BPF_REG_1 for it. + */ + if (is_kfunc_release(meta) && arg == 0) + arg_type |= OBJ_RELEASE; + return arg_type; } @@ -12997,8 +13004,6 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me ref_tname = btf_name_by_offset(btf, ref_t->name_off); } - if (regno == meta->release_regno) - arg_type |= OBJ_RELEASE; ret = check_func_arg_reg_off(env, reg, argno, arg_type); if (ret < 0) return ret; |
