* [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection
@ 2026-06-03 9:44 Ruslan Valiyev
2026-06-03 9:52 ` sashiko-bot
2026-06-04 16:45 ` Emil Tsalapatis
0 siblings, 2 replies; 10+ messages in thread
From: Ruslan Valiyev @ 2026-06-03 9:44 UTC (permalink / raw)
To: bpf, ast, daniel, andrii, eddyz87, martin.lau, memxor
Cc: song, yonghong.song, jolsa
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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection
2026-06-03 9:44 [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection Ruslan Valiyev
@ 2026-06-03 9:52 ` sashiko-bot
2026-06-04 16:45 ` Emil Tsalapatis
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-03 9:52 UTC (permalink / raw)
To: Ruslan Valiyev; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Multi-line comments do not follow the BPF subsystem style guide.
--
commit 68912cf41a7e5ee9f6445ed2bc4cecbbb14bad14
Author: Ruslan Valiyev <linuxoid@gmail.com>
selftests/bpf: add test for arena vma split and fork rejection
This commit adds a selftest to verify that an arena map's mmap()ed VMA
cannot be split with a partial munmap() or inherited across fork().
> 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.
> + */
[Severity: Low]
This isn't a bug, but does this multi-line comment format follow the BPF
subsystem style? The subsystem guidelines state that multi-line comments
should have the opening /* on its own line.
[ ... ]
> + /* 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.
> + */
[Severity: Low]
This isn't a bug, but does this comment also need the opening /* on its own
line to match the preferred BPF multi-line comment style?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260603094428.2597058-1-linuxoid@gmail.com?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection
2026-06-03 9:44 [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection Ruslan Valiyev
2026-06-03 9:52 ` 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
1 sibling, 1 reply; 10+ messages in thread
From: Emil Tsalapatis @ 2026-06-04 16:45 UTC (permalink / raw)
To: Ruslan Valiyev, bpf, ast, daniel, andrii, eddyz87, martin.lau,
memxor
Cc: song, yonghong.song, jolsa
On Wed Jun 3, 2026 at 5:44 AM EDT, Ruslan Valiyev wrote:
> 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.
> + */
Remove this comment, we don't frame tests as regression tests for
specific commits. The details about .may_split and VM_DONTCOPY also
don't matter. Something like
/* Make sure arena mappings cannot be split or inherited. */
The name is also misleading, this is two tests in one. It's not just the
fork test, you are also checking may_split. I think it's worth splitting
this into two separate tests, one for partial unmaps and one for forks.
> +
> +#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);
This expression is needlessly dense, unpack it.
> + }
> + 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
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 bpf-next] selftests/bpf: add arena split and fork tests
2026-06-04 16:45 ` Emil Tsalapatis
@ 2026-06-05 11:57 ` Ruslan Valiyev
2026-06-05 12:07 ` sashiko-bot
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Ruslan Valiyev @ 2026-06-05 11:57 UTC (permalink / raw)
To: bpf, ast, daniel, andrii, eddyz87, martin.lau, memxor
Cc: song, yonghong.song, jolsa, emil
Add two tests for an arena map's mmap()ed region: arena_split checks
that a partial munmap() that would split the mapping fails with -EINVAL,
and arena_fork checks that a forked child does not inherit the mapping
(mincore() reports the range as unmapped).
Signed-off-by: Ruslan Valiyev <linuxoid@gmail.com>
---
v2:
- Drop the regression-test framing and per-callback details; use
short one-line comments.
- Split into two separate tests, arena_split (partial unmap) and
arena_fork.
- Unpack the mincore() child check into explicit statements.
.../selftests/bpf/prog_tests/arena_fork.c | 53 +++++++++++++++++++
.../selftests/bpf/prog_tests/arena_split.c | 34 ++++++++++++
2 files changed, 87 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_fork.c
create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_split.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..bb134e9adb607
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/arena_fork.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+/* Make sure an arena mapping is not inherited across fork(). */
+
+#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;
+ void *area;
+ int fd, ret, status;
+ 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;
+
+ pid = fork();
+ if (pid == 0) {
+ unsigned char vec;
+ int rc;
+
+ /* If the mapping was not inherited the range is unmapped in
+ * the child, so mincore() fails with ENOMEM. A success means
+ * the child wrongly inherited the mapping.
+ */
+ rc = mincore(area, ps, &vec);
+ if (rc == 0)
+ _exit(1);
+ _exit(errno == ENOMEM ? 0 : 2);
+ }
+ if (ASSERT_GE(pid, 0, "fork")) {
+ 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 mapping");
+ }
+
+ munmap(area, sz);
+close_fd:
+ close(fd);
+}
diff --git a/tools/testing/selftests/bpf/prog_tests/arena_split.c b/tools/testing/selftests/bpf/prog_tests/arena_split.c
new file mode 100644
index 0000000000000..8a59cfdb2ef89
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/arena_split.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+/* Make sure an arena mapping cannot be split by a partial munmap(). */
+
+#define NR_PAGES 3
+
+void test_arena_split(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;
+ void *area;
+ int fd, ret, err;
+
+ fd = bpf_map_create(BPF_MAP_TYPE_ARENA, "arena_split", 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;
+
+ ret = munmap((char *)area + ps, ps);
+ err = errno;
+ if (ASSERT_ERR(ret, "split munmap"))
+ ASSERT_EQ(err, EINVAL, "split munmap errno");
+
+ munmap(area, sz);
+close_fd:
+ close(fd);
+}
base-commit: 174914ea551314c52a61713b9c4bde9e42d48073
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 bpf-next] selftests/bpf: add arena split and fork tests
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
2 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-05 12:07 UTC (permalink / raw)
To: Ruslan Valiyev; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Multi-line comment does not follow the required BPF subsystem comment style.
--
commit f3309fb333fa0cbe670a595203f862bdefb2a073
Author: Ruslan Valiyev <linuxoid@gmail.com>
selftests/bpf: add arena split and fork tests
This commit adds two tests for an arena map's mmap()ed region. The
arena_split test checks that a partial munmap() that would split the
mapping fails with EINVAL, while arena_fork verifies that a forked child
does not inherit the mapping.
> 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..bb134e9adb607
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/arena_fork.c
[ ... ]
> + pid = fork();
> + if (pid == 0) {
> + unsigned char vec;
> + int rc;
> +
> + /* If the mapping was not inherited the range is unmapped in
> + * the child, so mincore() fails with ENOMEM. A success means
> + * the child wrongly inherited the mapping.
> + */
[Severity: Low]
This isn't a bug, but does this multi-line comment in test_arena_fork()
follow the preferred BPF subsystem comment style?
The BPF guidelines require the opening /* to be on its own line for
multi-line comments, like this:
/*
* If the mapping was not inherited the range is unmapped in
* the child...
*/
> + rc = mincore(area, ps, &vec);
> + if (rc == 0)
> + _exit(1);
> + _exit(errno == ENOMEM ? 0 : 2);
> + }
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260605115713.3224051-1-linuxoid@gmail.com?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 bpf-next] selftests/bpf: add arena split and fork tests
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
2 siblings, 0 replies; 10+ messages in thread
From: bot+bpf-ci @ 2026-06-05 12:22 UTC (permalink / raw)
To: linuxoid, bpf, ast, daniel, andrii, eddyz87, martin.lau, memxor
Cc: song, yonghong.song, jolsa, emil, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1219 bytes --]
> 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 000000000000..bb134e9adb60
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/arena_fork.c
> @@ -0,0 +1,53 @@
[ ... ]
> + pid = fork();
> + if (pid == 0) {
> + unsigned char vec;
> + int rc;
> +
> + /* If the mapping was not inherited the range is unmapped in
> + * the child, so mincore() fails with ENOMEM. A success means
> + * the child wrongly inherited the mapping.
> + */
This isn't a bug, but does this multi-line comment match the preferred
BPF subsystem comment style? The guidelines ask for the opening /* to be
on its own line, for example:
/*
* If the mapping was not inherited the range is unmapped in
* the child, so mincore() fails with ENOMEM. A success means
* the child wrongly inherited the mapping.
*/
This was raised on v2 and does not appear to be addressed yet.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27013893868
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 bpf-next] selftests/bpf: add arena split and fork tests
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
2 siblings, 2 replies; 10+ messages in thread
From: Mykyta Yatsenko @ 2026-06-05 14:31 UTC (permalink / raw)
To: Ruslan Valiyev, bpf, ast, daniel, andrii, eddyz87, martin.lau,
memxor
Cc: song, yonghong.song, jolsa, emil
On 6/5/26 12:57 PM, Ruslan Valiyev wrote:
> Add two tests for an arena map's mmap()ed region: arena_split checks
> that a partial munmap() that would split the mapping fails with -EINVAL,
> and arena_fork checks that a forked child does not inherit the mapping
> (mincore() reports the range as unmapped).
>
> Signed-off-by: Ruslan Valiyev <linuxoid@gmail.com>
> ---
Two tests are quite small and share common setup. Does it make sense to
put them into the same file, extract common function and turn them into 2 subtests.
You can check other BPF selftests to see how to implement subtests.
> v2:
> - Drop the regression-test framing and per-callback details; use
> short one-line comments.
> - Split into two separate tests, arena_split (partial unmap) and
> arena_fork.
> - Unpack the mincore() child check into explicit statements.
>
> .../selftests/bpf/prog_tests/arena_fork.c | 53 +++++++++++++++++++
> .../selftests/bpf/prog_tests/arena_split.c | 34 ++++++++++++
> 2 files changed, 87 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_fork.c
> create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_split.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..bb134e9adb607
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/arena_fork.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <test_progs.h>
> +#include <errno.h>
> +#include <sys/mman.h>
> +#include <sys/wait.h>
> +
> +/* Make sure an arena mapping is not inherited across fork(). */
> +
> +#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;
> + void *area;
> + int fd, ret, status;
> + 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;
> +
> + pid = fork();
> + if (pid == 0) {
> + unsigned char vec;
> + int rc;
> +
> + /* If the mapping was not inherited the range is unmapped in
> + * the child, so mincore() fails with ENOMEM. A success means
> + * the child wrongly inherited the mapping.
> + */
> + rc = mincore(area, ps, &vec);
> + if (rc == 0)
> + _exit(1);
> + _exit(errno == ENOMEM ? 0 : 2);
> + }
> + if (ASSERT_GE(pid, 0, "fork")) {
> + 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 mapping");
> + }
> +
> + munmap(area, sz);
> +close_fd:
> + close(fd);
> +}
> diff --git a/tools/testing/selftests/bpf/prog_tests/arena_split.c b/tools/testing/selftests/bpf/prog_tests/arena_split.c
> new file mode 100644
> index 0000000000000..8a59cfdb2ef89
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/arena_split.c
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <test_progs.h>
> +#include <errno.h>
> +#include <sys/mman.h>
> +
> +/* Make sure an arena mapping cannot be split by a partial munmap(). */
> +
> +#define NR_PAGES 3
> +
> +void test_arena_split(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;
> + void *area;
> + int fd, ret, err;
> +
> + fd = bpf_map_create(BPF_MAP_TYPE_ARENA, "arena_split", 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;
> +
> + ret = munmap((char *)area + ps, ps);
> + err = errno;
> + if (ASSERT_ERR(ret, "split munmap"))
> + ASSERT_EQ(err, EINVAL, "split munmap errno");
> +
> + munmap(area, sz);
> +close_fd:
> + close(fd);
> +}
>
> base-commit: 174914ea551314c52a61713b9c4bde9e42d48073
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 bpf-next] selftests/bpf: add arena split and fork tests
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
1 sibling, 0 replies; 10+ messages in thread
From: Ruslan Valiyev @ 2026-06-08 13:25 UTC (permalink / raw)
To: mykyta.yatsenko5, bpf, ast, daniel, andrii, eddyz87, martin.lau,
memxor
Cc: song, yonghong.song, jolsa, emil
On Fri, Jun 5, 2026 at 4:31 PM Mykyta Yatsenko <mykyta.yatsenko5@gmail.com> wrote:
> Two tests are quite small and share common setup. Does it make sense to
> put them into the same file, extract common function and turn them into
> 2 subtests. You can check other BPF selftests to see how to implement
> subtests.
Sounds good, will do in v3: one file with a shared setup helper and two
subtests, "split" and "fork".
Thanks,
Ruslan
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 bpf-next] selftests/bpf: add tests for arena vma split and fork
2026-06-05 14:31 ` Mykyta Yatsenko
2026-06-08 13:25 ` Ruslan Valiyev
@ 2026-06-09 8:37 ` Ruslan Valiyev
2026-06-09 18:40 ` Emil Tsalapatis
1 sibling, 1 reply; 10+ messages in thread
From: Ruslan Valiyev @ 2026-06-09 8:37 UTC (permalink / raw)
To: bpf, ast, daniel, andrii, eddyz87, martin.lau, memxor
Cc: song, yonghong.song, jolsa, emil, mykyta.yatsenko5
Add a test that an arena map's mmap()ed region cannot be split by a
partial munmap() (the "split" subtest, which expects -EINVAL) and is not
inherited across fork() (the "fork" subtest, where mincore() reports the
child's range as unmapped).
Signed-off-by: Ruslan Valiyev <linuxoid@gmail.com>
---
v3:
- Consolidate into one file with a shared setup helper and two
subtests.
- Put the opening /* of the multi-line comment on its own line.
v2:
- Drop the regression-test framing and per-callback details.
- Split the original single test; unpack the mincore() check.
.../selftests/bpf/prog_tests/arena_vma.c | 94 +++++++++++++++++++
1 file changed, 94 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_vma.c
diff --git a/tools/testing/selftests/bpf/prog_tests/arena_vma.c b/tools/testing/selftests/bpf/prog_tests/arena_vma.c
new file mode 100644
index 0000000000000..f6c07cd31d08b
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/arena_vma.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+/* Make sure arena mappings cannot be split or inherited. */
+
+#define NR_PAGES 3
+
+static int arena_mmap(int *fd, void **area, size_t *sz)
+{
+ LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);
+
+ *sz = (size_t)NR_PAGES * sysconf(_SC_PAGESIZE);
+
+ *fd = bpf_map_create(BPF_MAP_TYPE_ARENA, "arena_vma", 0, 0, NR_PAGES, &opts);
+ if (!ASSERT_OK_FD(*fd, "arena map create"))
+ return -1;
+
+ *area = mmap(NULL, *sz, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
+ if (!ASSERT_NEQ(*area, MAP_FAILED, "mmap arena")) {
+ close(*fd);
+ return -1;
+ }
+ return 0;
+}
+
+/* A partial munmap that would split the arena mapping must be rejected. */
+static void split_test(void)
+{
+ long ps = sysconf(_SC_PAGESIZE);
+ void *area;
+ size_t sz;
+ int fd, ret, err;
+
+ if (arena_mmap(&fd, &area, &sz))
+ return;
+
+ ret = munmap((char *)area + ps, ps);
+ err = errno;
+ if (ASSERT_ERR(ret, "split munmap"))
+ ASSERT_EQ(err, EINVAL, "split munmap errno");
+
+ munmap(area, sz);
+ close(fd);
+}
+
+/* A forked child must not inherit the arena mapping. */
+static void fork_test(void)
+{
+ long ps = sysconf(_SC_PAGESIZE);
+ void *area;
+ size_t sz;
+ int fd, ret, status;
+ pid_t pid;
+
+ if (arena_mmap(&fd, &area, &sz))
+ return;
+
+ pid = fork();
+ if (pid == 0) {
+ unsigned char vec;
+ int rc;
+
+ /*
+ * If the mapping was not inherited the range is unmapped in
+ * the child, so mincore() fails with ENOMEM. A success means
+ * the child wrongly inherited the mapping.
+ */
+ rc = mincore(area, ps, &vec);
+ if (rc == 0)
+ _exit(1);
+ _exit(errno == ENOMEM ? 0 : 2);
+ }
+ if (ASSERT_GE(pid, 0, "fork")) {
+ 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 mapping");
+ }
+
+ munmap(area, sz);
+ close(fd);
+}
+
+void test_arena_vma(void)
+{
+ if (test__start_subtest("split"))
+ split_test();
+ if (test__start_subtest("fork"))
+ fork_test();
+}
base-commit: 174914ea551314c52a61713b9c4bde9e42d48073
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 bpf-next] selftests/bpf: add tests for arena vma split and fork
2026-06-09 8:37 ` [PATCH v3 bpf-next] selftests/bpf: add tests for arena vma split and fork Ruslan Valiyev
@ 2026-06-09 18:40 ` Emil Tsalapatis
0 siblings, 0 replies; 10+ messages in thread
From: Emil Tsalapatis @ 2026-06-09 18:40 UTC (permalink / raw)
To: Ruslan Valiyev, bpf, ast, daniel, andrii, eddyz87, martin.lau,
memxor
Cc: song, yonghong.song, jolsa, emil, mykyta.yatsenko5
On Tue Jun 9, 2026 at 4:37 AM EDT, Ruslan Valiyev wrote:
> Add a test that an arena map's mmap()ed region cannot be split by a
> partial munmap() (the "split" subtest, which expects -EINVAL) and is not
> inherited across fork() (the "fork" subtest, where mincore() reports the
> child's range as unmapped).
>
> Signed-off-by: Ruslan Valiyev <linuxoid@gmail.com>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
> ---
> v3:
> - Consolidate into one file with a shared setup helper and two
> subtests.
> - Put the opening /* of the multi-line comment on its own line.
> v2:
> - Drop the regression-test framing and per-callback details.
> - Split the original single test; unpack the mincore() check.
>
> .../selftests/bpf/prog_tests/arena_vma.c | 94 +++++++++++++++++++
> 1 file changed, 94 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/prog_tests/arena_vma.c
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/arena_vma.c b/tools/testing/selftests/bpf/prog_tests/arena_vma.c
> new file mode 100644
> index 0000000000000..f6c07cd31d08b
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/arena_vma.c
> @@ -0,0 +1,94 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <test_progs.h>
> +#include <errno.h>
> +#include <sys/mman.h>
> +#include <sys/wait.h>
> +
> +/* Make sure arena mappings cannot be split or inherited. */
> +
> +#define NR_PAGES 3
> +
> +static int arena_mmap(int *fd, void **area, size_t *sz)
> +{
> + LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);
> +
> + *sz = (size_t)NR_PAGES * sysconf(_SC_PAGESIZE);
> +
> + *fd = bpf_map_create(BPF_MAP_TYPE_ARENA, "arena_vma", 0, 0, NR_PAGES, &opts);
> + if (!ASSERT_OK_FD(*fd, "arena map create"))
> + return -1;
> +
> + *area = mmap(NULL, *sz, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
> + if (!ASSERT_NEQ(*area, MAP_FAILED, "mmap arena")) {
> + close(*fd);
> + return -1;
> + }
> + return 0;
> +}
> +
> +/* A partial munmap that would split the arena mapping must be rejected. */
> +static void split_test(void)
> +{
> + long ps = sysconf(_SC_PAGESIZE);
> + void *area;
> + size_t sz;
> + int fd, ret, err;
> +
> + if (arena_mmap(&fd, &area, &sz))
> + return;
> +
> + ret = munmap((char *)area + ps, ps);
> + err = errno;
> + if (ASSERT_ERR(ret, "split munmap"))
> + ASSERT_EQ(err, EINVAL, "split munmap errno");
> +
> + munmap(area, sz);
> + close(fd);
> +}
> +
> +/* A forked child must not inherit the arena mapping. */
> +static void fork_test(void)
> +{
> + long ps = sysconf(_SC_PAGESIZE);
> + void *area;
> + size_t sz;
> + int fd, ret, status;
> + pid_t pid;
> +
> + if (arena_mmap(&fd, &area, &sz))
> + return;
> +
> + pid = fork();
> + if (pid == 0) {
> + unsigned char vec;
> + int rc;
> +
> + /*
> + * If the mapping was not inherited the range is unmapped in
> + * the child, so mincore() fails with ENOMEM. A success means
> + * the child wrongly inherited the mapping.
> + */
> + rc = mincore(area, ps, &vec);
> + if (rc == 0)
> + _exit(1);
> + _exit(errno == ENOMEM ? 0 : 2);
> + }
> + if (ASSERT_GE(pid, 0, "fork")) {
> + 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 mapping");
> + }
> +
> + munmap(area, sz);
> + close(fd);
> +}
> +
> +void test_arena_vma(void)
> +{
> + if (test__start_subtest("split"))
> + split_test();
> + if (test__start_subtest("fork"))
> + fork_test();
> +}
>
> base-commit: 174914ea551314c52a61713b9c4bde9e42d48073
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-06-09 18:40 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-03 9:44 [PATCH bpf-next] selftests/bpf: add test for arena vma split and fork rejection Ruslan Valiyev
2026-06-03 9:52 ` 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
2026-06-09 18:40 ` Emil Tsalapatis
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.