[LTP] [PATCH v4 2/3] ptrace: add test for /proc/self/mem write rejection
Jan Polensky <[email protected]>
| Newsgroups | it.linux.lists.ltp |
|---|---|
| Message-ID | <[email protected]> |
Add ptrace12 to verify that /proc/self/mem writes are rejected when CONFIG_PROC_MEM_FORCE_PTRACE requires ptrace access checks for /proc/pid/mem writes. The test maps a page, makes it read-only so the write path needs FOLL_FORCE, then attempts to write to it through /proc/self/mem. Since a task cannot ptrace itself, the write is expected to fail with EIO. If the write succeeds, the test reports TCONF because the required kernel behavior is not active. Signed-off-by: Jan Polensky <[email protected]> --- runtest/syscalls | 1 + testcases/kernel/syscalls/ptrace/.gitignore | 1 + testcases/kernel/syscalls/ptrace/ptrace12.c | 95 +++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 testcases/kernel/syscalls/ptrace/ptrace12.c diff --git a/runtest/syscalls b/runtest/syscalls index b024d4c43a2c..7fc443247361 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1182,6 +1182,7 @@ ptrace09 ptrace09 ptrace10 ptrace10 ptrace11 ptrace11 +ptrace12 ptrace12 pwrite01 pwrite01 pwrite02 pwrite02 pwrite03 pwrite03 diff --git a/testcases/kernel/syscalls/ptrace/.gitignore b/testcases/kernel/syscalls/ptrace/.gitignore index 1ee6117e9d5b..8631219312d5 100644 --- a/testcases/kernel/syscalls/ptrace/.gitignore +++ b/testcases/kernel/syscalls/ptrace/.gitignore @@ -9,3 +9,4 @@ /ptrace09 /ptrace10 /ptrace11 +/ptrace12 diff --git a/testcases/kernel/syscalls/ptrace/ptrace12.c b/testcases/kernel/syscalls/ptrace/ptrace12.c new file mode 100644 index 000000000000..d72987a69a92 --- /dev/null +++ b/testcases/kernel/syscalls/ptrace/ptrace12.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 IBM Corporation + */ + +/*\ + * Verify that direct writes to /proc/self/mem are correctly rejected + * when CONFIG_PROC_MEM_FORCE_PTRACE=y is active. + * + * When CONFIG_PROC_MEM_FORCE_PTRACE=y is set, the kernel requires + * PTRACE_MODE_ATTACH for /proc/pid/mem writes. This means a process + * cannot write to its own memory via /proc/self/mem - such writes + * should fail with EIO. + * + * Test behavior: + * + * - If write fails with EIO: TPASS (correct rejection) + * - If write succeeds: TFAIL (policy violation under required config) + * - If write fails with other error: TFAIL (unexpected behavior) + */ + +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "tst_test.h" + +static int *test_ptr; +static int memfd = -1; + +static void setup(void) +{ + test_ptr = SAFE_MMAP(NULL, sizeof(int), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + *test_ptr = 0; + + /* Force /proc/self/mem to require FOLL_FORCE by targeting a read-only page */ + SAFE_MPROTECT((void *)test_ptr, sizeof(int), PROT_READ); + + memfd = SAFE_OPEN("/proc/self/mem", O_RDWR); +} + +static void run(void) +{ + int test_val = 0xdeadbeef; + + SAFE_LSEEK(memfd, (off_t)test_ptr, SEEK_SET); + TEST(write(memfd, &test_val, sizeof(test_val))); + + if (TST_RET == -1 && TST_ERR == EIO) { + tst_res(TPASS, + "Write to /proc/self/mem correctly rejected with EIO"); + return; + } + + if (TST_RET == -1) { + tst_res(TFAIL | TERRNO, + "Write to /proc/self/mem failed with unexpected error"); + return; + } + + if (TST_RET == sizeof(test_val)) { + tst_res(TFAIL, + "Write to /proc/self/mem succeeded under CONFIG_PROC_MEM_FORCE_PTRACE=y"); + return; + } + + tst_res(TFAIL, + "Short write to /proc/self/mem: %zd bytes (expected %zu or -1)", + TST_RET, sizeof(test_val)); +} + +static void cleanup(void) +{ + if (memfd >= 0) + SAFE_CLOSE(memfd); + + if (test_ptr) + SAFE_MUNMAP(test_ptr, sizeof(int)); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .needs_kconfigs = (const char *[]) { + "CONFIG_PROC_MEM_FORCE_PTRACE=y", + NULL + }, + .tags = (const struct tst_tag[]) { + {"linux-git", "41e8149c8892"}, + {} + } +}; -- 2.55.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp