Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

xen/privcmd: fix double free via VMA splitting

privcmd_vm_ops defines .close (privcmd_close), but neither .may_split
nor .open. When userspace does a partial munmap() on a privcmd mapping,
the kernel splits the VMA via __split_vma(). Since may_split is NULL,
the split is allowed. vm_area_dup() copies vm_private_data (a pages
array allocated in alloc_empty_pages()) into the new VMA without any
fixup, because there is no .open callback.

Both VMAs now point to the same pages array. When the unmapped portion
is closed, privcmd_close() calls:
- xen_unmap_domain_gfn_range()
- xen_free_unpopulated_pages()
- kvfree(pages)

The surviving VMA still holds the dangling pointer. When it is later
destroyed, the same sequence runs again, which leads to a double free.

Fix this issue by adding a .may_split callback denying the VMA split.

This is XSA-487 / CVE-2026-31787

Fixes: d71f513985c2 ("xen: privcmd: support autotranslated physmap guests.")
Reported-by: Atharva Vartak <atharva.a.vartak@gmail.com>
Suggested-by: Atharva Vartak <atharva.a.vartak@gmail.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>

+7
+7
drivers/xen/privcmd.c
··· 1620 1620 kvfree(pages); 1621 1621 } 1622 1622 1623 + static int privcmd_may_split(struct vm_area_struct *area, unsigned long addr) 1624 + { 1625 + /* Forbid splitting, avoids double free via privcmd_close(). */ 1626 + return -EINVAL; 1627 + } 1628 + 1623 1629 static vm_fault_t privcmd_fault(struct vm_fault *vmf) 1624 1630 { 1625 1631 printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n", ··· 1637 1631 1638 1632 static const struct vm_operations_struct privcmd_vm_ops = { 1639 1633 .close = privcmd_close, 1634 + .may_split = privcmd_may_split, 1640 1635 .fault = privcmd_fault 1641 1636 }; 1642 1637