drivers/xen/privcmd.c | 7 +++++++ 1 file changed, 7 insertions(+)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Xen Security Advisory CVE-2026-31787 / XSA-487
version 2
Linux kernel double free in Xen privcmd driver
UPDATES IN VERSION 2
====================
Public release.
ISSUE DESCRIPTION
=================
The Linux kernel's privcmd driver can be abused to circumvent kernel
lockdown (secure boot) by causing a double free of kernel memory.
Note that this operation can be performed by root only, so any
further impact on the system (like denial of service) is not security
relevant.
IMPACT
======
An administrator of a domain booted in secure mode is able to perform
actions on the kernel which should not be possible in secure mode.
VULNERABLE SYSTEMS
==================
Linux PVH or HVM domains (x86 or Arm) from kernel 3.8 onwards are
vulnerable.
PV domains or non-Linux domains are not vulnerable.
MITIGATION
==========
There is no mitigation available.
CREDITS
=======
This issue was discovered by Atharva Vartak (@0xAth4rv).
RESOLUTION
==========
Applying the attached patch resolves this issue.
xsa487-linux.patch Linux
$ sha256sum xsa487*
fc7ccf9697203c14ced4364d70175b463b08a17a7559fd8654a12b623b54e5bb xsa487-linux.patch
$
DEPLOYMENT DURING EMBARGO
=========================
Deployment of patches or mitigations is NOT permitted (except where
all the affected systems and VMs are administered and used only by
organisations which are members of the Xen Project Security Issues
Predisclosure List). Specifically, deployment on public cloud systems
is NOT permitted.
This is because the patch needs to be applied to the guest.
Deployment is permitted only AFTER the embargo ends.
(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable. This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)
For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----
iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAmnwoQUMHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZKRkH/A2DLI9IzMFrmuzksitp7G+MD/AWq3jJe93IAeU1
/QguHV7pQXFyhb1zWR/+DB4zt5tAcGIs75enob8njm3HZ/e5Ht6aSlYq+Rl5ZO6w
kK4aUljpRUxPTOg/PHPKn2sTkZccQxXGxmara5PwhZf0uXb0BBB33dhWbkxQoAR/
FzHSFNHvJKZct/fmmavE38R4AVel0GC3Ufi1jQ44l85xBWtmWN4+ioEno4tDqKkk
d9fmRfCoPta2zCL8DezC3y/LC7x8bbLeL1CMFchnVW+JjJOON22K2R/12dvBFUOF
If+HuBOHviA02fDW86H+sKTn/KnCI1jNjgUto9tCIkdyvSI=
=NY86
-----END PGP SIGNATURE-----
From 5577c003018abb1ad92dc4032cc71b1718a83dfa Mon Sep 17 00:00:00 2001
From: Juergen Gross <jgross@suse.com>
Date: Fri, 10 Apr 2026 09:20:04 +0200
Subject: [PATCH] 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>
---
drivers/xen/privcmd.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 15ba592236e8..725a49a0eee7 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -1620,6 +1620,12 @@ static void privcmd_close(struct vm_area_struct *vma)
kvfree(pages);
}
+static int privcmd_may_split(struct vm_area_struct *area, unsigned long addr)
+{
+ /* Forbid splitting, avoids double free via privcmd_close(). */
+ return -EINVAL;
+}
+
static vm_fault_t privcmd_fault(struct vm_fault *vmf)
{
printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n",
@@ -1631,6 +1637,7 @@ static vm_fault_t privcmd_fault(struct vm_fault *vmf)
static const struct vm_operations_struct privcmd_vm_ops = {
.close = privcmd_close,
+ .may_split = privcmd_may_split,
.fault = privcmd_fault
};
--
2.53.0
© 2016 - 2026 Red Hat, Inc.