]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: saveimage: validate cookieOffset and NUL-terminate XML buffer
authorHE WEI(ギカク) <skyexpoc@gmail.com>
Thu, 9 Jul 2026 10:35:22 +0000 (19:35 +0900)
committerDaniel P. Berrangé <dan-gitlab@berrange.com>
Thu, 16 Jul 2026 12:31:05 +0000 (12:31 +0000)
qemuSaveImageReadHeader() computed cookie_len = data_len - xml_len in size_t
with no check that cookieOffset <= data_len; a crafted header with
cookieOffset > data_len underflows cookie_len to ~SIZE_MAX and g_new0() aborts
the daemon. The XML buffer was also allocated to exactly xml_len with no NUL
terminator, then parsed as a C string, allowing a heap over-read for a
non-NUL-terminated payload. Reject cookieOffset > data_len and allocate one
extra (zeroed) byte for the XML terminator.

Signed-off-by: HE WEI(ギカク) <skyexpoc@gmail.com>
src/qemu/qemu_saveimage.c

index 64fbcd5f519aaf11ced84655ba3e7486b6e4e98d..d1a2bd8220852decf7b3a63fa781ac53c8ee93f6 100644 (file)
@@ -280,6 +280,12 @@ qemuSaveImageReadHeader(int fd, virQEMUSaveData **ret_data)
         return -1;
     }
 
+    if (header->cookieOffset > header->data_len) {
+        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                       _("invalid save image header: cookie offset exceeds data length"));
+        return -1;
+    }
+
     if (header->cookieOffset)
         xml_len = header->cookieOffset;
     else
@@ -287,7 +293,7 @@ qemuSaveImageReadHeader(int fd, virQEMUSaveData **ret_data)
 
     cookie_len = header->data_len - xml_len;
 
-    data->xml = g_new0(char, xml_len);
+    data->xml = g_new0(char, xml_len + 1);
 
     if (saferead(fd, data->xml, xml_len) != xml_len) {
         virReportError(VIR_ERR_OPERATION_FAILED,