bpf: Refuse an arena mmap() longer than max_entries pages

arena_map_alloc() puts max_entries free pages in the range tree of an
arena. But the arena kfuncs check their arguments against user_vm_start and
user_vm_end. Without map_extra, arena_map_mmap() takes both from the first
vma. This vma can be up to 4 GiB long. Then arena_free_pages() also marks
pages as free that were never in the range tree. Thus max_entries does not
limit the memory of the arena, but these pages are inside kern_vm.

Refuse an mmap() longer than max_entries pages with -E2BIG. With map_extra
this limit exists already. libbpf always maps max_entries pages. Replace
both SZ_4G checks with this limit, because it is at most 4 GiB.

Fixes: 317460317a ("bpf: Introduce bpf_arena.")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261101190535.1454146-6-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-11-01 19:05:13 +00:00
parent 52498f14c2
commit 1e01345b87
No known key found for this signature in database

View File

@ -634,7 +634,7 @@ static unsigned long arena_get_unmapped_area(struct file *filp, unsigned long ad
if (pgoff)
return -EINVAL;
if (len > SZ_4G)
if (len > (u64)map->max_entries * PAGE_SIZE)
return -E2BIG;
/* if user_vm_start was specified at arena creation time */
@ -682,7 +682,7 @@ static int arena_map_mmap(struct bpf_map *map, struct vm_area_struct *vma)
return -EBUSY;
/* Earlier checks should prevent this */
if (WARN_ON_ONCE(vma->vm_end - vma->vm_start > SZ_4G || vma->vm_pgoff))
if (WARN_ON_ONCE(vma_pages(vma) > map->max_entries || vma->vm_pgoff))
return -EFAULT;
if (remember_vma(arena, vma))