Re: [PATCH v2 bpf] bpf: properly verify tail call behavior

Alexei Starovoitov
2025-11-04T18:06:05Z

On Tue, Nov 4, 2025 at 5:58 AM <bot+bpf-ci@kernel.org> wrote:
>
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index ff40e5e65..4b7439a48 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
>
> [ ... ]
>
> > @@ -11884,6 +11888,24 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
> > env->prog->call_get_func_ip = true;
> > }
> >
> > + if (func_id == BPF_FUNC_tail_call) {
> > + if (env->cur_state->curframe) {
> > + struct bpf_verifier_state *branch;

add empty line.

> > + mark_reg_scratched(env, BPF_REG_0);
> > + branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
> > + if (IS_ERR(branch))
> > + return PTR_ERR(branch);
>
> Can push_stack() return an ERR_PTR? Looking at the push_stack()
> function in verifier.c, it returns NULL on all error paths (allocation
> failure at line 2095, copy failure at line 2105, and stack overflow at
> line 2110). Every other call site in the verifier checks for NULL:
>
> - cluster_alloc_swap_entry() at line 9017: if (!queued_st)
> - push_callback_call() at line 10608: if (!callback_state)
> - check_reference_leaks_function() at line 13852: if (!branch)
> - check_cond_jmp_op() at line 14314: if (branch && insn)
> - check_iter_next_call() at line 16739: if (!queued_st)
> - do_check() at line 16858: if (!other_branch)
>
> If push_stack() returns NULL due to memory pressure, IS_ERR(NULL)
> evaluates to false, so the error check won't trigger and the code will
> continue with a NULL branch pointer.

AI is correct, since it reviewed the patch against bpf tree
where push_stack() returns NULL.

This is a non-trivial change. If we land it it will go to bpf-next.
So pls respin with bpf-next tag, so CI can process it properly.

Overall it's an interesting idea!

pw-bot: cr