]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bpf: Fix tail_call_reachable leak
authorYonghong Song <yonghong.song@linux.dev>
Thu, 23 Apr 2026 03:34:35 +0000 (20:34 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 23 Apr 2026 14:54:50 +0000 (07:54 -0700)
In check_max_stack_depth_subprog(), the local variable
tail_call_reachable is set when entering a callee that has a tail
call, but never reset when popping back to the parent. This causes
the flag to leak across sibling subprogs in the DFS traversal.

This results in unnecessary JIT overhead: the JIT emits tail call
counter preservation code for subprogs that can never be reached
via a tail call path.

Fix this by resetting tail_call_reachable to the parent's actual
per-subprog flag when popping a frame. If the parent was already
marked tail_call_reachable by a previous sibling's traversal, the
local variable stays true. Otherwise it resets to false, so
subsequent siblings start with a clean state.

Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20260423033435.2538013-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index 6118743d87e6cadd5d34df0d0ebc4cce4b881e87..26b6cdfd8613329974899e0f6decb3132f50e927 100644 (file)
@@ -5490,6 +5490,9 @@ continue_func:
        frame = dinfo[idx].frame;
        i = dinfo[idx].ret_insn;
 
+       /* reset tail_call_reachable to the parent's actual state */
+       tail_call_reachable = subprog[idx].tail_call_reachable;
+
        goto continue_func;
 }