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 <mriedem.os@gmail.com>

Closes-Bug: #1552042

Change-Id: Iac8496065c8b6212d7edac320659444ab341b513
This commit is contained in:
Sean Dague 2016-06-02 13:14:11 -04:00 committed by Balazs Gibizer
parent 5b66caab87
commit d06a10f096
4 changed files with 58 additions and 39 deletions

View File

@ -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
"""),

View File

@ -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):

View File

@ -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

View File

@ -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