From: Jan Polensky <japo@linux.ibm.com>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v3 2/3] ptrace: add test for /proc/self/mem write rejection
Date: Tue, 21 Jul 2026 22:24:50 +0200 [thread overview]
Message-ID: <20260721202452.315581-3-japo@linux.ibm.com> (raw)
In-Reply-To: <20260721202452.315581-1-japo@linux.ibm.com>
Add ptrace12 to verify that direct writes to /proc/self/mem are
correctly rejected when CONFIG_PROC_MEM_FORCE_PTRACE=y is active.
The test allocates a read-only memory page and attempts to write to it
via /proc/self/mem. With CONFIG_PROC_MEM_FORCE_PTRACE=y, this write
should fail with EIO because:
- FOLL_FORCE flag is needed to write to read-only pages
- CONFIG_PROC_MEM_FORCE_PTRACE blocks FOLL_FORCE unless actively ptracing
- A process cannot ptrace itself
Test validates kernel commit 41e8149c8892 ("proc: add config & param to
block forcing mem writes").
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/ptrace/.gitignore | 1 +
testcases/kernel/syscalls/ptrace/ptrace12.c | 92 +++++++++++++++++++++
3 files changed, 94 insertions(+)
create mode 100644 testcases/kernel/syscalls/ptrace/ptrace12.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 2be7012a6cd4..9df4684cca41 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1176,6 +1176,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..8bf1707b9923
--- /dev/null
+++ b/testcases/kernel/syscalls/ptrace/ptrace12.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 SUSE LLC <japo@suse.cz>
+ */
+
+/*\
+ * 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 succeeds: TCONF (feature not active)
+ * - If write fails with EIO: TPASS (feature working correctly)
+ * - 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 == sizeof(test_val)) {
+ tst_res(TCONF,
+ "Direct writes to /proc/self/mem succeeded - "
+ "CONFIG_PROC_MEM_FORCE_PTRACE not active or overridden");
+ return;
+ }
+
+ 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;
+ }
+
+ 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,
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "41e8149c8892"},
+ {}
+ }
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
next prev parent reply other threads:[~2026-07-21 20:25 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-21 20:24 [LTP] [PATCH v3 0/3] Separate ptrace tests for CONFIG_PROC_MEM_FORCE_PTRACE Jan Polensky
2026-07-21 20:24 ` [LTP] [PATCH v3 1/3] thp04: Simplify to focus on CVE-2017-1000405 race test only Jan Polensky
2026-07-21 21:21 ` [LTP] " linuxtestproject.agent
2026-07-22 7:31 ` Andrea Cervesato via ltp
2026-07-21 20:24 ` Jan Polensky [this message]
2026-07-21 20:24 ` [LTP] [PATCH v3 3/3] ptrace: add test for /proc/pid/mem writes under ptrace Jan Polensky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260721202452.315581-3-japo@linux.ibm.com \
--to=japo@linux.ibm.com \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox