Re: [PATCH bpf-next v4 13/18] bpf: Support stack arguments for kfunc calls

Yonghong Song
2026-04-13T16:44:14Z

On 4/11/26 10:43 PM, bot+bpf-ci@kernel.org wrote:
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 45987041bb2a..206ffbd9596d 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
> [ ... ]
>
>> @@ -13848,9 +13858,9 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
>>
>> args = (const struct btf_param *)(meta->func_proto + 1);
>> nargs = btf_type_vlen(meta->func_proto);
>> - if (nargs > MAX_BPF_FUNC_REG_ARGS) {
>> + if (nargs > MAX_BPF_FUNC_ARGS) {
>> verbose(env, "Function %s has %d > %d args\n", func_name, nargs,
>> - MAX_BPF_FUNC_REG_ARGS);
>> + MAX_BPF_FUNC_ARGS);
>> return -EINVAL;
>> }
> [ ... ]
>
>> @@ -15152,6 +15198,16 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
>> mark_btf_func_reg_size(env, regno, t->size);
>> }
> With nargs now allowed up to MAX_BPF_FUNC_ARGS (12), the existing
> mark_btf_func_reg_size loop in check_kfunc_call() iterates beyond
> register arguments:
>
> for (i = 0; i < nargs; i++) {
> u32 regno = i + 1;
> ...
> mark_btf_func_reg_size(env, regno, t->size);
> }
>
> This calls __mark_btf_func_reg_size() with &regs[regno] where
> regs is bpf_func_state.regs[MAX_BPF_REG] and MAX_BPF_REG is 11.
>
> For nargs 6-10, the loop incorrectly calls mark_insn_zext() on
> callee-saved registers R6-R9 or the frame pointer R10. These
> registers are not cleared by the caller-saved register loop above,
> so if the BPF program wrote a 32-bit value to R6 before the kfunc
> call, mark_insn_zext() would set zext_dst on that unrelated
> instruction and clear the register's subreg_def.
>
> For nargs >= 11 (MAX_BPF_FUNC_ARGS is 12), regs[11] is an
> out-of-bounds access that overlaps bpf_func_state.callsite.

Thanks for pointing out. The for loop stays as is. What need to
do is change 'regno' to 'reg' which is a pointer to bpf_reg_state.
Will fix.

>
> Should this loop be bounded to register args only, similar to what
> v1 of this patch had?
>
> for (i = 0; i < nargs && i < MAX_BPF_FUNC_REG_ARGS; i++) {
>
>> + /* Track outgoing stack arg depth for kfuncs with >5 args */
>> + if (nargs > MAX_BPF_FUNC_REG_ARGS) {
>> + struct bpf_func_state *caller = cur_func(env);
>> + struct bpf_subprog_info *caller_info = &env->subprog_info[caller->subprogno];
>> + u16 kfunc_stack_arg_depth = (nargs - MAX_BPF_FUNC_REG_ARGS) * BPF_REG_SIZE;
>> +
>> + if (kfunc_stack_arg_depth > caller_info->outgoing_stack_arg_depth)
>> + caller_info->outgoing_stack_arg_depth = kfunc_stack_arg_depth;
>> + }
>
> ---
> 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/24299298635