mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
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:
parent
f89ebf0749
commit
07684726d3
|
|
@ -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
|
||||
----------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user