diff options
Diffstat (limited to 'sys-cluster/nova/files/cve-2015-7548-stable-liberty-0003.patch')
-rw-r--r-- | sys-cluster/nova/files/cve-2015-7548-stable-liberty-0003.patch | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/sys-cluster/nova/files/cve-2015-7548-stable-liberty-0003.patch b/sys-cluster/nova/files/cve-2015-7548-stable-liberty-0003.patch new file mode 100644 index 000000000000..b542041b5311 --- /dev/null +++ b/sys-cluster/nova/files/cve-2015-7548-stable-liberty-0003.patch @@ -0,0 +1,171 @@ +From 62516194c424abad3bec12ea360dde06617fe97d Mon Sep 17 00:00:00 2001 +From: Matthew Booth <mbooth@redhat.com> +Date: Fri, 11 Dec 2015 13:40:54 +0000 +Subject: [PATCH 3/3] Fix backing file detection in libvirt live snapshot + +When doing a live snapshot, the libvirt driver creates an intermediate +qcow2 file with the same backing file as the original disk. However, +it calls qemu-img info without specifying the input format explicitly. +An authenticated user can write data to a raw disk which will cause +this code to misinterpret the disk as a qcow2 file with a +user-specified backing file on the host, and return an arbitrary host +file as the backing file. + +This bug does not appear to result in a data leak in this case, but +this is hard to verify. It certainly results in corrupt output. + +Closes-Bug: #1524274 + +Change-Id: I11485f077d28f4e97529a691e55e3e3c0bea8872 +(cherry picked from commit ccea9095d9fb5bcdcb61ee5e352c4a8163754b9d) +--- + nova/tests/unit/virt/libvirt/fake_libvirt_utils.py | 4 ++-- + nova/tests/unit/virt/libvirt/test_driver.py | 7 ++++--- + nova/virt/images.py | 8 +++++--- + nova/virt/libvirt/driver.py | 11 +++++++---- + nova/virt/libvirt/utils.py | 9 +++++---- + 5 files changed, 23 insertions(+), 16 deletions(-) + +diff --git a/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py b/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py +index 52d1e85..b474687 100644 +--- a/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py ++++ b/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py +@@ -32,11 +32,11 @@ def create_cow_image(backing_file, path): + pass + + +-def get_disk_size(path): ++def get_disk_size(path, format=None): + return 0 + + +-def get_disk_backing_file(path): ++def get_disk_backing_file(path, format=None): + return disk_backing_files.get(path, None) + + +diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py +index 6fd8728..6d0afdf 100644 +--- a/nova/tests/unit/virt/libvirt/test_driver.py ++++ b/nova/tests/unit/virt/libvirt/test_driver.py +@@ -12018,7 +12018,7 @@ class LibvirtConnTestCase(test.NoDBTestCase): + + image_meta = objects.ImageMeta.from_dict(self.test_image_meta) + drvr._live_snapshot(self.context, self.test_instance, guest, +- srcfile, dstfile, "qcow2", image_meta) ++ srcfile, dstfile, "qcow2", "qcow2", image_meta) + + mock_dom.XMLDesc.assert_called_once_with(flags=( + fakelibvirt.VIR_DOMAIN_XML_INACTIVE | +@@ -12029,8 +12029,9 @@ class LibvirtConnTestCase(test.NoDBTestCase): + fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT | + fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_SHALLOW)) + +- mock_size.assert_called_once_with(srcfile) +- mock_backing.assert_called_once_with(srcfile, basename=False) ++ mock_size.assert_called_once_with(srcfile, format="qcow2") ++ mock_backing.assert_called_once_with(srcfile, basename=False, ++ format="qcow2") + mock_create_cow.assert_called_once_with(bckfile, dltfile, 1004009) + mock_chown.assert_called_once_with(dltfile, os.getuid()) + mock_snapshot.assert_called_once_with(dltfile, "qcow2", +diff --git a/nova/virt/images.py b/nova/virt/images.py +index e2b5b91..6f3e487 100644 +--- a/nova/virt/images.py ++++ b/nova/virt/images.py +@@ -44,7 +44,7 @@ CONF.register_opts(image_opts) + IMAGE_API = image.API() + + +-def qemu_img_info(path): ++def qemu_img_info(path, format=None): + """Return an object containing the parsed output from qemu-img info.""" + # TODO(mikal): this code should not be referring to a libvirt specific + # flag. +@@ -56,8 +56,10 @@ def qemu_img_info(path): + msg = (_("Path does not exist %(path)s") % {'path': path}) + raise exception.InvalidDiskInfo(reason=msg) + +- out, err = utils.execute('env', 'LC_ALL=C', 'LANG=C', +- 'qemu-img', 'info', path) ++ cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path) ++ if format is not None: ++ cmd = cmd + ('-f', format) ++ out, err = utils.execute(*cmd) + if not out: + msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") % + {'path': path, 'error': err}) +diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py +index 51b1e4b..53a27b2 100644 +--- a/nova/virt/libvirt/driver.py ++++ b/nova/virt/libvirt/driver.py +@@ -1434,7 +1434,8 @@ class LibvirtDriver(driver.ComputeDriver): + # NOTE(xqueralt): libvirt needs o+x in the temp directory + os.chmod(tmpdir, 0o701) + self._live_snapshot(context, instance, guest, disk_path, +- out_path, image_format, image_meta) ++ out_path, source_format, image_format, ++ image_meta) + else: + snapshot_backend.snapshot_extract(out_path, image_format) + finally: +@@ -1540,7 +1541,7 @@ class LibvirtDriver(driver.ComputeDriver): + self._set_quiesced(context, instance, image_meta, False) + + def _live_snapshot(self, context, instance, guest, disk_path, out_path, +- image_format, image_meta): ++ source_format, image_format, image_meta): + """Snapshot an instance without downtime.""" + dev = guest.get_block_device(disk_path) + +@@ -1558,9 +1559,11 @@ class LibvirtDriver(driver.ComputeDriver): + # in QEMU 1.3. In order to do this, we need to create + # a destination image with the original backing file + # and matching size of the instance root disk. +- src_disk_size = libvirt_utils.get_disk_size(disk_path) ++ src_disk_size = libvirt_utils.get_disk_size(disk_path, ++ format=source_format) + src_back_path = libvirt_utils.get_disk_backing_file(disk_path, +- basename=False) ++ format=source_format, ++ basename=False) + disk_delta = out_path + '.delta' + libvirt_utils.create_cow_image(src_back_path, disk_delta, + src_disk_size) +diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py +index 062b2fb..7b0cf42 100644 +--- a/nova/virt/libvirt/utils.py ++++ b/nova/virt/libvirt/utils.py +@@ -160,24 +160,25 @@ def pick_disk_driver_name(hypervisor_version, is_block_dev=False): + return None + + +-def get_disk_size(path): ++def get_disk_size(path, format=None): + """Get the (virtual) size of a disk image + + :param path: Path to the disk image ++ :param format: the on-disk format of path + :returns: Size (in bytes) of the given disk image as it would be seen + by a virtual machine. + """ +- size = images.qemu_img_info(path).virtual_size ++ size = images.qemu_img_info(path, format).virtual_size + return int(size) + + +-def get_disk_backing_file(path, basename=True): ++def get_disk_backing_file(path, basename=True, format=None): + """Get the backing file of a disk image + + :param path: Path to the disk image + :returns: a path to the image's backing store + """ +- backing_file = images.qemu_img_info(path).backing_file ++ backing_file = images.qemu_img_info(path, format).backing_file + if backing_file and basename: + backing_file = os.path.basename(backing_file) + +-- +2.5.0 + |