mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH bpf-next v2 0/2] bpf: Reject arena frees below the arena base
@ 2026-07-17 12:53 Yiyang Chen
  2026-07-17 12:53 ` [PATCH bpf-next v2 1/2] " Yiyang Chen
  2026-07-17 12:53 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover scalar arena frees below the base Yiyang Chen
  0 siblings, 2 replies; 4+ messages in thread
From: Yiyang Chen @ 2026-07-17 12:53 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Yiyang Chen, Martin KaFai Lau, Song Liu, Yonghong Song,
	Jiri Olsa, Shuah Khan, Emil Tsalapatis, Puranjay Mohan, bpf,
	linux-kselftest, linux-kernel

bpf_arena_free_pages() can be called with a scalar arena address. The
runtime reconstructs a full user address from the arena base and the low
32 bits before returning the range to the arena free tree. A scalar one
page below the arena base can otherwise produce an out-of-domain free-tree
offset and make a later allocation return an address below the arena
mapping.

Patch 1 rejects frees whose reconstructed full user address is below
user_vm_start. Patch 2 adds verifier_arena coverage for the
scalar-below-base case.

Changes in v2:
- Add Reviewed-by tags from Emil Tsalapatis.
- Remove the empty inline asm from the selftest.

v1: https://lore.kernel.org/bpf/cover.1782813442.git.chenyy23@mails.tsinghua.edu.cn/

Yiyang Chen (2):
  bpf: Reject arena frees below the arena base
  selftests/bpf: Cover scalar arena frees below the base

 kernel/bpf/arena.c                                 |  2 ++
 tools/testing/selftests/bpf/progs/verifier_arena.c | 40 +++++++++++++++++++---
 2 files changed, 37 insertions(+), 5 deletions(-)

base-commit: 1d91ea01185656ac3ee63c5f9f6f8bde3c746b3d
-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH bpf-next v2 1/2] bpf: Reject arena frees below the arena base
  2026-07-17 12:53 [PATCH bpf-next v2 0/2] bpf: Reject arena frees below the arena base Yiyang Chen
@ 2026-07-17 12:53 ` Yiyang Chen
  2026-07-17 12:53 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover scalar arena frees below the base Yiyang Chen
  1 sibling, 0 replies; 4+ messages in thread
From: Yiyang Chen @ 2026-07-17 12:53 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Yiyang Chen, Martin KaFai Lau, Song Liu, Yonghong Song,
	Jiri Olsa, Shuah Khan, Emil Tsalapatis, Puranjay Mohan, bpf,
	linux-kselftest, linux-kernel

bpf_arena_free_pages() accepts scalar arena addresses. The runtime
masks the address to the low 32 bits and reconstructs a full user
address from the arena base before returning the range to the arena
free tree.

When the scalar value is below the low 32 bits of the arena base,
full_uaddr falls below user_vm_start. The existing upper-end clipping
then turns this into an out-of-range free-tree offset. A later
allocation can reuse that offset and return an address below the arena
mapping.

Reject such frees before computing the clipped range.

Fixes: 317460317a02a ("bpf: Introduce bpf_arena.")
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
 kernel/bpf/arena.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
index 80b7b8a694464..97a5d8d212955 100644
--- a/kernel/bpf/arena.c
+++ b/kernel/bpf/arena.c
@@ -853,6 +853,8 @@ static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt,
 	uaddr &= PAGE_MASK;
 	kaddr = bpf_arena_get_kern_vm_start(arena) + uaddr;
 	full_uaddr = clear_lo32(arena->user_vm_start) + uaddr;
