Re: [PATCH v2 1/2] bpf: reject stack-argument callback subprograms

[email protected]
Newsgroups org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest
Message-ID <e304b97889065108a5b2a41908329bb9d38a7c23837a6861ce3b21302aaf7eed@mail.kernel.org>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index e421ea2b80c3..6f6e35bc7c97 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -9785,6 +9785,8 @@ static int push_callback_call(struct bpf_verifier_env *env, struct bpf_insn *ins
>  	err = btf_check_subprog_call(env, subprog, caller->regs);
>  	if (err == -EFAULT)
>  		return err;
> +	if (bpf_in_stack_arg_cnt(&env->subprog_info[subprog]))
> +		return -EINVAL;

Should this rejection include a verbose() message explaining why the
callback was rejected? Currently this returns a bare -EINVAL, which means
bpf_loop(), bpf_for_each_map_elem(), bpf_timer_set_callback(), bpf_find_vma(),
and bpf_user_ringbuf_drain() with a callback that has more than five
arguments will fail with EINVAL but nothing in the verifier log shows why.

check_helper_call() propagates the error silently for all five of those
helpers. Only the three kfunc callback sites (in check_kfunc_call()) add
"kfunc %s#%d failed callback verification".

Every other stack-argument rejection in this feature logs a message before
returning: check_stack_arg_read() reports "invalid read from stack arg off
%d depth %d", check_stack_arg_write() reports "stack arg write offset %d
exceeds max %d stack args", check_outgoing_stack_args() reports "callee
expects %d args, stack arg%d is not initialized", and bpf_fixup_call_args()
reports "func#%d writes %u stack arg slots, but calls only require %u".

This is the path the patch is meant to reject. For the other outcome (the
caller's outgoing slots are not initialized), btf_check_subprog_call()
returns -EFAULT and the existing message is printed, and push_callback_call()
returns before this new check.

All other error paths in push_callback_call() also log: verifier_bug() for
the two internal consistency checks, and verbose() inside
setup_func_entry() or push_stack().

>
>  	/* set_callee_state is used for direct subprog calls, but we are
>  	 * interested in validating only BPF helpers that can call subprogs as


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/32068993990
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.