Merge "virt: set address space & CPU time limits when running qemu-img" into stable/liberty

This commit is contained in:
Jenkins 2016-09-22 14:30:21 +00:00 committed by Gerrit Code Review
commit f680157175
4 changed files with 46 additions and 12 deletions

View File

@ -85,6 +85,7 @@ from nova.virt import fake
from nova.virt import firewall as base_firewall
from nova.virt import hardware
from nova.virt.image import model as imgmodel
from nova.virt import images
from nova.virt.libvirt import blockinfo
from nova.virt.libvirt import config as vconfig
from nova.virt.libvirt import driver as libvirt_driver
@ -7704,7 +7705,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, "execute")
utils.execute('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
'/test/disk.local').AndReturn((ret, ''))
'/test/disk.local', prlimit=images.QEMU_IMG_LIMITS,
).AndReturn((ret, ''))
self.mox.ReplayAll()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
@ -7812,7 +7814,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, "execute")
utils.execute('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
'/test/disk.local').AndReturn((ret, ''))
'/test/disk.local', prlimit=images.QEMU_IMG_LIMITS,
).AndReturn((ret, ''))
self.mox.ReplayAll()
conn_info = {'driver_volume_type': 'fake'}

View File

@ -91,7 +91,8 @@ disk size: 96K
mock_execute.return_value = (output, '')
d_backing = libvirt_utils.get_disk_backing_file(path)
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
mock_exists.assert_called_once_with(path)
self.assertIsNone(d_backing)
@ -99,7 +100,8 @@ disk size: 96K
d_size = libvirt_utils.get_disk_size(path)
self.assertEqual(expected_size, d_size)
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
@mock.patch('os.path.exists', return_value=True)
def test_disk_size(self, mock_exists):
@ -145,7 +147,8 @@ blah BLAH: bb
mock_execute.return_value = (example_output, '')
image_info = images.qemu_img_info(path)
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
mock_exists.assert_called_once_with(path)
self.assertEqual('disk.config', image_info.image)
self.assertEqual('raw', image_info.file_format)
@ -167,7 +170,8 @@ backing file: /var/lib/nova/a328c7998805951a_2
mock_execute.return_value = (example_output, '')
image_info = images.qemu_img_info(path)
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
mock_exists.assert_called_once_with(path)
self.assertEqual('disk.config', image_info.image)
self.assertEqual('qcow2', image_info.file_format)
@ -195,7 +199,8 @@ backing file: /var/lib/nova/a328c7998805951a_2 (actual path: /b/3a988059e51a_2)
mock_execute.return_value = (example_output, '')
image_info = images.qemu_img_info(path)
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
mock_exists.assert_called_once_with(path)
self.assertEqual('disk.config', image_info.image)
self.assertEqual('raw', image_info.file_format)
@ -223,7 +228,8 @@ junk stuff: bbb
mock_execute.return_value = (example_output, '')
image_info = images.qemu_img_info(path)
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
mock_exists.assert_called_once_with(path)
self.assertEqual('disk.config', image_info.image)
self.assertEqual('raw', image_info.file_format)
@ -247,7 +253,8 @@ ID TAG VM SIZE DATE VM CLOCK
mock_execute.return_value = (example_output, '')
image_info = images.qemu_img_info(path)
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
mock_exists.assert_called_once_with(path)
self.assertEqual('disk.config', image_info.image)
self.assertEqual('raw', image_info.file_format)
@ -283,7 +290,8 @@ ID TAG VM SIZE DATE VM CLOCK
mock_execute.return_value = ('stdout', None)
libvirt_utils.create_cow_image('/some/path', '/the/new/cow')
expected_args = [(('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', '/some/path'),),
'qemu-img', 'info', '/some/path'),
{'prlimit': images.QEMU_IMG_LIMITS}),
(('qemu-img', 'create', '-f', 'qcow2',
'-o', 'backing_file=/some/path',
'/the/new/cow'),)]
@ -369,7 +377,8 @@ disk size: 4.4M
mock_execute.return_value = (example_output, '')
self.assertEqual(4592640, disk.get_disk_size('/some/path'))
mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
'qemu-img', 'info', path)
'qemu-img', 'info', path,
prlimit=images.QEMU_IMG_LIMITS)
mock_exists.assert_called_once_with(path)
def test_copy_image(self):

View File

@ -25,6 +25,7 @@ from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import fileutils
from oslo_utils import units
from nova import exception
from nova.i18n import _, _LE
@ -43,6 +44,16 @@ image_opts = [
CONF = cfg.CONF
CONF.register_opts(image_opts)
IMAGE_API = image.API()
QEMU_IMG_LIMITS = None
try:
QEMU_IMG_LIMITS = processutils.ProcessLimits(
cpu_time=2,
address_space=1 * units.Gi)
except Exception:
LOG.error(_LE('Please upgrade to oslo.concurrency version '
'2.6.1 -- this version has fixes for the '
'vulnerability CVE-2015-5162.'))
def qemu_img_info(path, format=None):
@ -61,7 +72,10 @@ def qemu_img_info(path, format=None):
if format is not None:
cmd = cmd + ('-f', format)
try:
out, err = utils.execute(*cmd)
if QEMU_IMG_LIMITS is not None:
out, err = utils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
else:
out, err = utils.execute(*cmd)
except processutils.ProcessExecutionError as exp:
msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") %
{'path': path, 'exp': exp})

View File

@ -0,0 +1,8 @@
---
security:
- The qemu-img tool now has resource limits applied
which prevent it from using more than 1GB of address
space or more than 2 seconds of CPU time. This provides
protection against denial of service attacks from
maliciously crafted or corrupted disk images.
oslo.concurrency>=2.6.1 is required for this fix.