bpf: Don't turn struct arguments of KF_ACQUIRE kfuncs into memory

When a kfunc takes a pointer to a struct that has only scalar members, the
verifier also accepts memory of the prog. Then resolve_func_arg_type()
changes ARG_PTR_TO_BTF_ID to ARG_PTR_TO_MEM. This is correct for a struct
of parameters. But struct bpf_cpumask also has only scalar members, and the
kernel allocates and frees it. Thus bpf_cpumask_acquire() returns memory of
the prog as a referenced object, and bpf_cpumask_release() can free it.

The verifier does not change the argument that a kfunc releases. KF_ACQUIRE
does not say which argument is the object. Thus do not change any argument
of a KF_ACQUIRE kfunc. Then the verifier rejects memory there. No other
KF_ACQUIRE kfunc takes memory in an ARG_PTR_TO_BTF_ID argument. Add to
kfuncs.rst that a KF_ACQUIRE kfunc must pair a struct of parameters with a
__sz argument.

The first commit below added the bug. Later the struct had pointers in an
rcu_head, so the verifier rejected memory. The second commit removed them.

Fixes: 516f4d3397 ("bpf: Enable cpumasks to be queried and used as kptrs")
Fixes: 8e07bb9ebc ("bpf: Convert bpf_cpumask to bpf_mem_cache_free_rcu.")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261101190535.1454146-10-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-11-01 19:05:17 +00:00
parent f89ebf0749
commit 07684726d3
No known key found for this signature in database
2 changed files with 12 additions and 0 deletions

View File

@ -407,6 +407,13 @@ referenced kptr (by invoking bpf_kptr_xchg). If not, the verifier fails the
loading of the BPF program until no lingering references remain in all possible
explored states of the program.
A pointer to a struct in the arguments of a KF_ACQUIRE kfunc accepts only an
object of that type. The same applies to the argument that a KF_RELEASE kfunc
releases. For other arguments a kfunc also accepts memory of the program, if the
struct has only scalar members. struct __sk_buff and struct xdp_md never accept
memory. A KF_ACQUIRE kfunc which wants such memory has to pair the pointer with
a __sz argument.
2.5.2 KF_RET_NULL flag
----------------------

View File

@ -13574,7 +13574,12 @@ static int resolve_func_arg_type(struct bpf_verifier_env *env,
if (base_type(*arg_type) != ARG_PTR_TO_BTF_ID)
return 0;
/*
* A kfunc that releases an object, or that takes a reference to one,
* needs the object itself: memory of the program cannot stand in for it.
*/
if (!is_kfunc(meta) || arg_type_is_release(*arg_type) ||
is_kfunc_acquire(meta) ||
base_type(reg->type) == PTR_TO_BTF_ID ||
reg2btf_ids[base_type(reg->type)])
return 0;