Version in base suite: 26.2.2-1~deb12u3 Base version: nova_26.2.2-1~deb12u3 Target version: nova_26.2.2-1~deb12u4 Base file: /srv/ftp-master.debian.org/ftp/pool/main/n/nova/nova_26.2.2-1~deb12u3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/n/nova/nova_26.2.2-1~deb12u4.dsc changelog | 11 patches/cve-2026-24708-make-disk.extend-pass-format-to-qemu-img-2024.2.patch | 131 ++++++++++ patches/series | 1 3 files changed, 143 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpsrbl5u5l/nova_26.2.2-1~deb12u3.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpsrbl5u5l/nova_26.2.2-1~deb12u4.dsc: no acceptable signature found diff -Nru nova-26.2.2/debian/changelog nova-26.2.2/debian/changelog --- nova-26.2.2/debian/changelog 2024-07-10 21:49:31.000000000 +0000 +++ nova-26.2.2/debian/changelog 2026-02-06 10:19:03.000000000 +0000 @@ -1,3 +1,14 @@ +nova (2:26.2.2-1~deb12u4) bookworm-security; urgency=high + + * CVE-2026-24708/OSSA-2026-002: By writing a malicious QCOW header to a root + or ephemeral disk and then triggering a resize, a user may convince Nova's + flat image backend to call qemu-img without a format restriction resulting + in an unsafe image resize operation that could destroy data on the host + system. Appiled upstream patch (Closes: #1128294): + - cve-2026-24708-make-disk.extend-pass-format-to-qemu-img-2024.2.patch + + -- Thomas Goirand Fri, 06 Feb 2026 11:19:03 +0100 + nova (2:26.2.2-1~deb12u3) bookworm-security; urgency=high * CVE-2024-40767: Regression VMDK/qcow arbitrary file access (CVE-2024-32498) diff -Nru nova-26.2.2/debian/patches/cve-2026-24708-make-disk.extend-pass-format-to-qemu-img-2024.2.patch nova-26.2.2/debian/patches/cve-2026-24708-make-disk.extend-pass-format-to-qemu-img-2024.2.patch --- nova-26.2.2/debian/patches/cve-2026-24708-make-disk.extend-pass-format-to-qemu-img-2024.2.patch 1970-01-01 00:00:00.000000000 +0000 +++ nova-26.2.2/debian/patches/cve-2026-24708-make-disk.extend-pass-format-to-qemu-img-2024.2.patch 2026-02-06 10:19:03.000000000 +0000 @@ -0,0 +1,131 @@ +Author: Dan Smith +Date: Thu, 8 Jan 2026 08:39:10 -0800 +Subject: CVE-2026-24708/OSSA-2026-002: Make disk.extend() pass format to qemu-img + This fixes an instance of us passing a disk image to qemu-img for + resize where we don't constrain the format. As has previously been + identified, it is never safe to do that when the image itself is not + trusted. In this case, an instance with a previously-raw disk image + being used by imagebackend.Flat is susceptible to the user writing a + qcow2 (or other) header to their disk causing the unconstrained + qemu-img resize operation to interpret it as a qcow2 file. + . + Since Flat maintains the intended disk format in the disk.info file, + and since we would have safety-checked images we got from glance, + we should be able to trust the image.format specifier, which comes + from driver_format in imagebackend, which is read from disk.info. + Since only raw or qcow2 files should be resized anyway, we can further + constrain it to those. + . + Notes: + 1. qemu-img refuses to resize some types of VMDK files, but it may + be able to resize others (there are many subformats). Technically, + Flat will allow running an instance directly from a VMDK file, + and so this change _could_ be limiting existing "unintentionally + works" behavior. + 2. This assumes that disk.info is correct, present, etc. The code to + handle disk.info will regenerate the file if it's missing or + unreadable by probing the image without a safety check, which + would be unsafe. However, that is a much more sophisticated attack, + requiring either access to the system to delete the file or an + errant operator action in the first place. +Change-Id: I07cbe90b7a7a0a416ef13fbc3a1b7e2272c90951 +Bug: https://launchpad.net/bugs/2137507 +Bug-Debian: https://bugs.debian.org/1128294 +Origin: upstream, https://review.opendev.org/c/openstack/nova/+/977104 +Last-Update: 2026-02-17 + +Index: nova/nova/tests/unit/virt/disk/test_api.py +=================================================================== +--- nova.orig/nova/tests/unit/virt/disk/test_api.py ++++ nova/nova/tests/unit/virt/disk/test_api.py +@@ -19,6 +19,7 @@ from unittest import mock + from oslo_concurrency import processutils + from oslo_utils import units + ++from nova import exception + from nova import test + from nova.virt.disk import api + from nova.virt.disk.mount import api as mount +@@ -127,7 +128,7 @@ class APITestCase(test.NoDBTestCase): + + mock_can_resize.assert_called_once_with(imgfile, imgsize) + mock_exec.assert_called_once_with('qemu-img', 'resize', +- imgfile, imgsize) ++ '-f', 'qcow2', imgfile, imgsize) + mock_extendable.assert_called_once_with(image) + mock_inst.assert_called_once_with(image, None, None) + mock_resize.assert_called_once_with(mounter.device, +@@ -153,8 +154,8 @@ class APITestCase(test.NoDBTestCase): + api.extend(image, imgsize) + + mock_can_resize_image.assert_called_once_with(imgfile, imgsize) +- mock_execute.assert_called_once_with('qemu-img', 'resize', imgfile, +- imgsize) ++ mock_execute.assert_called_once_with('qemu-img', 'resize', '-f', ++ 'qcow2', imgfile, imgsize) + self.assertFalse(mock_extendable.called) + + @mock.patch.object(api, 'can_resize_image', autospec=True, +@@ -185,8 +186,34 @@ class APITestCase(test.NoDBTestCase): + api.extend(image, imgsize) + + mock_exec.assert_has_calls( +- [mock.call('qemu-img', 'resize', imgfile, imgsize), ++ [mock.call('qemu-img', 'resize', '-f', 'raw', imgfile, imgsize), + mock.call('e2label', image.path)]) + mock_resize.assert_called_once_with(imgfile, run_as_root=False, + check_exit_code=[0]) + mock_can_resize.assert_called_once_with(imgfile, imgsize) ++ ++ @mock.patch.object(api, 'can_resize_image', autospec=True, ++ return_value=True) ++ @mock.patch.object(api, 'resize2fs', autospec=True) ++ @mock.patch('oslo_concurrency.processutils.execute', autospec=True) ++ def test_extend_vmdk_failure(self, mock_exec, mock_resize, ++ mock_can_resize): ++ ++ imgfile = tempfile.NamedTemporaryFile() ++ self.addCleanup(imgfile.close) ++ imgsize = 10 ++ # NOTE(danms): There is no image.model.FORMAT_VMDK, but since the ++ # code initializes this directly from Image.disk_format without using ++ # the constant (tsk), this can actually happen at runtime. ++ self.assertRaises(exception.InvalidImageFormat, ++ imgmodel.LocalFileImage, imgfile, 'vmdk') ++ ++ # Patch ALL_FORMATS to include vmdk as if it got added at some point ++ with mock.patch('nova.virt.image.model.ALL_FORMATS', ++ new=['vmdk']): ++ image = imgmodel.LocalFileImage(imgfile, 'vmdk') ++ ++ # Make sure that we still don't call qemu-img resize on the image ++ self.assertRaises(exception.InvalidDiskFormat, ++ api.extend, image, imgsize) ++ mock_exec.assert_not_called() +Index: nova/nova/virt/disk/api.py +=================================================================== +--- nova.orig/nova/virt/disk/api.py ++++ nova/nova/virt/disk/api.py +@@ -125,7 +125,21 @@ def extend(image, size): + nova.privsep.libvirt.ploop_resize(image.path, size) + return + +- processutils.execute('qemu-img', 'resize', image.path, size) ++ # NOTE(danms): We should not call qemu-img without a format, and ++ # only qcow2 and raw are supported. So check which one we're being ++ # told this is supposed to be and pass that to qemu-img. Also note ++ # that we need to pass the qemu format string to this command, which ++ # may or may not be the same as the FORMAT_* constant, so be ++ # explicit here. ++ if image.format == imgmodel.FORMAT_RAW: ++ format = 'raw' ++ elif image.format == imgmodel.FORMAT_QCOW2: ++ format = 'qcow2' ++ else: ++ LOG.warning('Attempting to resize image %s with format %s, ' ++ 'which is not supported', image.path, image.format) ++ raise exception.InvalidDiskFormat(disk_format=image.format) ++ processutils.execute('qemu-img', 'resize', '-f', format, image.path, size) + + if (image.format != imgmodel.FORMAT_RAW and + not CONF.resize_fs_using_block_device): diff -Nru nova-26.2.2/debian/patches/series nova-26.2.2/debian/patches/series --- nova-26.2.2/debian/patches/series 2024-07-10 21:49:31.000000000 +0000 +++ nova-26.2.2/debian/patches/series 2026-02-06 10:19:03.000000000 +0000 @@ -10,3 +10,4 @@ CVE-2024-40767_2_Reproduce_iso_regression_with_deep_format_inspection_antelope.patch CVE-2024-40767_3_Add-iso-file-format-inspector_antelope.patch CVE-2024-40767_4_Change-force_format-strategy-to-catch-mismatches_antelope.patch +cve-2026-24708-make-disk.extend-pass-format-to-qemu-img-2024.2.patch