summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAmery Hung <ameryhung@gmail.com>2026-09-11 15:04:01 -0700
committerAlexei Starovoitov <ast@kernel.org>2026-09-11 20:16:03 -0700
commit57e181cde7e6bfbb90fcd60d1e96153f529ffe2e (patch)
tree36cd2dc95a5b61a72fd1ee5ed31f10e79eea8cc5 /kernel
parent0cc91f0e72415cbd17697e2f8fd0cd8de5c7aae9 (diff)
downloadlinux-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.c9
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;