[PATCH bpf-next 2/2] selftests/bpf: Cover out-of-range arena free addresses
From: Nuoqi Gui
Date: Mon Jul 06 2026 - 12:28:14 EST
Add a verifier selftest that fills a two-page arena, frees the page below
the arena start through a scalar value, and checks that a third allocation
is still unavailable.
Without the arena free range check, the out-of-range free can be inserted
into the free range tree and then allocated again, so the test returns 3.
With the fix, the out-of-range free is ignored and the focused test passes.
Signed-off-by: Nuoqi Gui <gnq25@xxxxxxxxxxxxxxxxxxxxx>
---
tools/testing/selftests/bpf/progs/verifier_arena.c | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_arena.c b/tools/testing/selftests/bpf/progs/verifier_arena.c
index df0e22d1a29b..b21a8895804f 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena.c
@@ -11,6 +11,7 @@
#include <bpf_arena_common.h>
#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
+#define ARENA_VM_START_L32 (~0u - __PAGE_SIZE * 2 + 1)
struct {
__uint(type, BPF_MAP_TYPE_ARENA);
@@ -93,6 +94,31 @@ int basic_alloc1(void *ctx)
return 0;
}
+SEC("syscall")
+__success __retval(0)
+int free_pages_out_of_bounds(void *ctx)
+{
+#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
+ __u64 page1, page2, no_page;
+ __u64 below_start = (__u32)(ARENA_VM_START_L32 - __PAGE_SIZE);
+
+ page1 = (__u64)bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+ if (!page1)
+ return 1;
+ page2 = (__u64)bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+ if (!page2)
+ return 2;
+
+ asm volatile("" : "+r"(below_start));
+ bpf_arena_free_pages(&arena, (void __arena *)below_start, 1);
+
+ no_page = (__u64)bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+ if (no_page)
+ return 3;
+#endif
+ return 0;
+}
+
SEC("socket")
__success __retval(0)
int basic_alloc2_nosleep(void *ctx)
--
2.34.1