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

bot+bpf-ci
2026-04-12T05:43:16Z

[-- Attachment #1: Type: text/plain, Size: 2562 bytes --]

> 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.

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