Re: [PATCH bpf-next v4 09/18] bpf: Support stack arguments for bpf functions

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

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

> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 01df990f841a..e664d924e8d4 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c

[ ... ]

> @@ -22383,11 +22682,11 @@ static int check_and_resolve_insns(struct bpf_verifier_env *env)
> return err;
>
> for (i = 0; i < insn_cnt; i++, insn++) {
> - if (insn->dst_reg >= MAX_BPF_REG) {
> + if (insn->dst_reg >= MAX_BPF_REG && insn->dst_reg != BPF_REG_STACK_ARG_BASE) {
> verbose(env, "R%d is invalid\n", insn->dst_reg);
> return -EINVAL;
> }
> - if (insn->src_reg >= MAX_BPF_REG) {
> + if (insn->src_reg >= MAX_BPF_REG && insn->src_reg != BPF_REG_STACK_ARG_BASE) {
> verbose(env, "R%d is invalid\n", insn->src_reg);
> return -EINVAL;
> }

This allows r12 (BPF_REG_STACK_ARG_BASE) through the register
validation for all instruction classes, but only BPF_LDX, BPF_STX,
and BPF_ST have explicit early-return handling for r12. What happens
if a BPF program uses r12 as src_reg or dst_reg in an ALU or JMP
instruction?

As far as I can tell, the path would be:

check_alu_op() or check_cond_jmp_op()
check_reg_arg(env, 12, ...)
__check_reg_arg(env, regs, 12, ...)
reg = &regs[12];

The regs array is struct bpf_reg_state regs[MAX_BPF_REG] with
MAX_BPF_REG = 11 (indices 0-10), so regs[12] is an out-of-bounds
access into whatever follows the regs array in bpf_func_state.

Would it make sense to restrict the r12 exemption here to only the
instruction classes that actually handle it (BPF_LDX, BPF_STX,
BPF_ST), rather than allowing it globally?

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