Skip to content

Commit b90d77e

Browse files
Alexei Starovoitovborkmann
authored andcommitted
bpf: Fix remap of arena.
The bpf arena logic didn't account for mremap operation. Add a refcnt for multiple mmap events to prevent use-after-free in arena_vm_close. Fixes: 3174603 ("bpf: Introduce bpf_arena.") Reported-by: Pengfei Xu <pengfei.xu@intel.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Barret Rhoden <brho@google.com> Tested-by: Pengfei Xu <pengfei.xu@intel.com> Closes: https://lore.kernel.org/bpf/Zmuw29IhgyPNKnIM@xpf.sh.intel.com Link: https://lore.kernel.org/bpf/20240617171812.76634-1-alexei.starovoitov@gmail.com
1 parent bfbcb2c commit b90d77e

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

kernel/bpf/arena.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ static u64 arena_map_mem_usage(const struct bpf_map *map)
212212
struct vma_list {
213213
struct vm_area_struct *vma;
214214
struct list_head head;
215+
atomic_t mmap_count;
215216
};
216217

217218
static int remember_vma(struct bpf_arena *arena, struct vm_area_struct *vma)
@@ -221,20 +222,30 @@ static int remember_vma(struct bpf_arena *arena, struct vm_area_struct *vma)
221222
vml = kmalloc(sizeof(*vml), GFP_KERNEL);
222223
if (!vml)
223224
return -ENOMEM;
225+
atomic_set(&vml->mmap_count, 1);
224226
vma->vm_private_data = vml;
225227
vml->vma = vma;
226228
list_add(&vml->head, &arena->vma_list);
227229
return 0;
228230
}
229231

232+
static void arena_vm_open(struct vm_area_struct *vma)
233+
{
234+
struct vma_list *vml = vma->vm_private_data;
235+
236+
atomic_inc(&vml->mmap_count);
237+
}
238+
230239
static void arena_vm_close(struct vm_area_struct *vma)
231240
{
232241
struct bpf_map *map = vma->vm_file->private_data;
233242
struct bpf_arena *arena = container_of(map, struct bpf_arena, map);
234-
struct vma_list *vml;
243+
struct vma_list *vml = vma->vm_private_data;
235244

245+
if (!atomic_dec_and_test(&vml->mmap_count))
246+
return;
236247
guard(mutex)(&arena->lock);
237-
vml = vma->vm_private_data;
248+
/* update link list under lock */
238249
list_del(&vml->head);
239250
vma->vm_private_data = NULL;
240251
kfree(vml);
@@ -287,6 +298,7 @@ static vm_fault_t arena_vm_fault(struct vm_fault *vmf)
287298
}
288299

289300
static const struct vm_operations_struct arena_vm_ops = {
301+
.open = arena_vm_open,
290302
.close = arena_vm_close,
291303
.fault = arena_vm_fault,
292304
};

0 commit comments

Comments
 (0)