Re: [PATCH bpf-next v5 10/16] bpf: Reject stack arguments if tail call reachable

Yonghong Song
2026-04-18T17:25:13Z

On 4/17/26 6:04 PM, bot+bpf-ci@kernel.org wrote:
>> bpf: Reject stack arguments if tail call reachable
>>
>> Tailcalls are been deprecated. So reject stack arguments
> This isn't a bug, but there's a grammar error: 'are been' should be
> 'have been' or 'are being'.
>
> The commit message states that "Tailcalls are been deprecated." Is this
> claim accurate?
>
> Based on earlier mailing list discussion, the restriction exists because
> tail calls and stack arguments require incompatible stack frame handling,
> not because tail calls are being deprecated.
>
> Could the commit message be more precise about the actual technical reason
> for the restriction?

Stack arguments and tail calls CAN work together. However, since tail calls
are in deprecation stage, it is not worthwhile to involve stack arguments
and tail calls together.

I will keep commit message as is.

> This commit appears to fix a bug but lacks a Fixes: tag. The suggested tag
> would be:
>
> Fixes: 13ee5d67a7c9 ("bpf: Support stack arguments for bpf functions")
>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 7a65b532e84a..739c3127520c 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -5662,6 +5662,11 @@ static int check_max_stack_depth_subprog(struct bpf_verifier_env *env, int idx,
>> verbose(env, "cannot tail call within exception cb\n");
>> return -EINVAL;
>> }
>> + if (subprog[tmp].incoming_stack_arg_depth ||
>> + subprog[tmp].outgoing_stack_arg_depth) {
>> + verbose(env, "tail_calls are not allowed in programs with stack args\n");
>> + return -EINVAL;
>> + }
>> subprog[tmp].tail_call_reachable = true;
>> }
>> if (subprog[0].tail_call_reachable)
> When the DFS traversal in check_max_stack_depth_subprog() pops a frame to
> return to the caller (moving from a child subprogram back to its parent),
> is the tail_call_reachable variable reset to false?
>
> Looking at the code, tail_call_reachable is initialized at the function
> start but appears to persist across the entire traversal. Consider this
> scenario:
>
> 1. The verifier traverses a subprogram that contains a tail call, setting
> tail_call_reachable = true
> 2. The traversal returns to the parent (pops the frame via idx =
> dinfo[idx].caller)
> 3. The traversal then visits a sibling subprogram that uses stack arguments
>
> In this scenario, wouldn't tail_call_reachable still be true from step 1,
> causing the check in the new code to incorrectly reject the sibling
> subprogram even though it has no tail calls in its own call chain?
>
> This could cause false positive rejections of valid BPF programs where one
> subprogram uses tail calls and a completely unrelated sibling subprogram
> uses stack arguments.
>
>
> ---
> 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/24592562564