diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst index 73578a4c3b1f..329d1510b02a 100644 --- a/Documentation/bpf/kfuncs.rst +++ b/Documentation/bpf/kfuncs.rst @@ -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 ---------------------- diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 89c0f0304341..ac56e7642432 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -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;