From 78f17f0ad79380ee3d9c50f2670252bcc559b62b Mon Sep 17 00:00:00 2001 From: Sean McGinnis Date: Thu, 22 Sep 2016 15:31:37 -0500 Subject: [PATCH] Limit memory & CPU when running qemu-img info It was found that a modified or corrupted image file can cause a DoS on the host when getting image info with qemu-img. This uses the newer 'prlimit' parameter for oslo.concurrency execute to set an address space limit of 1GB and CPU time limit of 2 seconds when running the qemu-img info command. Change-Id: If5b7129b266ef065642bc7898ce9dcf93722a053 Closes-bug: #1449062 --- cinder/image/image_utils.py | 6 +++++- cinder/tests/unit/test_image_utils.py | 9 ++++++--- .../notes/apply-limits-to-qemu-img-29f722a1bf4b91f8.yaml | 7 +++++++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/apply-limits-to-qemu-img-29f722a1bf4b91f8.yaml diff --git a/cinder/image/image_utils.py b/cinder/image/image_utils.py index fac5cd927ba..b9041658538 100644 --- a/cinder/image/image_utils.py +++ b/cinder/image/image_utils.py @@ -54,6 +54,9 @@ image_helper_opts = [cfg.StrOpt('image_conversion_dir', CONF = cfg.CONF CONF.register_opts(image_helper_opts) +QEMU_IMG_LIMITS = processutils.ProcessLimits( + cpu_time=2, + address_space=1 * units.Gi) # NOTE(abhishekk): qemu-img convert command supports raw, qcow2, qed, # vdi, vmdk, vhd and vhdx disk-formats but glance doesn't support qed @@ -71,7 +74,8 @@ def qemu_img_info(path, run_as_root=True): cmd = ('env', 'LC_ALL=C', 'qemu-img', 'info', path) if os.name == 'nt': cmd = cmd[2:] - out, _err = utils.execute(*cmd, run_as_root=run_as_root) + out, _err = utils.execute(*cmd, run_as_root=run_as_root, + prlimit=QEMU_IMG_LIMITS) return imageutils.QemuImgInfo(out) diff --git a/cinder/tests/unit/test_image_utils.py b/cinder/tests/unit/test_image_utils.py index 95dd82bdabd..b1eac4001a3 100644 --- a/cinder/tests/unit/test_image_utils.py +++ b/cinder/tests/unit/test_image_utils.py @@ -39,7 +39,8 @@ class TestQemuImgInfo(test.TestCase): output = image_utils.qemu_img_info(test_path) mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img', - 'info', test_path, run_as_root=True) + 'info', test_path, run_as_root=True, + prlimit=image_utils.QEMU_IMG_LIMITS) self.assertEqual(mock_info.return_value, output) @mock.patch('oslo_utils.imageutils.QemuImgInfo') @@ -52,7 +53,8 @@ class TestQemuImgInfo(test.TestCase): output = image_utils.qemu_img_info(test_path, run_as_root=False) mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img', - 'info', test_path, run_as_root=False) + 'info', test_path, run_as_root=False, + prlimit=image_utils.QEMU_IMG_LIMITS) self.assertEqual(mock_info.return_value, output) @mock.patch('cinder.image.image_utils.os') @@ -67,7 +69,8 @@ class TestQemuImgInfo(test.TestCase): output = image_utils.qemu_img_info(test_path) mock_exec.assert_called_once_with('qemu-img', 'info', test_path, - run_as_root=True) + run_as_root=True, + prlimit=image_utils.QEMU_IMG_LIMITS) self.assertEqual(mock_info.return_value, output) @mock.patch('cinder.utils.execute') diff --git a/releasenotes/notes/apply-limits-to-qemu-img-29f722a1bf4b91f8.yaml b/releasenotes/notes/apply-limits-to-qemu-img-29f722a1bf4b91f8.yaml new file mode 100644 index 00000000000..1ec4c3e6246 --- /dev/null +++ b/releasenotes/notes/apply-limits-to-qemu-img-29f722a1bf4b91f8.yaml @@ -0,0 +1,7 @@ +--- +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.