]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 May 2026 17:25:09 +0000 (19:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 May 2026 17:25:09 +0000 (19:25 +0200)
added patches:
bpf-fix-use-after-free-in-arena_vm_close-on-fork.patch

queue-6.12/bpf-fix-use-after-free-in-arena_vm_close-on-fork.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/bpf-fix-use-after-free-in-arena_vm_close-on-fork.patch b/queue-6.12/bpf-fix-use-after-free-in-arena_vm_close-on-fork.patch
new file mode 100644 (file)
index 0000000..582964c
--- /dev/null
@@ -0,0 +1,92 @@
+From 4fddde2a732de60bb97e3307d4eb69ac5f1d2b74 Mon Sep 17 00:00:00 2001
+From: Alexei Starovoitov <ast@kernel.org>
+Date: Mon, 13 Apr 2026 12:42:45 -0700
+Subject: bpf: Fix use-after-free in arena_vm_close on fork
+
+From: Alexei Starovoitov <ast@kernel.org>
+
+commit 4fddde2a732de60bb97e3307d4eb69ac5f1d2b74 upstream.
+
+arena_vm_open() only bumps vml->mmap_count but never registers the
+child VMA in arena->vma_list. The vml->vma always points at the
+parent VMA, so after parent munmap the pointer dangles. If the child
+then calls bpf_arena_free_pages(), zap_pages() reads the stale
+vml->vma triggering use-after-free.
+
+Fix this by preventing the arena VMA from being inherited across
+fork with VM_DONTCOPY, and preventing VMA splits via the may_split
+callback.
+
+Also reject mremap with a .mremap callback returning -EINVAL. A
+same-size mremap(MREMAP_FIXED) on the full arena VMA reaches
+copy_vma() through the following path:
+
+  check_prep_vma()       - returns 0 early: new_len == old_len
+                           skips VM_DONTEXPAND check
+  prep_move_vma()        - vm_start == old_addr and
+                           vm_end == old_addr + old_len
+                           so may_split is never called
+  move_vma()
+    copy_vma_and_data()
+      copy_vma()
+        vm_area_dup()    - copies vm_private_data (vml pointer)
+        vm_ops->open()   - bumps vml->mmap_count
+      vm_ops->mremap()   - returns -EINVAL, rollback unmaps new VMA
+
+The refcount ensures the rollback's arena_vm_close does not free
+the vml shared with the original VMA.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Fixes: 317460317a02 ("bpf: Introduce bpf_arena.")
+Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
+Link: https://lore.kernel.org/r/20260413194245.21449-1-alexei.starovoitov@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/arena.c |   19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/kernel/bpf/arena.c
++++ b/kernel/bpf/arena.c
+@@ -236,6 +236,16 @@ static void arena_vm_open(struct vm_area
+       refcount_inc(&vml->mmap_count);
+ }
++static int arena_vm_may_split(struct vm_area_struct *vma, unsigned long addr)
++{
++      return -EINVAL;
++}
++
++static int arena_vm_mremap(struct vm_area_struct *vma)
++{
++      return -EINVAL;
++}
++
+ static void arena_vm_close(struct vm_area_struct *vma)
+ {
+       struct bpf_map *map = vma->vm_file->private_data;
+@@ -299,6 +309,8 @@ out:
+ static const struct vm_operations_struct arena_vm_ops = {
+       .open           = arena_vm_open,
++      .may_split      = arena_vm_may_split,
++      .mremap         = arena_vm_mremap,
+       .close          = arena_vm_close,
+       .fault          = arena_vm_fault,
+ };
+@@ -368,10 +380,11 @@ static int arena_map_mmap(struct bpf_map
+       arena->user_vm_end = vma->vm_end;
+       /*
+        * bpf_map_mmap() checks that it's being mmaped as VM_SHARED and
+-       * clears VM_MAYEXEC. Set VM_DONTEXPAND as well to avoid
+-       * potential change of user_vm_start.
++       * clears VM_MAYEXEC. Set VM_DONTEXPAND to avoid potential change
++       * of user_vm_start. Set VM_DONTCOPY to prevent arena VMA from
++       * being copied into the child process on fork.
+        */
+-      vm_flags_set(vma, VM_DONTEXPAND);
++      vm_flags_set(vma, VM_DONTEXPAND | VM_DONTCOPY);
+       vma->vm_ops = &arena_vm_ops;
+       return 0;
+ }
index 312509fc63b97eb3360f725272d1d27cc8c71497..cc683df651936968b7aa778a005f46153041e62e 100644 (file)
@@ -175,3 +175,4 @@ loongarch-kvm-fix-hw-timer-interrupt-lost-when-inject-interrupt-by-software.patc
 loongarch-kvm-move-unconditional-delay-into-timer-clear-scenery.patch
 loongarch-kvm-use-kvm_set_pte-in-kvm_flush_pte.patch
 loongarch-use-per-root-bridge-pcih-flag-to-skip-mem-resource-fixup.patch
+bpf-fix-use-after-free-in-arena_vm_close-on-fork.patch