* [PATCH bpf-next v3 0/2] bpf: Fix sleepable check for tracing prog @ 2026-08-04 14:57 Leon Hwang 2026-08-04 14:57 ` [PATCH bpf-next v3 1/2] " Leon Hwang 2026-08-04 14:57 ` [PATCH bpf-next v3 2/2] selftests/bpf: Verify rejection of sleepable " Leon Hwang 0 siblings, 2 replies; 7+ messages in thread From: Leon Hwang @ 2026-08-04 14:57 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Shuah Khan, Sechang Lim, Varun R Mallya, Leon Hwang, Viktor Malik, linux-kernel, linux-kselftest, netdev When CONFIG_FUNCTION_ERROR_INJECTION is disabled, a sleepable tracing prog is allowed to attach to '__x64_'-alike prefix symbols. It is because the verifier does not verify whether the symbol is a kernel function or a bpf prog. That said, a sleepable tracing prog is allowed to attach to a bpf prog target whose name has '__x64_'-alike prefix. For example, a sleepable fentry prog attaches to a '__x64_sys_nop' XDP prog, and copies buffer from a user pointer with bpf_copy_from_user() helper. After attaching the XDP prog to lo interface, the kernel BUG could be triggered by 'ping -c 1 -W 1 127.0.0.1': [ 3.460756] BUG: sleeping function called from invalid context at kernel/bpf/trampoline.c:1324 Fix it by disallowing sleepable tracing prog always when its target btf is not kernel's btf. Changes: v2 -> v3: * Use btf_is_kernel() instead of passing 'tgt_prog'. (per Andrii) * v2: https://lore.kernel.org/bpf/20260725132624.78373-1-leon.hwang@linux.dev/ v1 -> v2: * Drop redundant 'prog->sleepable' check. (per Viktor) * Collect Acked-by from Viktor, Thanks. * v1: https://lore.kernel.org/bpf/20260724141422.10463-1-leon.hwang@linux.dev/ Leon Hwang (2): bpf: Fix sleepable check for tracing prog selftests/bpf: Verify rejection of sleepable tracing prog kernel/bpf/verifier.c | 3 + .../selftests/bpf/prog_tests/fexit_bpf2bpf.c | 57 +++++++++++++++++++ .../selftests/bpf/progs/fentry_sleepable.c | 18 ++++++ tools/testing/selftests/bpf/progs/xdp_dummy.c | 6 ++ 4 files changed, 84 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/fentry_sleepable.c -- 2.55.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf-next v3 1/2] bpf: Fix sleepable check for tracing prog 2026-08-04 14:57 [PATCH bpf-next v3 0/2] bpf: Fix sleepable check for tracing prog Leon Hwang @ 2026-08-04 14:57 ` Leon Hwang 2026-08-04 15:43 ` sashiko-bot 2026-08-04 23:39 ` Andrii Nakryiko 2026-08-04 14:57 ` [PATCH bpf-next v3 2/2] selftests/bpf: Verify rejection of sleepable " Leon Hwang 1 sibling, 2 replies; 7+ messages in thread From: Leon Hwang @ 2026-08-04 14:57 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Shuah Khan, Sechang Lim, Varun R Mallya, Leon Hwang, Viktor Malik, linux-kernel, linux-kselftest, netdev When CONFIG_FUNCTION_ERROR_INJECTION is disabled, a sleepable tracing prog is allowed to attach to '__x64_'-alike prefix symbols. It is because the verifier does not verify whether the symbol is a kernel function or a bpf prog. That said, a sleepable tracing prog is allowed to attach to a bpf prog target whose name has '__x64_'-alike prefix. For example, a sleepable fentry prog attaches to a '__x64_sys_nop' XDP prog, and copies buffer from a user pointer with bpf_copy_from_user() helper. After attaching the XDP prog to lo interface, the kernel BUG could be triggered by 'ping -c 1 -W 1 127.0.0.1': [ 3.460756] BUG: sleeping function called from invalid context at kernel/bpf/trampoline.c:1324 Fix it by disallowing sleepable tracing prog always when its target btf is not kernel's btf. Fixes: 16d9c5660692 ("bpf: Always allow sleepable programs on syscalls") Acked-by: Viktor Malik <vmalik@redhat.com> Signed-off-by: Leon Hwang <leon.hwang@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 b274004fccfd..7bb541e343b2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -19019,6 +19019,9 @@ static int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct b switch (prog->type) { case BPF_PROG_TYPE_TRACING: + if (!btf_is_kernel(btf)) + return -EINVAL; + t = btf_type_by_id(btf, btf_id); if (!t) return -EINVAL; -- 2.55.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: Fix sleepable check for tracing prog 2026-08-04 14:57 ` [PATCH bpf-next v3 1/2] " Leon Hwang @ 2026-08-04 15:43 ` sashiko-bot 2026-08-04 23:39 ` Andrii Nakryiko 1 sibling, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-08-04 15:43 UTC (permalink / raw) To: Leon Hwang; +Cc: bpf Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [High] Bypass of `bpf_d_path_allowed` allowlist using forged BTF IDs allows non-sleepable tracing programs to call `bpf_d_path`, leading to kernel deadlocks. -- --- Patch [1]: [PATCH bpf-next v3 1/2] bpf: Fix sleepable check for tracing prog --- commit bd029887d83c0773bad79aca8216a06849cdbd32 Author: Leon Hwang <leon.hwang@linux.dev> bpf: Fix sleepable check for tracing prog When CONFIG_FUNCTION_ERROR_INJECTION is disabled, a sleepable tracing prog is allowed to attach to '__x64_'-alike prefix symbols. > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 7439afdc851a7..d4541cca7180e 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -19024,6 +19024,9 @@ static int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct b > > switch (prog->type) { > case BPF_PROG_TYPE_TRACING: > + if (!btf_is_kernel(btf)) > + return -EINVAL; > + [Severity: High] This is a pre-existing issue, but does the same bypass exist for non-sleepable tracing programs calling bpf_d_path()? Looking at bpf_d_path_allowed() in kernel/trace/bpf_trace.c: kernel/trace/bpf_trace.c:bpf_d_path_allowed() { ... return btf_id_set_contains(&btf_allowlist_d_path, prog->aux->attach_btf_id); } This check relies entirely on the integer attach_btf_id and fails to verify if attach_btf is the kernel's vmlinux BTF. Can a user load a dummy BPF program with a crafted BTF where a function's BTF ID exactly matches an ID in btf_allowlist_d_path, and then attach a non-sleepable tracing program to it? If this dummy program is triggered in softirq context by network traffic, and the tracing program extracts a valid path and calls bpf_d_path(), this would invoke d_path() which attempts to acquire rename_lock (a seqlock). If the softirq interrupts a process holding the seqlock writer spinlock, wouldn't read_seqbegin_or_lock() retry and fall back to taking the spinlock, causing a deadlock on the same CPU? > t = btf_type_by_id(btf, btf_id); > if (!t) > return -EINVAL; -- Sashiko AI review · https://sashiko.dev/#/patchset/20260804145710.43062-1-leon.hwang@linux.dev?part=1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: Fix sleepable check for tracing prog 2026-08-04 14:57 ` [PATCH bpf-next v3 1/2] " Leon Hwang 2026-08-04 15:43 ` sashiko-bot @ 2026-08-04 23:39 ` Andrii Nakryiko 2026-08-05 1:52 ` Leon Hwang 1 sibling, 1 reply; 7+ messages in thread From: Andrii Nakryiko @ 2026-08-04 23:39 UTC (permalink / raw) To: Leon Hwang Cc: bpf, Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Shuah Khan, Sechang Lim, Varun R Mallya, Viktor Malik, linux-kernel, linux-kselftest, netdev On Tue, Aug 4, 2026 at 7:57 AM Leon Hwang <leon.hwang@linux.dev> wrote: > > When CONFIG_FUNCTION_ERROR_INJECTION is disabled, a sleepable tracing prog > is allowed to attach to '__x64_'-alike prefix symbols. > > It is because the verifier does not verify whether the symbol is a kernel > function or a bpf prog. That said, a sleepable tracing prog is allowed to > attach to a bpf prog target whose name has '__x64_'-alike prefix. > > For example, a sleepable fentry prog attaches to a '__x64_sys_nop' XDP > prog, and copies buffer from a user pointer with bpf_copy_from_user() > helper. After attaching the XDP prog to lo interface, the kernel BUG > could be triggered by 'ping -c 1 -W 1 127.0.0.1': > > [ 3.460756] BUG: sleeping function called from invalid context at kernel/bpf/trampoline.c:1324 > > Fix it by disallowing sleepable tracing prog always when its target btf > is not kernel's btf. > > Fixes: 16d9c5660692 ("bpf: Always allow sleepable programs on syscalls") > Acked-by: Viktor Malik <vmalik@redhat.com> > Signed-off-by: Leon Hwang <leon.hwang@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 b274004fccfd..7bb541e343b2 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -19019,6 +19019,9 @@ static int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct b > > switch (prog->type) { > case BPF_PROG_TYPE_TRACING: > + if (!btf_is_kernel(btf)) > + return -EINVAL; > + see sashiko reply, just move it outside of switch and disallow sleepable for anything that is not kernel/module BTF, regardless of program type pw-bot: cr > t = btf_type_by_id(btf, btf_id); > if (!t) > return -EINVAL; > -- > 2.55.0 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: Fix sleepable check for tracing prog 2026-08-04 23:39 ` Andrii Nakryiko @ 2026-08-05 1:52 ` Leon Hwang 0 siblings, 0 replies; 7+ messages in thread From: Leon Hwang @ 2026-08-05 1:52 UTC (permalink / raw) To: Andrii Nakryiko Cc: bpf, Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Shuah Khan, Sechang Lim, Varun R Mallya, Viktor Malik, linux-kernel, linux-kselftest, netdev On 5/8/26 07:39, Andrii Nakryiko wrote: > On Tue, Aug 4, 2026 at 7:57 AM Leon Hwang <leon.hwang@linux.dev> wrote: [...] >> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c >> index b274004fccfd..7bb541e343b2 100644 >> --- a/kernel/bpf/verifier.c >> +++ b/kernel/bpf/verifier.c >> @@ -19019,6 +19019,9 @@ static int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct b >> >> switch (prog->type) { >> case BPF_PROG_TYPE_TRACING: >> + if (!btf_is_kernel(btf)) >> + return -EINVAL; >> + > > see sashiko reply, just move it outside of switch and disallow > sleepable for anything that is not kernel/module BTF, regardless of > program type > Ack. I think another Fixes tag is needed for the LSM case. Thanks, Leon ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf-next v3 2/2] selftests/bpf: Verify rejection of sleepable tracing prog 2026-08-04 14:57 [PATCH bpf-next v3 0/2] bpf: Fix sleepable check for tracing prog Leon Hwang 2026-08-04 14:57 ` [PATCH bpf-next v3 1/2] " Leon Hwang @ 2026-08-04 14:57 ` Leon Hwang 2026-08-04 15:49 ` sashiko-bot 1 sibling, 1 reply; 7+ messages in thread From: Leon Hwang @ 2026-08-04 14:57 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Shuah Khan, Sechang Lim, Varun R Mallya, Leon Hwang, Viktor Malik, linux-kernel, linux-kselftest, netdev Add a test to verify that the sleepable tracing prog cannot attach to a '__x64_sys' prefix prog target. When CONFIG_FUNCTION_ERROR_INJECTION is disabled, without the fix, the test would trigger the BUG: [ 3.460756] BUG: sleeping function called from invalid context at kernel/bpf/trampoline.c:1324 Signed-off-by: Leon Hwang <leon.hwang@linux.dev> --- .../selftests/bpf/prog_tests/fexit_bpf2bpf.c | 57 +++++++++++++++++++ .../selftests/bpf/progs/fentry_sleepable.c | 18 ++++++ tools/testing/selftests/bpf/progs/xdp_dummy.c | 6 ++ 3 files changed, 81 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/fentry_sleepable.c diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c index 4a87d7163c8c..2523c07a16c6 100644 --- a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c +++ b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c @@ -5,6 +5,7 @@ #include <bpf/btf.h> #include "bind4_prog.skel.h" #include "freplace_progmap.skel.h" +#include "fentry_sleepable.skel.h" #include "xdp_dummy.skel.h" typedef int (*test_cb)(struct bpf_object *obj); @@ -576,6 +577,60 @@ static void test_func_replace_progmap(void) freplace_progmap__destroy(skel); } +static void test_sleepable_fentry_to_xdp(void) +{ + struct fentry_sleepable *skel = NULL; + struct xdp_dummy *skel_xdp = NULL; + int ifindex, prog_fd, err; + char buff[64] = {}; + +#ifndef __x86_64__ + test__skip(); + return; +#endif + + ifindex = if_nametoindex("lo"); + if (!ASSERT_GT(ifindex, 0, "if_nametoindex")) + return; + + skel_xdp = xdp_dummy__open_and_load(); + if (!ASSERT_OK_PTR(skel_xdp, "xdp_dummy__open_and_load")) + return; + + skel = fentry_sleepable__open(); + if (!ASSERT_OK_PTR(skel, "fentry_sleepable__open")) + goto out; + + skel->bss->user_ptr = buff; + + prog_fd = bpf_program__fd(skel_xdp->progs.__x64_sys_nop); + err = bpf_program__set_attach_target(skel->progs.fentry_xdp, prog_fd, "__x64_sys_nop"); + if (!ASSERT_OK(err, "bpf_program__set_attach_target")) + goto out; + + err = fentry_sleepable__load(skel); + ASSERT_ERR(err, "fentry_sleepable__load"); + if (err) + goto out; + + skel->links.fentry_xdp = bpf_program__attach_trace(skel->progs.fentry_xdp); + if (!ASSERT_OK_PTR(skel->links.fentry_xdp, "bpf_program__attach_trace")) + goto out; + + skel_xdp->links.__x64_sys_nop = bpf_program__attach_xdp(skel_xdp->progs.__x64_sys_nop, + ifindex); + if (!ASSERT_OK_PTR(skel_xdp->links.__x64_sys_nop, "bpf_program__attach_xdp")) + goto out; + + err = system("ping -q -c 1 -W 1 127.0.0.1 > /dev/null"); + ASSERT_OK(err, "ping"); + ASSERT_ERR(skel->bss->retval, "retval"); + +out: + fentry_sleepable__destroy(skel); + xdp_dummy__destroy(skel_xdp); +} + /* NOTE: affect other tests, must run in serial mode */ void serial_test_fexit_bpf2bpf(void) { @@ -607,4 +662,6 @@ void serial_test_fexit_bpf2bpf(void) test_func_replace_int_with_void(); if (test__start_subtest("freplace_void")) test_func_replace_void(); + if (test__start_subtest("sleepable_fentry_to_xdp")) + test_sleepable_fentry_to_xdp(); } diff --git a/tools/testing/selftests/bpf/progs/fentry_sleepable.c b/tools/testing/selftests/bpf/progs/fentry_sleepable.c new file mode 100644 index 000000000000..8c0fc691d329 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/fentry_sleepable.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "vmlinux.h" +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> + +char LICENSE[] SEC("license") = "GPL"; + +void *user_ptr; +int retval; + +SEC("fentry.s") +int BPF_PROG(fentry_xdp) +{ + char buff[64]; + + retval = bpf_copy_from_user(buff, sizeof(buff), user_ptr); + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/xdp_dummy.c b/tools/testing/selftests/bpf/progs/xdp_dummy.c index d988b2e0cee8..5f1e0771021d 100644 --- a/tools/testing/selftests/bpf/progs/xdp_dummy.c +++ b/tools/testing/selftests/bpf/progs/xdp_dummy.c @@ -10,4 +10,10 @@ int xdp_dummy_prog(struct xdp_md *ctx) return XDP_PASS; } +SEC("xdp") +int __x64_sys_nop(struct xdp_md *ctx) +{ + return XDP_PASS; +} + char _license[] SEC("license") = "GPL"; -- 2.55.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v3 2/2] selftests/bpf: Verify rejection of sleepable tracing prog 2026-08-04 14:57 ` [PATCH bpf-next v3 2/2] selftests/bpf: Verify rejection of sleepable " Leon Hwang @ 2026-08-04 15:49 ` sashiko-bot 0 siblings, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-08-04 15:49 UTC (permalink / raw) To: Leon Hwang; +Cc: bpf Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The test contains dead reproducer code that intentionally crashes the kernel on test failure instead of failing gracefully. -- --- Patch [2]: [PATCH bpf-next v3 2/2] selftests/bpf: Verify rejection of sleepable tracing prog --- commit 22c464db2aa39d78b7ca52b202c4a7828b6fddc2 Author: Leon Hwang <leon.hwang@linux.dev> selftests/bpf: Verify rejection of sleepable tracing prog This commit adds a test to verify that a sleepable tracing program cannot attach to a '__x64_sys' prefixed program target. > diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c > index 4a87d7163c8c7..2523c07a16c65 100644 > --- a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c > +++ b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c [ ... ] > @@ -576,6 +577,60 @@ static void test_func_replace_progmap(void) > freplace_progmap__destroy(skel); > } > > +static void test_sleepable_fentry_to_xdp(void) > +{ [ ... ] > + err = fentry_sleepable__load(skel); > + ASSERT_ERR(err, "fentry_sleepable__load"); > + if (err) > + goto out; > + > + skel->links.fentry_xdp = bpf_program__attach_trace(skel->progs.fentry_xdp); > + if (!ASSERT_OK_PTR(skel->links.fentry_xdp, "bpf_program__attach_trace")) > + goto out; > + > + skel_xdp->links.__x64_sys_nop = bpf_program__attach_xdp(skel_xdp->progs.__x64_sys_nop, > + ifindex); > + if (!ASSERT_OK_PTR(skel_xdp->links.__x64_sys_nop, "bpf_program__attach_xdp")) > + goto out; > + > + err = system("ping -q -c 1 -W 1 127.0.0.1 > /dev/null"); > + ASSERT_OK(err, "ping"); > + ASSERT_ERR(skel->bss->retval, "retval"); [Severity: Medium] Will this sequence crash the kernel if the test fails? If the kernel lacks the fix, fentry_sleepable__load() will return 0. ASSERT_ERR() will correctly log a test failure, but since err == 0, the if (err) goto out; check will be bypassed. The test will then proceed to attach the sleepable program and trigger it with ping, intentionally causing the kernel panic described in the commit message. Additionally, when the kernel is fixed and the test passes, this entire block is dead code because fentry_sleepable__load() returns < 0 and the test exits early via goto out. Could this test fail gracefully without crashing the system during automated bisections? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260804145710.43062-1-leon.hwang@linux.dev?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-05 1:53 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-04 14:57 [PATCH bpf-next v3 0/2] bpf: Fix sleepable check for tracing prog Leon Hwang 2026-08-04 14:57 ` [PATCH bpf-next v3 1/2] " Leon Hwang 2026-08-04 15:43 ` sashiko-bot 2026-08-04 23:39 ` Andrii Nakryiko 2026-08-05 1:52 ` Leon Hwang 2026-08-04 14:57 ` [PATCH bpf-next v3 2/2] selftests/bpf: Verify rejection of sleepable " Leon Hwang 2026-08-04 15:49 ` sashiko-bot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.