+	if (full_uaddr < arena->user_vm_start)
+		return;
 	uaddr_end = min(arena->user_vm_end, full_uaddr + (page_cnt << PAGE_SHIFT));
 	if (full_uaddr >= uaddr_end)
 		return;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH bpf-next v2 2/2] selftests/bpf: Cover scalar arena frees below the base
  2026-07-17 12:53 [PATCH bpf-next v2 0/2] bpf: Reject arena frees below the arena base Yiyang Chen
  2026-07-17 12:53 ` [PATCH bpf-next v2 1/2] " Yiyang Chen
@ 2026-07-17 12:53 ` Yiyang Chen
  2026-07-17 13:39   ` bot+bpf-ci
  1 sibling, 1 reply; 4+ messages in thread
From: Yiyang Chen @ 2026-07-17 12:53 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Yiyang Chen, Martin KaFai Lau, Song Liu, Yonghong Song,
	Jiri Olsa, Shuah Khan, Emil Tsalapatis, Puranjay Mohan, bpf,
	linux-kselftest, linux-kernel

Add a verifier_arena case that fills a two-page arena, calls
bpf_arena_free_pages() with a scalar address one page below the arena
base, and then verifies that another allocation is still rejected.

Before the runtime guard, the invalid free can repopulate the free
tree with an out-of-domain offset and the final allocation succeeds.

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
 tools/testing/selftests/bpf/progs/verifier_arena.c | 40 +++++++++++++++++++---
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/bpf/progs/verifier_arena.c b/tools/testing/selftests/bpf/progs/verifier_arena.c
index df0e22d1a29b1..b241bbcf54a8a 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena.c
@@ -12,15 +12,17 @@
 
 #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
 
+#ifdef __TARGET_ARCH_arm64
+#define ARENA_VM_START ((1ull << 32) | (~0u - __PAGE_SIZE * 2 + 1))
+#else
+#define ARENA_VM_START ((1ull << 44) | (~0u - __PAGE_SIZE * 2 + 1))
+#endif
+
 struct {
 	__uint(type, BPF_MAP_TYPE_ARENA);
 	__uint(map_flags, BPF_F_MMAPABLE);
 	__uint(max_entries, 2); /* arena of two pages close to 32-bit boundary*/
-#ifdef __TARGET_ARCH_arm64
-        __ulong(map_extra, (1ull << 32) | (~0u - __PAGE_SIZE * 2 + 1)); /* start of mmap() region */
-#else
-        __ulong(map_extra, (1ull << 44) | (~0u - __PAGE_SIZE * 2 + 1)); /* start of mmap() region */
-#endif
+	__ulong(map_extra, ARENA_VM_START); /* start of mmap() region */
 } arena SEC(".maps");
 
 SEC("socket")
@@ -93,6 +95,34 @@ int basic_alloc1(void *ctx)
 	return 0;
 }
 
+SEC("syscall")
+__success __retval(0)
+int free_scalar_below_arena(void *ctx)
+{
+	void __arena *page1, *page2, *page3;
+	__u64 bad_addr = ARENA_VM_START - __PAGE_SIZE;
+
+	page1 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+	if (!page1)
+		return 1;
+
+	page2 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+	if (!page2)
+		return 2;
+
+	page3 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+	if (page3)
+		return 3;
+
+	bpf_arena_free_pages(&arena, (void __arena *)bad_addr, 1);
+
+	page3 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+	if (page3)
+		return 4;
+
+	return 0;
+}
+
 SEC("socket")
 __success __retval(0)
 int basic_alloc2_nosleep(void *ctx)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Cover scalar arena frees below the base
  2026-07-17 12:53 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover scalar arena frees below the base Yiyang Chen
@ 2026-07-17 13:39   ` bot+bpf-ci
  0 siblings, 0 replies; 4+ messages in thread
From: bot+bpf-ci @ 2026-07-17 13:39 UTC (permalink / raw)
  To: chenyy23, ast, daniel, andrii, eddyz87, memxor
  Cc: chenyy23, martin.lau, song, yonghong.song, jolsa, shuah, emil,
	puranjay, bpf, linux-kselftest, linux-kernel, ast, andrii,
	daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 1364 bytes --]

>     selftests/bpf: Cover scalar arena frees below the base
>
>     Add a verifier_arena case that fills a two-page arena, calls
>     bpf_arena_free_pages() with a scalar address one page below the arena
>     base, and then verifies that another allocation is still rejected.
>
>     Before the runtime guard, the invalid free can repopulate the free
>     tree with an out-of-domain offset and the final allocation succeeds.
>
>     Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
>     Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>

This test covers a memory-safety issue where bpf_arena_free_pages()
accepts a scalar address below the arena base and repopulates the free
tree with an out-of-domain offset, so a later allocation can return an
address below the arena mapping.

The clipping logic in arena_free_pages() that only bounded the upper end
(uaddr_end = min(...)) without checking full_uaddr >= arena->user_vm_start
was introduced in commit 317460317a02a.  The paired kernel fix
a6ceda1f4a47 also carries that tag.

Should this include:

  Fixes: 317460317a02a ("bpf: Introduce bpf_arena.")


---
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/29583169394

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-17 13:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-17 12:53 [PATCH bpf-next v2 0/2] bpf: Reject arena frees below the arena base Yiyang Chen
2026-07-17 12:53 ` [PATCH bpf-next v2 1/2] " Yiyang Chen
2026-07-17 12:53 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover scalar arena frees below the base Yiyang Chen
2026-07-17 13:39   ` bot+bpf-ci

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox