summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2026-03-27 16:13:38 +0300
committerJuergen Gross <jgross@suse.com>2026-04-23 16:32:51 +0300
commit27fdbab4221b375de54bf91919798d88520c6e28 (patch)
tree07dbd4841752a8ef8145ce6bf201c13178919ab4
parent2e68039281932e6dc37718a1ea7cbb8e2cda42e6 (diff)
downloadlinux-27fdbab4221b375de54bf91919798d88520c6e28.tar.xz
Buffer overflow in drivers/xen/sys-hypervisor.c
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>
-rw-r--r--drivers/xen/sys-hypervisor.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
index b1bb01ba82f8..91923242a5ae 100644
--- a/drivers/xen/sys-hypervisor.c
+++ b/drivers/xen/sys-hypervisor.c
@@ -366,6 +366,8 @@ static ssize_t buildid_show(struct hyp_sysfs_attr *attr, char *buffer)
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_sysfs_attr *attr, char *buffer)
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;