On Tue, Dec 2, 2025 at 6:20 AM Shuran Liu electronlsr@gmail.com wrote:
Add a regression test for bpf_d_path() when invoked from an LSM program. The test attaches to the bprm_check_security hook, calls bpf_d_path() on the binary being executed, and verifies that a simple prefix comparison on the returned pathname behaves correctly after the fix in patch 1.
To avoid nondeterminism, the LSM program now filters based on the expected PID, which is populated from userspace before the test binary is executed. This prevents unrelated processes that also trigger the bprm_check_security LSM hook from overwriting test results. Parent and child processes are synchronized through a pipe to ensure the PID is set before the child execs the test binary.
Per review feedback, the new LSM coverage is merged into the existing d_path selftest rather than adding new prog_tests/ or progs/ files. The loop that checks the pathname prefix now uses bpf_for(), which is a verifier-friendly way to express a small, fixed-iteration loop, and the temporary /tmp/bpf_d_path_test binary is removed in the test cleanup path.
Co-developed-by: Zesen Liu ftyg@live.com Signed-off-by: Zesen Liu ftyg@live.com Co-developed-by: Peili Gao gplhust955@gmail.com Signed-off-by: Peili Gao gplhust955@gmail.com Co-developed-by: Haoran Ni haoran.ni.cs@gmail.com Signed-off-by: Haoran Ni haoran.ni.cs@gmail.com Signed-off-by: Shuran Liu electronlsr@gmail.com Reviewed-by: Matt Bobrowski mattbobrowski@google.com
.../testing/selftests/bpf/prog_tests/d_path.c | 65 +++++++++++++++++++ .../testing/selftests/bpf/progs/test_d_path.c | 33 ++++++++++ 2 files changed, 98 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/d_path.c b/tools/testing/selftests/bpf/prog_tests/d_path.c index ccc768592e66..202b44e6f482 100644 --- a/tools/testing/selftests/bpf/prog_tests/d_path.c +++ b/tools/testing/selftests/bpf/prog_tests/d_path.c @@ -195,6 +195,68 @@ static void test_d_path_check_types(void) test_d_path_check_types__destroy(skel); }
+static void test_d_path_lsm(void) +{
struct test_d_path *skel;int err;int pipefd[2];pid_t pid;skel = test_d_path__open_and_load();if (!ASSERT_OK_PTR(skel, "d_path skeleton failed"))return;err = test_d_path__attach(skel);if (!ASSERT_OK(err, "attach failed"))goto cleanup;/* Prepare the test binary */system("cp /bin/true /tmp/bpf_d_path_test 2>/dev/null || :");if (!ASSERT_OK(pipe(pipefd), "pipe failed"))goto cleanup;pid = fork();if (!ASSERT_GE(pid, 0, "fork failed")) {close(pipefd[0]);close(pipefd[1]);goto cleanup;}if (pid == 0) {/* Child */char buf;close(pipefd[1]);/* Wait for parent to set PID in BPF map */if (read(pipefd[0], &buf, 1) != 1)exit(1);close(pipefd[0]);execl("/tmp/bpf_d_path_test", "/tmp/bpf_d_path_test", NULL);exit(1);}
No forks please. They often make selftest to be flaky. Use simples possible way to test it. Without forks and pipes.
pw-bot: cr