[PATCH STAGING v2 10/16] fchroot07: test execve blocked by failfs root
Andrea Cervesato <[email protected]>
| Newsgroups | gmane.linux.ltp |
|---|---|
| Message-ID | <[email protected]> |
From: Andrea Cervesato <andrea.cervesato-IBi9RG/[email protected]> Verify that after fchroot() moved the root into failfs, loading a binary by absolute path fails with EOPNOTSUPP. The exec runs in a grandchild so a wrongly successful exec is still detected through the exit code. Signed-off-by: Andrea Cervesato <andrea.cervesato-IBi9RG/[email protected]> --- runtest/staging | 1 + testcases/kernel/syscalls/fchroot/.gitignore | 1 + testcases/kernel/syscalls/fchroot/fchroot07.c | 72 +++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/runtest/staging b/runtest/staging index 8b6b1ecd9..b8954bb5a 100644 --- a/runtest/staging +++ b/runtest/staging @@ -6,3 +6,4 @@ fchroot03 fchroot03 fchroot04 fchroot04 fchroot05 fchroot05 fchroot06 fchroot06 +fchroot07 fchroot07 diff --git a/testcases/kernel/syscalls/fchroot/.gitignore b/testcases/kernel/syscalls/fchroot/.gitignore index 12151270a..b68069d9a 100644 --- a/testcases/kernel/syscalls/fchroot/.gitignore +++ b/testcases/kernel/syscalls/fchroot/.gitignore @@ -4,3 +4,4 @@ fchroot03 fchroot04 fchroot05 fchroot06 +fchroot07 diff --git a/testcases/kernel/syscalls/fchroot/fchroot07.c b/testcases/kernel/syscalls/fchroot/fchroot07.c new file mode 100644 index 000000000..d5ebfc576 --- /dev/null +++ b/testcases/kernel/syscalls/fchroot/fchroot07.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato-IBi9RG/[email protected]> + */ + +/*\ + * Test that :manpage:`execve(2)` is blocked under the failfs root. + * + * After :manpage:`fchroot(2)` moved the process root into failfs, loading + * a binary by absolute path fails with ``EOPNOTSUPP``. + * + * Root is required because entering failfs with the ``FD_FAILFS_ROOT`` + * sentinel requires ``CAP_SYS_CHROOT``. + * + * The exec runs in a grandchild: a wrongly successful exec would replace + * the test image, so the outcome can only be reported when the exec call + * returns, and the grandchild exit code tells the parent whether the + * image was replaced. + */ + +#define _GNU_SOURCE +#include <sys/wait.h> +#include <unistd.h> +#include "tst_test.h" +#include "lapi/fcntl.h" +#include "lapi/syscalls.h" + +/* Marker exit code proving the grandchild image was not replaced. */ +#define EXEC_NOT_REPLACED 42 + +static void check_exec_blocked(void) +{ + pid_t pid = SAFE_FORK(); + int status; + + if (!pid) { + TST_EXP_FAIL(execl("/bin/true", "true", NULL), EOPNOTSUPP, + "absolute exec blocked by the failfs root"); + + exit(EXEC_NOT_REPLACED); + } + + SAFE_WAITPID(pid, &status, 0); + if (!WIFEXITED(status) || WEXITSTATUS(status) != EXEC_NOT_REPLACED) + tst_res(TFAIL, "exec replaced the test image"); +} + +static void run(void) +{ + if (SAFE_FORK()) + return; + + TST_EXP_PASS(tst_syscall(__NR_fchroot, FD_FAILFS_ROOT, 0), + "fchroot() with the FD_FAILFS_ROOT sentinel"); + + check_exec_blocked(); + + exit(0); +} + +static void setup(void) +{ + if (access("/bin/true", X_OK)) + tst_brk(TCONF | TERRNO, "/bin/true is not available"); +} + +static struct tst_test test = { + .setup = setup, + .test_all = run, + .needs_root = 1, + .forks_child = 1, +}; -- 2.51.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp