* [PATCH 0/2] selftests/bpf: make probe_user safe for parallel runs
@ 2026-02-26 4:29 Sun Jian
2026-02-26 4:29 ` [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference Sun Jian
2026-02-26 4:29 ` [PATCH 2/2] selftests/bpf: probe_user: drop serial restriction Sun Jian
0 siblings, 2 replies; 5+ messages in thread
From: Sun Jian @ 2026-02-26 4:29 UTC (permalink / raw)
To: Andrii Nakryiko, Shuah Khan
Cc: bpf, linux-kselftest, Alexei Starovoitov, Daniel Borkmann,
Sun Jian
The probe_user selftest attaches ksyscall hooks for connect() (and
socketcall() on s390). Historically this could corrupt other tests
calling connect(), which is why the test was marked as serial and
carried a TODO warning about cross-test corruption.
This series makes the test safe for parallel execution by filtering the
BPF-side instrumentation to the current test process only, and then
drops the serial restriction and the stale TODO comment.
Patch 1/2 adds a single-entry pid_map and checks current tgid (process
ID) before calling bpf_probe_read_user()/bpf_probe_write_user(). The
userspace test writes its PID into the map after loading the object.
Patch 2/2 drops the serial_ prefix and removes the outdated TODO, since
cross-test interference is no longer possible.
Tested on x86_64 (clang):
./test_progs -t probe_user -v
./test_progs -j$(nproc) -t probe_user
Sun Jian (2):
selftests/bpf: probe_user: filter by pid to avoid cross-test
interference
selftests/bpf: probe_user: drop serial restriction
.../selftests/bpf/prog_tests/probe_user.c | 16 +++++++++++---
.../selftests/bpf/progs/test_probe_user.c | 22 +++++++++++++++++++
2 files changed, 35 insertions(+), 3 deletions(-)
base-commit: 7dff99b354601dd01829e1511711846e04340a69
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference 2026-02-26 4:29 [PATCH 0/2] selftests/bpf: make probe_user safe for parallel runs Sun Jian @ 2026-02-26 4:29 ` Sun Jian 2026-02-26 4:56 ` Alexei Starovoitov 2026-02-26 5:08 ` bot+bpf-ci 2026-02-26 4:29 ` [PATCH 2/2] selftests/bpf: probe_user: drop serial restriction Sun Jian 1 sibling, 2 replies; 5+ messages in thread From: Sun Jian @ 2026-02-26 4:29 UTC (permalink / raw) To: Andrii Nakryiko, Shuah Khan Cc: bpf, linux-kselftest, Alexei Starovoitov, Daniel Borkmann, Sun Jian The test installs a kprobe on __sys_connect and checks that bpf_probe_write_user() can modify the syscall argument. However, any concurrent thread in any other test that calls connect() will also trigger the kprobe and have its sockaddr silently overwritten, causing flaky failures in unrelated tests. Fix this by introducing a pid_map (BPF_MAP_TYPE_ARRAY) that stores the test process's PID. The kprobe handler returns early if the current PID does not match, confining the hook to the test process only. Also remove the TODO comment that tracked this issue. Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> --- .../selftests/bpf/prog_tests/probe_user.c | 13 ++++++++++- .../selftests/bpf/progs/test_probe_user.c | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/probe_user.c b/tools/testing/selftests/bpf/prog_tests/probe_user.c index 8721671321de..f50ee4066759 100644 --- a/tools/testing/selftests/bpf/prog_tests/probe_user.c +++ b/tools/testing/selftests/bpf/prog_tests/probe_user.c @@ -13,13 +13,15 @@ void serial_test_probe_user(void) enum { prog_count = ARRAY_SIZE(prog_names) }; const char *obj_file = "./test_probe_user.bpf.o"; DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, ); - int err, results_map_fd, sock_fd, duration = 0; + int err, results_map_fd, pid_map_fd, sock_fd, duration = 0; struct sockaddr curr, orig, tmp; struct sockaddr_in *in = (struct sockaddr_in *)&curr; struct bpf_link *kprobe_links[prog_count] = {}; struct bpf_program *kprobe_progs[prog_count]; struct bpf_object *obj; static const int zero = 0; + __u32 key = 0; + __u32 pid; size_t i; obj = bpf_object__open_file(obj_file, &opts); @@ -38,6 +40,15 @@ void serial_test_probe_user(void) if (CHECK(err, "obj_load", "err %d\n", err)) goto cleanup; + pid_map_fd = bpf_find_map(__func__, obj, "pid_map"); + if (CHECK(pid_map_fd < 0, "find_pid_map", "err %d\n", pid_map_fd)) + goto cleanup; + + pid = getpid(); + err = bpf_map_update_elem(pid_map_fd, &key, &pid, BPF_ANY); + if (CHECK(err, "update_pid_map", "err %d\n", err)) + goto cleanup; + results_map_fd = bpf_find_map(__func__, obj, "test_pro.bss"); if (CHECK(results_map_fd < 0, "find_bss_map", "err %d\n", results_map_fd)) diff --git a/tools/testing/selftests/bpf/progs/test_probe_user.c b/tools/testing/selftests/bpf/progs/test_probe_user.c index a8e501af9604..20a13b984fb0 100644 --- a/tools/testing/selftests/bpf/progs/test_probe_user.c +++ b/tools/testing/selftests/bpf/progs/test_probe_user.c @@ -5,6 +5,24 @@ #include <bpf/bpf_core_read.h> #include "bpf_misc.h" +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, __u32); +} pid_map SEC(".maps"); + +static __always_inline int pid_ok(void) +{ + __u32 key = 0, *expected_pid; + + expected_pid = bpf_map_lookup_elem(&pid_map, &key); + if (!expected_pid || + *expected_pid != (bpf_get_current_pid_tgid() >> 32)) + return 0; + return 1; +} + static struct sockaddr_in old; static int handle_sys_connect_common(struct sockaddr_in *uservaddr) @@ -22,6 +40,8 @@ SEC("ksyscall/connect") int BPF_KSYSCALL(handle_sys_connect, int fd, struct sockaddr_in *uservaddr, int addrlen) { + if (!pid_ok()) + return 0; return handle_sys_connect_common(uservaddr); } @@ -36,6 +56,8 @@ int BPF_KSYSCALL(handle_sys_socketcall, int call, unsigned long *args) if (call == SYS_CONNECT) { struct sockaddr_in *uservaddr; + if (!pid_ok()) + return 0; bpf_probe_read_user(&uservaddr, sizeof(uservaddr), &args[1]); return handle_sys_connect_common(uservaddr); } -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference 2026-02-26 4:29 ` [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference Sun Jian @ 2026-02-26 4:56 ` Alexei Starovoitov 2026-02-26 5:08 ` bot+bpf-ci 1 sibling, 0 replies; 5+ messages in thread From: Alexei Starovoitov @ 2026-02-26 4:56 UTC (permalink / raw) To: Sun Jian Cc: Andrii Nakryiko, Shuah Khan, bpf, open list:KERNEL SELFTEST FRAMEWORK, Alexei Starovoitov, Daniel Borkmann On Wed, Feb 25, 2026 at 8:31 PM Sun Jian <sun.jian.kdev@gmail.com> wrote: > > The test installs a kprobe on __sys_connect and checks that > bpf_probe_write_user() can modify the syscall argument. However, any > concurrent thread in any other test that calls connect() will also > trigger the kprobe and have its sockaddr silently overwritten, causing > flaky failures in unrelated tests. > > Fix this by introducing a pid_map (BPF_MAP_TYPE_ARRAY) that stores the > test process's PID. The kprobe handler returns early if the current PID > does not match, confining the hook to the test process only. > > Also remove the TODO comment that tracked this issue. > > Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> > --- > .../selftests/bpf/prog_tests/probe_user.c | 13 ++++++++++- > .../selftests/bpf/progs/test_probe_user.c | 22 +++++++++++++++++++ > 2 files changed, 34 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/bpf/prog_tests/probe_user.c b/tools/testing/selftests/bpf/prog_tests/probe_user.c > index 8721671321de..f50ee4066759 100644 > --- a/tools/testing/selftests/bpf/prog_tests/probe_user.c > +++ b/tools/testing/selftests/bpf/prog_tests/probe_user.c > @@ -13,13 +13,15 @@ void serial_test_probe_user(void) > enum { prog_count = ARRAY_SIZE(prog_names) }; > const char *obj_file = "./test_probe_user.bpf.o"; > DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, ); > - int err, results_map_fd, sock_fd, duration = 0; > + int err, results_map_fd, pid_map_fd, sock_fd, duration = 0; > struct sockaddr curr, orig, tmp; > struct sockaddr_in *in = (struct sockaddr_in *)&curr; > struct bpf_link *kprobe_links[prog_count] = {}; > struct bpf_program *kprobe_progs[prog_count]; > struct bpf_object *obj; > static const int zero = 0; > + __u32 key = 0; > + __u32 pid; > size_t i; > > obj = bpf_object__open_file(obj_file, &opts); > @@ -38,6 +40,15 @@ void serial_test_probe_user(void) > if (CHECK(err, "obj_load", "err %d\n", err)) > goto cleanup; > > + pid_map_fd = bpf_find_map(__func__, obj, "pid_map"); > + if (CHECK(pid_map_fd < 0, "find_pid_map", "err %d\n", pid_map_fd)) > + goto cleanup; > + > + pid = getpid(); > + err = bpf_map_update_elem(pid_map_fd, &key, &pid, BPF_ANY); > + if (CHECK(err, "update_pid_map", "err %d\n", err)) > + goto cleanup; > + > results_map_fd = bpf_find_map(__func__, obj, "test_pro.bss"); > if (CHECK(results_map_fd < 0, "find_bss_map", > "err %d\n", results_map_fd)) > diff --git a/tools/testing/selftests/bpf/progs/test_probe_user.c b/tools/testing/selftests/bpf/progs/test_probe_user.c > index a8e501af9604..20a13b984fb0 100644 > --- a/tools/testing/selftests/bpf/progs/test_probe_user.c > +++ b/tools/testing/selftests/bpf/progs/test_probe_user.c > @@ -5,6 +5,24 @@ > #include <bpf/bpf_core_read.h> > #include "bpf_misc.h" > > +struct { > + __uint(type, BPF_MAP_TYPE_ARRAY); > + __uint(max_entries, 1); > + __type(key, __u32); > + __type(value, __u32); > +} pid_map SEC(".maps"); > + > +static __always_inline int pid_ok(void) > +{ > + __u32 key = 0, *expected_pid; > + > + expected_pid = bpf_map_lookup_elem(&pid_map, &key); > + if (!expected_pid || > + *expected_pid != (bpf_get_current_pid_tgid() >> 32)) > + return 0; Good idea, but there are much simpler ways to do it via global variables. See other selftests. pw-bot: cr ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference 2026-02-26 4:29 ` [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference Sun Jian 2026-02-26 4:56 ` Alexei Starovoitov @ 2026-02-26 5:08 ` bot+bpf-ci 1 sibling, 0 replies; 5+ messages in thread From: bot+bpf-ci @ 2026-02-26 5:08 UTC (permalink / raw) To: sun.jian.kdev, andrii, shuah Cc: bpf, linux-kselftest, ast, daniel, sun.jian.kdev, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 1178 bytes --] > Also remove the TODO comment that tracked this issue. The TODO comment is still present after this commit: tools/testing/selftests/bpf/prog_tests/probe_user.c: /* TODO: corrupts other tests uses connect() */ void serial_test_probe_user(void) It looks like the removal was moved to patch 2/2 ("selftests/bpf: probe_user: drop serial restriction", 849a4da3ab25) but this commit message wasn't updated to match. Should this sentence be dropped from the commit message? --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/22428129620 AI-authorship-score: medium AI-authorship-explanation: Template-like PID filtering pattern, well-structured commit message, and the mismatch between claimed and actual changes suggest possible AI assistance, though the pattern is also common in hand-written kernel patches. issues-found: 1 issue-severity-score: low issue-severity-explanation: Commit message inaccurately claims TODO comment removal that was actually done in the next patch in the series. ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] selftests/bpf: probe_user: drop serial restriction 2026-02-26 4:29 [PATCH 0/2] selftests/bpf: make probe_user safe for parallel runs Sun Jian 2026-02-26 4:29 ` [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference Sun Jian @ 2026-02-26 4:29 ` Sun Jian 1 sibling, 0 replies; 5+ messages in thread From: Sun Jian @ 2026-02-26 4:29 UTC (permalink / raw) To: Andrii Nakryiko, Shuah Khan Cc: bpf, linux-kselftest, Alexei Starovoitov, Daniel Borkmann, Sun Jian Patch 1/2 added PID filtering to the probe_user BPF program to avoid cross-test interference from the global connect() hooks. With the interference removed, drop the serial_ prefix and remove the stale TODO comment so the test can run in parallel. Tested: ./test_progs -t probe_user -v ./test_progs -j$(nproc) -t probe_user Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> --- tools/testing/selftests/bpf/prog_tests/probe_user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/probe_user.c b/tools/testing/selftests/bpf/prog_tests/probe_user.c index f50ee4066759..0ace1cf157ca 100644 --- a/tools/testing/selftests/bpf/prog_tests/probe_user.c +++ b/tools/testing/selftests/bpf/prog_tests/probe_user.c @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <test_progs.h> -/* TODO: corrupts other tests uses connect() */ -void serial_test_probe_user(void) +void test_probe_user(void) { static const char *const prog_names[] = { "handle_sys_connect", -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-02-26 5:08 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-26 4:29 [PATCH 0/2] selftests/bpf: make probe_user safe for parallel runs Sun Jian 2026-02-26 4:29 ` [PATCH 1/2] selftests/bpf: probe_user: filter by pid to avoid cross-test interference Sun Jian 2026-02-26 4:56 ` Alexei Starovoitov 2026-02-26 5:08 ` bot+bpf-ci 2026-02-26 4:29 ` [PATCH 2/2] selftests/bpf: probe_user: drop serial restriction Sun Jian
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox