--- /dev/null
+From 45d6d2dd7ae32bc230890e733a926bce7dbe09bf Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 27 Mar 2026 14:13:38 +0100
+Subject: Buffer overflow in drivers/xen/sys-hypervisor.c
+
+From: Juergen Gross <jgross@suse.com>
+
+commit 27fdbab4221b375de54bf91919798d88520c6e28 upstream.
+
+The build id returned by HYPERVISOR_xen_version(XENVER_build_id) is
+neither NUL terminated nor a string.
+
+The first causes a buffer overflow as sprintf in buildid_show will
+read and copy till it finds a NUL.
+
+00000000 f4 91 51 f4 dd 38 9e 9d 65 47 52 eb 10 71 db 50 |..Q..8..eGR..q.P|
+00000010 b9 a8 01 42 6f 2e 32 |...Bo.2|
+00000017
+
+So use a memcpy instead of sprintf to have the correct value:
+
+00000000 f4 91 51 f4 dd 00 9e 9d 65 47 52 eb 10 71 db 50 |..Q.....eGR..q.P|
+00000010 b9 a8 01 42 |...B|
+00000014
+
+(the above have a hack to embed a zero inside and check it's
+returned correctly).
+
+This is XSA-485 / CVE-2026-31786
+
+Fixes: 84b7625728ea ("xen: add sysfs node for hypervisor build id")
+Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/xen/sys-hypervisor.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/xen/sys-hypervisor.c
++++ b/drivers/xen/sys-hypervisor.c
+@@ -366,6 +366,8 @@ static ssize_t buildid_show(struct hyp_s
+ ret = sprintf(buffer, "<denied>");
+ return ret;
+ }
++ if (ret > PAGE_SIZE)
++ return -ENOSPC;
+
+ buildid = kmalloc(sizeof(*buildid) + ret, GFP_KERNEL);
+ if (!buildid)
+@@ -373,8 +375,10 @@ static ssize_t buildid_show(struct hyp_s
+
+ buildid->len = ret;
+ ret = HYPERVISOR_xen_version(XENVER_build_id, buildid);
+- if (ret > 0)
+- ret = sprintf(buffer, "%s", buildid->buf);
++ if (ret > 0) {
++ /* Build id is binary, not a string. */
++ memcpy(buffer, buildid->buf, ret);
++ }
+ kfree(buildid);
+
+ return ret;
--- /dev/null
+From 4ad984ad2a76e59f285d3f73ce0198aad2c24890 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 10 Apr 2026 09:20:04 +0200
+Subject: xen/privcmd: fix double free via VMA splitting
+
+From: Juergen Gross <jgross@suse.com>
+
+commit 24daca4fc07f3ff8cd0e3f629cd982187f48436a upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/xen/privcmd.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -1619,6 +1619,12 @@ static void privcmd_close(struct vm_area
+ 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",
+@@ -1630,6 +1636,7 @@ static vm_fault_t privcmd_fault(struct v
+
+ static const struct vm_operations_struct privcmd_vm_ops = {
+ .close = privcmd_close,
++ .may_split = privcmd_may_split,
+ .fault = privcmd_fault
+ };
+