selftests/bpf: Test direct tail calls from callbacks

tailcall_callback tests a tail call one static subprogram below a callback.
That reaches the later stack-depth rejection, but it does not exercise the
tail-call helper while the current frame is itself a callback.

Add a callback that calls bpf_tail_call directly and expect the existing
"cannot tail call within callback" diagnostic. On an affected kernel, the
load instead reaches the "callback unexpected regs" verifier bug, so the
expected message is absent and the test fails. The existing ordinary
subprogram case remains a success control for legitimate tail calls.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-5-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Kumar Kartikeya Dwivedi 2026-09-03 16:44:22 +02:00 committed by Alexei Starovoitov
parent 266aa4ad0b
commit d9ae3e4c7f

View File

@ -44,6 +44,13 @@ int callback_loop(int index, void **cb_ctx)
return ret ? 1 : 0;
}
static __noinline
int callback_tail(int index, void **cb_ctx)
{
bpf_tail_call_static(*cb_ctx, &jmp_table, 0);
return 0;
}
static __noinline
int callback_empty(int index, void *data)
{
@ -78,4 +85,13 @@ int tailcall_callback_2(struct __sk_buff *skb)
return 0;
}
/* callback with a direct tail call is rejected without a verifier bug */
SEC("tc")
__failure __msg("cannot tail call within callback")
int tailcall_callback_3(struct __sk_buff *skb)
{
bpf_loop(1, callback_tail, &skb, 0);
return 0;
}
char __license[] SEC("license") = "GPL";