summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Cordasco <graffatcolmingov@gmail.com>2016-12-07 09:52:30 -0600
committerMatt Riedemann <mriedem@us.ibm.com>2016-12-08 13:16:12 -0500
commit9496b9dd83a3eb9605f93e648498d837403aab44 (patch)
treeed0d0938e68315e47cddf4d96749b111b26ffaef
parent46d92cb0ba1f14698d7250aa18cf315e37cb4ffb (diff)
downloadglance-stable/liberty.tar.gz
Allow for oslo.concurrency 2.3.0liberty-eol11.0.2stable/liberty
Currently, stable/liberty has a minimum version constraint on oslo.concurrency of 2.3.0. The code needed in oslo.concurrency to avoid CVE-2015-5162 is only present in 2.6.1 and newer versions. This hack is shamelessly stolen from Nova (I135b5242af1bfdcb0ea09a6fcda21fc03a6fbe7d) to avoid breaking operators who chose to deploy with the minimum allowed version of oslo.concurrency. Change-Id: Iff51c59041e23fa158f7939891c46e9a150883fc (cherry picked from commit e3ac9c61d038e38f63a6136e0b89111b0de9d776)
-rw-r--r--glance/async/flows/base_import.py8
-rw-r--r--glance/async/flows/introspect.py7
-rw-r--r--glance/async/utils.py22
-rw-r--r--glance/tests/unit/async/flows/test_import.py29
-rw-r--r--glance/tests/unit/async/flows/test_introspect.py36
-rw-r--r--releasenotes/notes/add-processlimits-to-qemu-img-c215f5d90f741d8a.yaml9
6 files changed, 96 insertions, 15 deletions
diff --git a/glance/async/flows/base_import.py b/glance/async/flows/base_import.py
index fb0c04502..03c37cb7f 100644
--- a/glance/async/flows/base_import.py
+++ b/glance/async/flows/base_import.py
@@ -152,13 +152,17 @@ class _ImportToFS(task.Task):
path = self.store.add(image_id, data, 0, context=None)[0]
+ trycmd_kwargs = {}
+ if utils.QEMU_IMG_PROC_LIMITS is not None:
+ trycmd_kwargs['prlimit'] = utils.QEMU_IMG_PROC_LIMITS
+
try:
# NOTE(flaper87): Consider moving this code to a common
# place that other tasks can consume as well.
stdout, stderr = putils.trycmd('qemu-img', 'info',
'--output=json', path,
- prlimit=utils.QEMU_IMG_PROC_LIMITS,
- log_errors=putils.LOG_ALL_ERRORS)
+ log_errors=putils.LOG_ALL_ERRORS,
+ **trycmd_kwargs)
except OSError as exc:
with excutils.save_and_reraise_exception():
msg = (_LE('Failed to execute security checks on the image '
diff --git a/glance/async/flows/introspect.py b/glance/async/flows/introspect.py
index af1be3b7e..efc64bdb0 100644
--- a/glance/async/flows/introspect.py
+++ b/glance/async/flows/introspect.py
@@ -44,12 +44,15 @@ class _Introspect(utils.OptionalTask):
:param image_id: Glance image ID
:param file_path: Path to the file being introspected
"""
+ trycmd_kwargs = {}
+ if utils.QEMU_IMG_PROC_LIMITS is not None:
+ trycmd_kwargs['prlimit'] = utils.QEMU_IMG_PROC_LIMITS
try:
stdout, stderr = putils.trycmd('qemu-img', 'info',
'--output=json', file_path,
- prlimit=utils.QEMU_IMG_PROC_LIMITS,
- log_errors=putils.LOG_ALL_ERRORS)
+ log_errors=putils.LOG_ALL_ERRORS,
+ **trycmd_kwargs)
except OSError as exc:
# NOTE(flaper87): errno == 2 means the executable file
# was not found. For now, log an error and move forward
diff --git a/glance/async/utils.py b/glance/async/utils.py
index 3a515dfe8..f99d23348 100644
--- a/glance/async/utils.py
+++ b/glance/async/utils.py
@@ -23,14 +23,22 @@ from glance import i18n
LOG = logging.getLogger(__name__)
_LW = i18n._LW
+_LE = i18n._LE
-# NOTE(hemanthm): As reported in the bug #1449062, "qemu-img info" calls can
-# be exploited to craft DoS attacks by providing malicious input. The process
-# limits defined here are protections against such attacks. This essentially
-# limits the CPU time and address space used by the process that executes
-# "qemu-img info" command to 2 seconds and 1 GB respectively.
-QEMU_IMG_PROC_LIMITS = putils.ProcessLimits(cpu_time=2,
- address_space=1 * units.Gi)
+QEMU_IMG_PROC_LIMITS = None
+try:
+ # NOTE(hemanthm): As reported in the bug #1449062, "qemu-img info" calls
+ # can be exploited to craft DoS attacks by providing malicious input. The
+ # process limits defined here are protections against such attacks. This
+ # essentially limits the CPU time and address space used by the process
+ # that executes "qemu-img info" command to 2 seconds and 1 GB
+ # respectively.
+ QEMU_IMG_PROC_LIMITS = putils.ProcessLimits(cpu_time=2,
+ address_space=1 * units.Gi)
+except Exception:
+ LOG.error(_LE('Please upgrade to oslo.concurrency version 2.6.1 -- '
+ 'the version presently installed prevents fixing the '
+ 'vulnerability CVE-2015-5162.'))
class OptionalTask(task.Task):
diff --git a/glance/tests/unit/async/flows/test_import.py b/glance/tests/unit/async/flows/test_import.py
index 1c8d6bcc0..48d67ef89 100644
--- a/glance/tests/unit/async/flows/test_import.py
+++ b/glance/tests/unit/async/flows/test_import.py
@@ -408,6 +408,35 @@ class TestImportTask(test_utils.BaseTestCase):
self.assertTrue(os.path.exists(tmp_image_path))
self._assert_qemu_process_limits(tmock)
+ def test_import_to_fs_ignores_process_limits(self):
+ import_fs = import_flow._ImportToFS(self.task.task_id,
+ self.task_type,
+ self.task_repo,
+ 'http://example.com/image.qcow2')
+
+ with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
+ with mock.patch('glance.async.utils.QEMU_IMG_PROC_LIMITS', None):
+ dmock.return_value = "test"
+
+ with mock.patch.object(putils, 'trycmd') as tmock:
+ tmock.return_value = (json.dumps({
+ 'format': 'qcow2',
+ }), None)
+
+ image_id = UUID1
+ path = import_fs.execute(image_id)
+ reader, size = glance_store.get_from_backend(path)
+ self.assertEqual(4, size)
+ self.assertEqual(dmock.return_value, "".join(reader))
+
+ image_path = os.path.join(self.work_dir, image_id)
+ tmp_image_path = os.path.join(self.work_dir, image_path)
+ self.assertTrue(os.path.exists(tmp_image_path))
+ # NOTE(sigmavirus234): Assert that process limits are
+ # being ignores for older oslo.concurrency versions.
+ kw_args = tmock.call_args[1]
+ self.assertNotIn('prlimit', kw_args)
+
def test_delete_from_fs(self):
delete_fs = import_flow._DeleteFromFS(self.task.task_id,
self.task_type)
diff --git a/glance/tests/unit/async/flows/test_introspect.py b/glance/tests/unit/async/flows/test_introspect.py
index 869f99de4..1c0cb6005 100644
--- a/glance/tests/unit/async/flows/test_introspect.py
+++ b/glance/tests/unit/async/flows/test_introspect.py
@@ -97,6 +97,42 @@ class TestImportTask(test_utils.BaseTestCase):
self.assertEqual(async_utils.QEMU_IMG_PROC_LIMITS,
kw_args.get('prlimit'))
+ def test_introspect_quietly_refuses_to_apply_process_limits(self):
+ image_create = introspect._Introspect(self.task.task_id,
+ self.task_type,
+ self.img_repo)
+
+ self.task_repo.get.return_value = self.task
+ image_id = mock.sentinel.image_id
+ image = mock.MagicMock(image_id=image_id)
+ self.img_repo.get.return_value = image
+
+ with mock.patch.object(processutils, 'execute') as exc_mock:
+ with mock.patch('glance.async.utils.QEMU_IMG_PROC_LIMITS', None):
+ result = json.dumps({
+ "virtual-size": 10737418240,
+ "filename": "/tmp/image.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": 373030912,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "0.10"
+ }
+ },
+ "dirty-flag": False
+ })
+
+ exc_mock.return_value = (result, None)
+ image_create.execute(image, '/test/path.qcow2')
+ self.assertEqual(10737418240, image.virtual_size)
+
+ # NOTE(sigmavirus24): Assert that process limits are being
+ # ignored when oslo.concurrency is too old.
+ kw_args = exc_mock.call_args[1]
+ self.assertNotIn('prlimit', kw_args)
+
def test_introspect_no_image(self):
image_create = introspect._Introspect(self.task.task_id,
self.task_type,
diff --git a/releasenotes/notes/add-processlimits-to-qemu-img-c215f5d90f741d8a.yaml b/releasenotes/notes/add-processlimits-to-qemu-img-c215f5d90f741d8a.yaml
index 5c471d43d..eaf8388d9 100644
--- a/releasenotes/notes/add-processlimits-to-qemu-img-c215f5d90f741d8a.yaml
+++ b/releasenotes/notes/add-processlimits-to-qemu-img-c215f5d90f741d8a.yaml
@@ -1,10 +1,11 @@
---
security:
- - All ``qemu-img info`` calls are now run under resource
+ - All ``qemu-img info`` calls will be run under resource
limitations that limit the CPU time and address space
- usage of the process running the command to 2 seconds
- and 1 GB respectively. This addresses the bug
- https://bugs.launchpad.net/glance/+bug/1449062
+ usage of the process if oslo.concurrency is at least
+ version 2.6.1. ``qemu-img info`` calls are now limited
+ to 2 seconds and 1 GB respectively. This addresses the
+ bug https://bugs.launchpad.net/glance/+bug/1449062
Current usage of "qemu-img" is limited to Glance tasks.
In the Mitaka release, tasks by default will only be