From d06a10f09699ef260002cc3474b33f08aca06583 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Thu, 2 Jun 2016 13:14:11 -0400 Subject: [PATCH] Remove non-libguestfs file injection for libvirt This is a security concern, as mounting filesystems on the host has had previous CVEs around executing code on the host. libguestfs is much safer, and is the only way we should allow this. Some caveats came up during the discussion of the bug and this change which are documented in the release note. Co-Authored-By: Matt Riedemann Closes-Bug: #1552042 Change-Id: Iac8496065c8b6212d7edac320659444ab341b513 --- nova/conf/libvirt.py | 15 ++++--- nova/tests/unit/virt/disk/test_api.py | 6 +-- nova/virt/disk/vfs/api.py | 35 ++++------------ ...s-injection-fallback-2bd22422df05d99d.yaml | 41 +++++++++++++++++++ 4 files changed, 58 insertions(+), 39 deletions(-) create mode 100644 releasenotes/notes/bug-1552042-remove-non-libguestfs-injection-fallback-2bd22422df05d99d.yaml diff --git a/nova/conf/libvirt.py b/nova/conf/libvirt.py index d23bcd6427a3..9b6d361414a7 100644 --- a/nova/conf/libvirt.py +++ b/nova/conf/libvirt.py @@ -192,13 +192,12 @@ Related options: default=-2, min=-2, help=""" -Determines the way how the file system is chosen to inject data into it. +Determines how the file system is chosen to inject data into it. -*libguestfs* will be used a first solution to inject data. If that's not -available on the host, the image will be locally mounted on the host as a -fallback solution. If libguestfs is not able to determine the root partition -(because there are more or less than one root partition) or cannot mount the -file system it will result in an error and the instance won't be boot. +*libguestfs* is used to inject data. If libguestfs is not able to determine +the root partition (because there are more or less than one root partition) or +cannot mount the file system it will result in an error and the instance won't +boot. Possible values: @@ -215,8 +214,8 @@ Related options: on value greater or equal to -1 for ``inject_partition``. * ``inject_password``: If this option allows the injection of an admin password it depends on value greater or equal to -1 for ``inject_partition``. -* ``guestfs`` You can enable the debug log level of libguestfs with this - config option. A more verbose output will help in debugging issues. +* ``[guestfs]/debug`` You can enable the debug log level of libguestfs with + this config option. A more verbose output will help in debugging issues. * ``virt_type``: If you use ``lxc`` as virt_type it will be treated as a single partition image """), diff --git a/nova/tests/unit/virt/disk/test_api.py b/nova/tests/unit/virt/disk/test_api.py index 1d82ef91daf6..5b90fd186e46 100644 --- a/nova/tests/unit/virt/disk/test_api.py +++ b/nova/tests/unit/virt/disk/test_api.py @@ -22,7 +22,6 @@ from oslo_utils import units from nova import test from nova.virt.disk import api from nova.virt.disk.mount import api as mount -from nova.virt.disk.vfs import localfs from nova.virt.image import model as imgmodel @@ -41,14 +40,11 @@ class FakeMount(object): class APITestCase(test.NoDBTestCase): - @mock.patch.object(localfs.VFSLocalFS, 'get_image_fs', autospec=True, - return_value='') - def test_can_resize_need_fs_type_specified(self, mock_image_fs): + def test_can_resize_need_fs_type_specified(self): imgfile = tempfile.NamedTemporaryFile() self.addCleanup(imgfile.close) image = imgmodel.LocalFileImage(imgfile.name, imgmodel.FORMAT_QCOW2) self.assertFalse(api.is_image_extendable(image)) - self.assertTrue(mock_image_fs.called) @mock.patch('oslo_concurrency.processutils.execute', autospec=True) def test_is_image_extendable_raw(self, mock_exec): diff --git a/nova/virt/disk/vfs/api.py b/nova/virt/disk/vfs/api.py index f98404ad1d17..b9b6cb232a62 100644 --- a/nova/virt/disk/vfs/api.py +++ b/nova/virt/disk/vfs/api.py @@ -15,8 +15,6 @@ from oslo_log import log as logging from oslo_utils import importutils -from nova import exception - LOG = logging.getLogger(__name__) @@ -49,31 +47,16 @@ class VFS(object): "partition=%(partition)s", {'image': image, 'partition': partition}) - vfs = None - try: - LOG.debug("Using primary VFSGuestFS") - vfs = importutils.import_object( - "nova.virt.disk.vfs.guestfs.VFSGuestFS", - image, partition) - if not VFS.guestfs_ready: - # Inspect for capabilities and keep - # track of the result only if succeeded. - vfs.inspect_capabilities() - VFS.guestfs_ready = True - return vfs - except exception.NovaException: - if vfs is not None: - # We are able to load libguestfs but - # something wrong happens when trying to - # check for capabilities. - raise - else: - LOG.info("Unable to import guestfs, " - "falling back to VFSLocalFS") - - return importutils.import_object( - "nova.virt.disk.vfs.localfs.VFSLocalFS", + LOG.debug("Using primary VFSGuestFS") + vfs = importutils.import_object( + "nova.virt.disk.vfs.guestfs.VFSGuestFS", image, partition) + if not VFS.guestfs_ready: + # Inspect for capabilities and keep + # track of the result only if succeeded. + vfs.inspect_capabilities() + VFS.guestfs_ready = True + return vfs def __init__(self, image, partition): """Create a new local VFS instance diff --git a/releasenotes/notes/bug-1552042-remove-non-libguestfs-injection-fallback-2bd22422df05d99d.yaml b/releasenotes/notes/bug-1552042-remove-non-libguestfs-injection-fallback-2bd22422df05d99d.yaml new file mode 100644 index 000000000000..b38c4233fef4 --- /dev/null +++ b/releasenotes/notes/bug-1552042-remove-non-libguestfs-injection-fallback-2bd22422df05d99d.yaml @@ -0,0 +1,41 @@ +--- +upgrade: + - | + Be sure to read the **Security** release notes about upgrade impacts for + resolving bug 1552042. +security: + - | + When using the *libvirt* compute driver, the **libguestfs** package is now + **required** for file injection, if you are supporting that in your cloud + (see the ``[libvirt]/inject_partition`` config option). + + Previously, if the libguestfs package was not installed, the nova-compute + service would fallback to mounting to the local compute host file system + which is a security exposure. This has been discussed for years in several + forums: + + http://lists.openstack.org/pipermail/openstack-dev/2014-September/046764.html + + http://lists.openstack.org/pipermail/openstack-dev/2016-July/098703.html + + http://lists.openstack.org/pipermail/openstack-dev/2016-November/107233.html + + Furthermore, the `2.57 compute REST API microversion`_ deprecated the use + of personality files for file injection. For more history on deprecating + file injection, see the `spec`__. + + There are some known caveats with this: + + * If running on s390x, you will need libguestfs >= 1.37.14. + * At this time, FreeBSD does not have a libguestfs package, therefore + file injection cannot be supported with the libvirt driver on a FreeBSD + compute host. + * ``[libvirt]/virt_type`` config option values other than ``kvm`` or + ``qemu`` may be impacted, like ``lxc``, where libguestfs was not + previously required. + + For more background on this change, see + https://bugs.launchpad.net/nova/+bug/1552042. + + .. _2.57 compute REST API microversion: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id51 + .. __: https://specs.openstack.org/openstack/nova-specs/specs/queens/implemented/deprecate-file-injection.html