[PATCH bpf-next v2 2/9] bpf: Fix tail_call_reachable leak

Yonghong Song
2026-04-22T05:42:09Z

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>
---
kernel/bpf/verifier.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a768359b22cb..34696af96b3e 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5490,6 +5490,9 @@ static int check_max_stack_depth_subprog(struct bpf_verifier_env *env, int idx,
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;
}

--
2.52.0