bpf_arena_free_pages() accepts scalar arena addresses. The free path
masks the low 32 bits, computes the full user address, and clips only
against arena->user_vm_end before inserting the range into the arena
free range tree.
A scalar address below arena->user_vm_start can therefore produce an
out-of-domain page offset. A later allocation can consume that offset
from the free range tree and return an address outside the arena range.
Reject frees whose computed full address is below the arena start before
clipping the end of the range.
Fixes: 317460317a02 ("bpf: Introduce bpf_arena.")
Signed-off-by: Nuoqi Gui <[email protected]>
---
kernel/bpf/arena.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
index 80b7b8a69446..97a5d8d21295 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