summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app-admin/glance/files/cve-2015-5163-stable-kilo.patch')
-rw-r--r--app-admin/glance/files/cve-2015-5163-stable-kilo.patch260
1 files changed, 0 insertions, 260 deletions
diff --git a/app-admin/glance/files/cve-2015-5163-stable-kilo.patch b/app-admin/glance/files/cve-2015-5163-stable-kilo.patch
deleted file mode 100644
index 91507c964f43..000000000000
--- a/app-admin/glance/files/cve-2015-5163-stable-kilo.patch
+++ /dev/null
@@ -1,260 +0,0 @@
-From eb99e45829a1b4c93db5692bdbf636a86faa56c4 Mon Sep 17 00:00:00 2001
-From: Flavio Percoco <flaper87@gmail.com>
-Date: Thu, 9 Jul 2015 14:44:04 +0200
-Subject: Don't import files with backed files
-
-There's a security issue where it'd be possible to import images with
-backed files using the task engine and then use/convert those to access
-system files or any other file in the system. An example of an attack
-would be to import an image with a backing file pointing to
-`/etc/passwd`, then convert it to raw and download the generated image.
-
-This patch forbids importing files with baking files entirely. It does
-that in the `_ImportToFS` task, which is the one that imports the image
-locally to then execute other tasks on it. It's not necessary for the
-`_ImportToStore` task because other tasks won't be executed when the
-image is imported in the final store.
-
-Change-Id: I35f43c3b3f326942fb53b7dadb94700ac4513494
-Closes-bug: #1471912
-(cherry picked from commit d529863a1e8d2307526bdb395b4aebe97f81603d)
-
-diff --git a/glance/async/flows/base_import.py b/glance/async/flows/base_import.py
-index 7656bde..d216aa8 100644
---- a/glance/async/flows/base_import.py
-+++ b/glance/async/flows/base_import.py
-@@ -13,12 +13,15 @@
- # License for the specific language governing permissions and limitations
- # under the License.
-
-+import json
- import logging
- import os
-
- import glance_store as store_api
- from glance_store import backend
-+from oslo_concurrency import processutils as putils
- from oslo_config import cfg
-+from oslo_utils import excutils
- import six
- from stevedore import named
- from taskflow.patterns import linear_flow as lf
-@@ -146,6 +149,29 @@ class _ImportToFS(task.Task):
- data = script_utils.get_image_data_iter(self.uri)
-
- path = self.store.add(image_id, data, 0, context=None)[0]
-+
-+ 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,
-+ log_errors=putils.LOG_ALL_ERRORS)
-+ except OSError as exc:
-+ with excutils.save_and_reraise_exception():
-+ msg = (_LE('Failed to execute security checks on the image '
-+ '%(task_id)s: %(exc)s') %
-+ {'task_id': self.task_id, 'exc': exc.message})
-+ LOG.error(msg)
-+
-+ metadata = json.loads(stdout)
-+
-+ backing_file = metadata.get('backing-filename')
-+ if backing_file is not None:
-+ msg = _("File %(path)s has invalid backing file "
-+ "%(bfile)s, aborting.") % {'path': path,
-+ 'bfile': backing_file}
-+ raise RuntimeError(msg)
-+
- return path
-
- def revert(self, image_id, result=None, **kwargs):
-diff --git a/glance/tests/unit/async/flows/test_import.py b/glance/tests/unit/async/flows/test_import.py
-index 70f790c..4cf3d13 100644
---- a/glance/tests/unit/async/flows/test_import.py
-+++ b/glance/tests/unit/async/flows/test_import.py
-@@ -13,14 +13,17 @@
- # License for the specific language governing permissions and limitations
- # under the License.
-
-+import json
- import mock
- import os
- import urllib2
-
- import glance_store
-+from oslo_concurrency import processutils as putils
- from oslo_config import cfg
- from six.moves import cStringIO
- from taskflow import task
-+from taskflow.types import failure
-
- import glance.async.flows.base_import as import_flow
- from glance.async import taskflow_executor
-@@ -106,16 +109,23 @@ class TestImportTask(test_utils.BaseTestCase):
-
- with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
- dmock.return_value = cStringIO("TEST_IMAGE")
-- executor.begin_processing(self.task.task_id)
-- image_path = os.path.join(self.test_dir, self.image.image_id)
-- tmp_image_path = os.path.join(self.work_dir,
-- "%s.tasks_import" % image_path)
-- self.assertFalse(os.path.exists(tmp_image_path))
-- self.assertTrue(os.path.exists(image_path))
-- self.assertEqual(1, len(list(self.image.locations)))
-- self.assertEqual("file://%s/%s" % (self.test_dir,
-- self.image.image_id),
-- self.image.locations[0]['url'])
-+
-+ with mock.patch.object(putils, 'trycmd') as tmock:
-+ tmock.return_value = (json.dumps({
-+ 'format': 'qcow2',
-+ }), None)
-+
-+ executor.begin_processing(self.task.task_id)
-+ image_path = os.path.join(self.test_dir, self.image.image_id)
-+ tmp_image_path = os.path.join(self.work_dir,
-+ "%s.tasks_import" % image_path)
-+
-+ self.assertFalse(os.path.exists(tmp_image_path))
-+ self.assertTrue(os.path.exists(image_path))
-+ self.assertEqual(1, len(list(self.image.locations)))
-+ self.assertEqual("file://%s/%s" % (self.test_dir,
-+ self.image.image_id),
-+ self.image.locations[0]['url'])
-
- def test_import_flow_missing_work_dir(self):
- self.config(engine_mode='serial', group='taskflow_executor')
-@@ -151,6 +161,54 @@ class TestImportTask(test_utils.BaseTestCase):
- self.assertFalse(os.path.exists(tmp_image_path))
- self.assertTrue(os.path.exists(image_path))
-
-+ def test_import_flow_backed_file_import_to_fs(self):
-+ self.config(engine_mode='serial', group='taskflow_executor')
-+
-+ img_factory = mock.MagicMock()
-+
-+ executor = taskflow_executor.TaskExecutor(
-+ self.context,
-+ self.task_repo,
-+ self.img_repo,
-+ img_factory)
-+
-+ self.task_repo.get.return_value = self.task
-+
-+ def create_image(*args, **kwargs):
-+ kwargs['image_id'] = UUID1
-+ return self.img_factory.new_image(*args, **kwargs)
-+
-+ self.img_repo.get.return_value = self.image
-+ img_factory.new_image.side_effect = create_image
-+
-+ with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
-+ dmock.return_value = cStringIO("TEST_IMAGE")
-+
-+ with mock.patch.object(putils, 'trycmd') as tmock:
-+ tmock.return_value = (json.dumps({
-+ 'backing-filename': '/etc/password'
-+ }), None)
-+
-+ with mock.patch.object(import_flow._ImportToFS,
-+ 'revert') as rmock:
-+ self.assertRaises(RuntimeError,
-+ executor.begin_processing,
-+ self.task.task_id)
-+ self.assertTrue(rmock.called)
-+ self.assertIsInstance(rmock.call_args[1]['result'],
-+ failure.Failure)
-+
-+ image_path = os.path.join(self.test_dir,
-+ self.image.image_id)
-+
-+ fname = "%s.tasks_import" % image_path
-+ tmp_image_path = os.path.join(self.work_dir, fname)
-+
-+ self.assertFalse(os.path.exists(tmp_image_path))
-+ # Note(sabari): The image should not have been uploaded to
-+ # the store as the flow failed before ImportToStore Task.
-+ self.assertFalse(os.path.exists(image_path))
-+
- def test_import_flow_revert(self):
- self.config(engine_mode='serial',
- group='taskflow_executor')
-@@ -175,20 +233,31 @@ class TestImportTask(test_utils.BaseTestCase):
- with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
- dmock.return_value = cStringIO("TEST_IMAGE")
-
-- with mock.patch.object(import_flow, "_get_import_flows") as imock:
-- imock.return_value = (x for x in [_ErrorTask()])
-- self.assertRaises(RuntimeError,
-- executor.begin_processing, self.task.task_id)
-- image_path = os.path.join(self.test_dir, self.image.image_id)
-- tmp_image_path = os.path.join(self.work_dir,
-- "%s.tasks_import" % image_path)
-- self.assertFalse(os.path.exists(tmp_image_path))
--
-- # NOTE(flaper87): Eventually, we want this to be assertTrue.
-- # The current issue is there's no way to tell taskflow to
-- # continue on failures. That is, revert the subflow but keep
-- # executing the parent flow. Under discussion/development.
-- self.assertFalse(os.path.exists(image_path))
-+ with mock.patch.object(putils, 'trycmd') as tmock:
-+ tmock.return_value = (json.dumps({
-+ 'format': 'qcow2',
-+ }), None)
-+
-+ with mock.patch.object(import_flow,
-+ "_get_import_flows") as imock:
-+ imock.return_value = (x for x in [_ErrorTask()])
-+ self.assertRaises(RuntimeError,
-+ executor.begin_processing,
-+ self.task.task_id)
-+
-+ image_path = os.path.join(self.test_dir,
-+ self.image.image_id)
-+ tmp_image_path = os.path.join(self.work_dir,
-+ ("%s.tasks_import" %
-+ image_path))
-+ self.assertFalse(os.path.exists(tmp_image_path))
-+
-+ # NOTE(flaper87): Eventually, we want this to be assertTrue
-+ # The current issue is there's no way to tell taskflow to
-+ # continue on failures. That is, revert the subflow but
-+ # keep executing the parent flow. Under
-+ # discussion/development.
-+ self.assertFalse(os.path.exists(image_path))
-
- def test_import_flow_no_import_flows(self):
- self.config(engine_mode='serial',
-@@ -271,15 +340,20 @@ class TestImportTask(test_utils.BaseTestCase):
- with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
- dmock.return_value = "test"
-
-- 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))
-+ 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))
-+ 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))
-
- def test_delete_from_fs(self):
- delete_fs = import_flow._DeleteFromFS(self.task.task_id,
---
-cgit v0.10.2
-