diff options
| author | Kumar Kartikeya Dwivedi <memxor@gmail.com> | 2026-09-03 16:44:22 +0200 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-09-03 09:44:51 -0700 |
| commit | d9ae3e4c7fb5bfaccc9ca295692d54130862f3b2 (patch) | |
| tree | a06da3993bf507b25b450e7175acf60428e6902c | |
| parent | 266aa4ad0b2e82397cd9045752c9bff03d98eddd (diff) | |
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>
| -rw-r--r-- | tools/testing/selftests/bpf/progs/tailcall_callback.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/progs/tailcall_callback.c b/tools/testing/selftests/bpf/progs/tailcall_callback.c index c41632cf423b..14fa7a87028e 100644 --- a/tools/testing/selftests/bpf/progs/tailcall_callback.c +++ b/tools/testing/selftests/bpf/progs/tailcall_callback.c @@ -45,6 +45,13 @@ int callback_loop(int index, void **cb_ctx) } 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) { return 0; @@ -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"; |
