From: Ruslan Valiyev <linuxoid@gmail.com>
To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net,
andrii@kernel.org, eddyz87@gmail.com, martin.lau@linux.dev,
memxor@gmail.com
Cc: song@kernel.org, yonghong.song@linux.dev, jolsa@kernel.org
Subject: [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection
Date: Wed, 3 Jun 2026 11:44:28 +0200 [thread overview]
Message-ID: <20260603094428.2597058-1-linuxoid@gmail.com> (raw)
Verify that an arena map's mmap()ed VMA cannot be split with a partial
munmap() or inherited across fork().
Before commit 4fddde2a732d ("bpf: Fix use-after-free in arena_vm_close
on fork") the arena VMA had no .may_split callback and was not marked
VM_DONTCOPY, so a splitting munmap() and a fork() both succeeded. The
fork() case left the child with a VMA whose vml->vma still pointed at
the parent, dangling after the parent unmapped and leading to a
use-after-free if the child freed arena pages.
The test creates an arena map, mmap()s it, and asserts that a splitting
munmap() fails with -EINVAL and that the child of a fork() does not
inherit the arena VMA.
Signed-off-by: Ruslan Valiyev <linuxoid@gmail.com>
---
.../selftests/bpf/prog_tests/arena_fork.c | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_fork.c
diff --git a/tools/testing/selftests/bpf/prog_tests/arena_fork.c b/tools/testing/selftests/bpf/prog_tests/arena_fork.c
new file mode 100644
index 0000000000000..f3d5218c9e071
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/arena_fork.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+/* Regression test for commit 4fddde2a732d ("bpf: Fix use-after-free in
+ * arena_vm_close on fork"): an arena VMA must reject a splitting munmap()
+ * (.may_split) and must not be inherited across fork() (VM_DONTCOPY). On
+ * an unfixed kernel both operations succeed.
+ */
+
+#define NR_PAGES 3
+
+void test_arena_fork(void)
+{
+ LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);
+ long ps = sysconf(_SC_PAGESIZE);
+ size_t sz = (size_t)NR_PAGES * ps;
+ int fd, ret, status, err;
+ void *area;
+ pid_t pid;
+
+ fd = bpf_map_create(BPF_MAP_TYPE_ARENA, "arena_fork", 0, 0, NR_PAGES, &opts);
+ if (!ASSERT_OK_FD(fd, "arena map create"))
+ return;
+
+ area = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (!ASSERT_NEQ(area, MAP_FAILED, "mmap arena"))
+ goto close_fd;
+
+ /* A split of the arena VMA must be rejected (.may_split). */
+ ret = munmap((char *)area + ps, ps);
+ err = errno;
+ ASSERT_ERR(ret, "split munmap rejected");
+ ASSERT_EQ(err, EINVAL, "split munmap errno");
+
+ /* The child of a fork() must not inherit the arena VMA (VM_DONTCOPY);
+ * mincore() returns ENOMEM for the unmapped range.
+ */
+ pid = fork();
+ if (ASSERT_GE(pid, 0, "fork")) {
+ if (pid == 0) {
+ unsigned char vec;
+
+ _exit(mincore(area, ps, &vec) < 0 && errno == ENOMEM ? 0 : 1);
+ }
+ while ((ret = waitpid(pid, &status, 0)) < 0 && errno == EINTR)
+ ;
+ if (ASSERT_EQ(ret, pid, "waitpid"))
+ ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0,
+ "child must not inherit arena vma");
+ }
+
+ munmap(area, sz);
+close_fd:
+ close(fd);
+}
base-commit: 174914ea551314c52a61713b9c4bde9e42d48073
--
2.43.0
next reply other threads:[~2026-06-03 9:44 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-03 9:44 Ruslan Valiyev [this message]
2026-06-03 9:52 ` [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection sashiko-bot
2026-06-04 16:45 ` Emil Tsalapatis
2026-06-05 11:57 ` [PATCH v2 bpf-next] selftests/bpf: add arena split and fork tests Ruslan Valiyev
2026-06-05 12:07 ` sashiko-bot
2026-06-05 12:22 ` bot+bpf-ci
2026-06-05 14:31 ` Mykyta Yatsenko
2026-06-08 13:25 ` Ruslan Valiyev
2026-06-09 8:37 ` [PATCH v3 bpf-next] selftests/bpf: add tests for arena vma split and fork Ruslan Valiyev
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=20260603094428.2597058-1-linuxoid@gmail.com \
--to=linuxoid@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=jolsa@kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.