diff options
Diffstat (limited to 'app-admin/glance/files/CVE-2015-5286_2015.1.1.patch')
-rw-r--r-- | app-admin/glance/files/CVE-2015-5286_2015.1.1.patch | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/app-admin/glance/files/CVE-2015-5286_2015.1.1.patch b/app-admin/glance/files/CVE-2015-5286_2015.1.1.patch new file mode 100644 index 000000000000..04781355e2ba --- /dev/null +++ b/app-admin/glance/files/CVE-2015-5286_2015.1.1.patch @@ -0,0 +1,137 @@ +From 5bebd513fa71edcdb84f7dec7b16f3523c0c1092 Mon Sep 17 00:00:00 2001 +From: Mike Fedosin <mfedosin@mirantis.com> +Date: Sun, 20 Sep 2015 17:01:22 +0300 +Subject: Cleanup chunks for deleted image if token expired + +In patch I47229b366c25367ec1bd48aec684e0880f3dfe60 it was +introduced the logic that if image was deleted during file +upload when we want to update image status from 'saving' +to 'active' it's expected to get Duplicate error and delete +stale chunks after that. But if user's token is expired +there will be Unathorized exception and chunks will stay +in store and clog it. +And when, the upload operation for such an image is +completed the operator configured quota can be exceeded. + +This patch fixes the issue of left over chunks for an image +which was deleted from saving status, by correctly handle +auth exceptions from registry server. + +Partial-bug: #1498163 + +Conflicts: + glance/api/v1/upload_utils.py + (Kilo catches NotFound instead of ImagenotFound) + +Change-Id: I17a66eca55bfb83107046910e69c4da01415deec +(cherry picked from commit 98a8832777a0639a4031e52c69f0d565b3f500c5) + +diff --git a/glance/api/v1/upload_utils.py b/glance/api/v1/upload_utils.py +index 7adb2dc..ad4f724 100644 +--- a/glance/api/v1/upload_utils.py ++++ b/glance/api/v1/upload_utils.py +@@ -171,6 +171,14 @@ def upload_data_to_store(req, image_meta, image_data, store, notifier): + raise exception.NotFound() + else: + raise ++ ++ except exception.NotAuthenticated as e: ++ # Delete image data due to possible token expiration. ++ LOG.debug("Authentication error - the token may have " ++ "expired during file upload. Deleting image data for " ++ " %s " % image_id) ++ initiate_deletion(req, location_data, image_id) ++ raise webob.exc.HTTPUnauthorized(explanation=e.msg, request=req) + except exception.NotFound: + msg = _LI("Image %s could not be found after upload. The image may" + " have been deleted during the upload.") % image_id +diff --git a/glance/api/v2/image_data.py b/glance/api/v2/image_data.py +index 4025eeb..9967662 100644 +--- a/glance/api/v2/image_data.py ++++ b/glance/api/v2/image_data.py +@@ -88,7 +88,19 @@ class ImageDataController(object): + raise webob.exc.HTTPGone(explanation=msg, + request=req, + content_type='text/plain') +- ++ except exception.NotAuthenticated: ++ msg = (_("Authentication error - the token may have " ++ "expired during file upload. Deleting image data for " ++ "%s.") % image_id) ++ LOG.debug(msg) ++ try: ++ image.delete() ++ except exception.NotAuthenticated: ++ # NOTE: Ignore this exception ++ pass ++ raise webob.exc.HTTPUnauthorized(explanation=msg, ++ request=req, ++ content_type='text/plain') + except ValueError as e: + LOG.debug("Cannot save data for image %(id)s: %(e)s", + {'id': image_id, 'e': utils.exception_to_str(e)}) +diff --git a/glance/tests/unit/v1/test_upload_utils.py b/glance/tests/unit/v1/test_upload_utils.py +index 1afaf00..8d05515 100644 +--- a/glance/tests/unit/v1/test_upload_utils.py ++++ b/glance/tests/unit/v1/test_upload_utils.py +@@ -323,3 +323,29 @@ class TestUploadUtils(base.StoreClearingUnitTest): + 'metadata': {}}, image_meta['id']) + mock_safe_kill.assert_called_once_with( + req, image_meta['id'], 'saving') ++ ++ @mock.patch.object(registry, 'update_image_metadata', ++ side_effect=exception.NotAuthenticated) ++ @mock.patch.object(upload_utils, 'initiate_deletion') ++ def test_activate_image_with_expired_token( ++ self, mocked_delete, mocked_update): ++ """Test token expiration during image upload. ++ ++ If users token expired before image was uploaded then if auth error ++ was caught from registry during changing image status from 'saving' ++ to 'active' then it's required to delete all image data. ++ """ ++ context = mock.Mock() ++ req = mock.Mock() ++ req.context = context ++ with self._get_store_and_notifier() as (location, checksum, image_meta, ++ image_data, store, notifier, ++ update_data): ++ self.assertRaises(webob.exc.HTTPUnauthorized, ++ upload_utils.upload_data_to_store, ++ req, image_meta, image_data, store, notifier) ++ self.assertEqual(2, mocked_update.call_count) ++ mocked_delete.assert_called_once_with( ++ req, ++ {'url': 'file://foo/bar', 'status': 'active', 'metadata': {}}, ++ 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d') +diff --git a/glance/tests/unit/v2/test_image_data_resource.py b/glance/tests/unit/v2/test_image_data_resource.py +index bc8891e..7458eda 100644 +--- a/glance/tests/unit/v2/test_image_data_resource.py ++++ b/glance/tests/unit/v2/test_image_data_resource.py +@@ -192,6 +192,23 @@ class TestImagesController(base.StoreClearingUnitTest): + self.assertRaises(webob.exc.HTTPBadRequest, self.controller.upload, + request, unit_test_utils.UUID1, 'YYYY', 4) + ++ def test_upload_with_expired_token(self): ++ def side_effect(image, from_state=None): ++ if from_state == 'saving': ++ raise exception.NotAuthenticated() ++ ++ mocked_save = mock.Mock(side_effect=side_effect) ++ mocked_delete = mock.Mock() ++ request = unit_test_utils.get_fake_request() ++ image = FakeImage('abcd') ++ image.delete = mocked_delete ++ self.image_repo.result = image ++ self.image_repo.save = mocked_save ++ self.assertRaises(webob.exc.HTTPUnauthorized, self.controller.upload, ++ request, unit_test_utils.UUID1, 'YYYY', 4) ++ self.assertEqual(3, mocked_save.call_count) ++ mocked_delete.assert_called_once_with() ++ + def test_upload_non_existent_image_during_save_initiates_deletion(self): + def fake_save_not_found(self): + raise exception.NotFound() +-- +cgit v0.10.2 + |