--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openstack/glance/patches/08-CVE-2014-9623.patch Mon Mar 16 02:56:46 2015 -0700
@@ -0,0 +1,272 @@
+# This patch is taken from community. Fix is present in version 2015.2.2
+# This fix could be found in following URL
+# https://review.openstack.org/gitweb?p=openstack/glance.git;a=commit;h=f1260cc771ee068651aa62b972bef49d9af81eb0
+
+--- glance-2013.2.3.orginal/glance/api/authorization.py 2015-02-20 03:57:20.678874000 -0600
++++ glance-2013.2.3//glance/api/authorization.py 2015-02-20 04:07:24.881647830 -0600
+@@ -119,10 +119,10 @@
+ raise exception.Forbidden(message
+ % self.image.image_id)
+
+- def save(self, image_member):
++ def save(self, image_member, from_state=None):
+ if (self.context.is_admin or
+ self.context.owner == image_member.member_id):
+- updated_member = self.member_repo.save(image_member)
++ updated_member = self.member_repo.save(image_member, from_state=from_state)
+ return proxy_member(self.context, updated_member)
+ else:
+ message = _("You cannot update image member %s")
+
+--- glance-2013.2.3.orginal/glance/api/policy.py 2015-02-20 03:57:20.670610060 -0600
++++ glance-2013.2.3//glance/api/policy.py 2015-02-20 04:33:34.232748980 -0600
+@@ -174,9 +174,9 @@
+ self.policy.enforce(self.context, 'get_images', {})
+ return super(ImageRepoProxy, self).list(*args, **kwargs)
+
+- def save(self, image):
++ def save(self, image, from_state=None):
+ self.policy.enforce(self.context, 'modify_image', {})
+- return super(ImageRepoProxy, self).save(image)
++ return super(ImageRepoProxy, self).save(image, from_state=from_state)
+
+ def add(self, image):
+ self.policy.enforce(self.context, 'add_image', {})
+@@ -271,9 +271,9 @@
+ self.policy.enforce(self.context, 'get_member', {})
+ return self.member_repo.get(member_id)
+
+- def save(self, member):
++ def save(self, member, from_state=None):
+ self.policy.enforce(self.context, 'modify_member', {})
+- return self.member_repo.save(member)
++ return self.member_repo.save(member, from_state=from_state)
+
+ def list(self, *args, **kwargs):
+ self.policy.enforce(self.context, 'get_members', {})
+
+--- glance-2013.2.3.old/glance/api/v1/upload_utils.py 2014-04-03 11:43:55.000000000 -0700
++++ glance-2013.2.3/glance/api/v1/upload_utils.py 2015-03-08 23:28:12.600039932 -0700
+@@ -139,13 +139,24 @@
+ update_data = {'checksum': checksum,
+ 'size': size}
+ try:
+- image_meta = registry.update_image_metadata(req.context,
+- image_id,
+- update_data)
+-
+- except exception.NotFound as e:
+- msg = _("Image %s could not be found after upload. The image may "
+- "have been deleted during the upload.") % image_id
++ try:
++ state = 'saving'
++ image_meta = registry.update_image_metadata(req.context,
++ image_id,
++ update_data,
++ from_state=state)
++ image = registry.get_image_metadata(req.context, image_id)
++ if image['status'] == 'deleted':
++ raise exception.NotFound()
++ except exception.Duplicate:
++ image = registry.get_image_metadata(req.context, image_id)
++ if image['status'] == 'deleted':
++ raise exception.NotFound()
++ else:
++ raise
++ except exception.NotFound:
++ msg = _("Image %s could not be found after upload. The image may"
++ " have been deleted during the upload.") % image_id
+ LOG.info(msg)
+
+ # NOTE(jculp): we need to clean up the datastore if an image
+
+--- glance-2013.2.3.orginal/glance/api/v2/image_data.py 2015-02-20 03:57:20.678035080 -0600
++++ glance-2013.2.3//glance/api/v2/image_data.py 2015-02-20 05:49:21.505608540 -0600
+@@ -24,6 +24,7 @@
+ import glance.domain
+ import glance.gateway
+ import glance.notifier
++from glance.openstack.common import excutils
+ import glance.openstack.common.log as logging
+ import glance.store
+
+@@ -53,11 +54,12 @@
+ try:
+ image_repo.save(image)
+ image.set_data(data, size)
+- image_repo.save(image)
+- except exception.NotFound as e:
+- msg = (_("Image %s could not be found after upload."
+- "The image may have been deleted during the upload: %s")
+- % (image_id, e))
++ image_repo.save(image, from_state='saving')
++ except (exception.NotFound, exception.Conflict):
++ msg = (_("Image %s could not be found after upload. "
++ "The image may have been deleted during the "
++ "upload, cleaning up the chunks uploaded.") %
++ image_id)
+ LOG.warn(msg)
+ raise webob.exc.HTTPGone(explanation=msg,
+ request=req,
+@@ -111,6 +113,10 @@
+ raise webob.exc.HTTPServiceUnavailable(explanation=msg,
+ request=req)
+
++ except webob.exc.HTTPGone as e:
++ with excutils.save_and_reraise_exception():
++ LOG.error(_("Failed to upload image data due to HTTP error"))
++
+ except webob.exc.HTTPError as e:
+ LOG.error(_("Failed to upload image data due to HTTP error"))
+ raise
+
+
+
+
+diff --git glance-2013.2.3/glance/db/__init__.py glance-2013.2.3/glance/db/__init__.py
+
+index a59447d..379cf6f 100644 (file)
+
+
+--- glance-2013.2.3/glance/db/__init__.py
++++ glance-2013.2.3/glance/db/__init__.py
+@@ -162,7 +162,7 @@ class ImageRepo(object):
+ image.created_at = new_values['created_at']
+ image.updated_at = new_values['updated_at']
+
+- def save(self, image):
++ def save(self, image, from_state=None):
+ image_values = self._format_image_to_db(image)
+ if image_values['size'] > CONF.image_size_cap:
+ raise exception.ImageSizeLimitExceeded
+@@ -170,7 +170,8 @@ class ImageRepo(object):
+ new_values = self.db_api.image_update(self.context,
+ image.image_id,
+ image_values,
+- purge_props=True)
++ purge_props=True,
++ from_state=from_state)
+ except (exception.NotFound, exception.Forbidden):
+ msg = _("No image found with ID %s") % image.image_id
+ raise exception.NotFound(msg)
+@@ -263,7 +264,7 @@ class ImageMemberRepo(object):
+ msg = _("The specified member %s could not be found")
+ raise exception.NotFound(msg % image_member.id)
+
+- def save(self, image_member):
++ def save(self, image_member, from_state=None):
+ image_member_values = self._format_image_member_to_db(image_member)
+ try:
+ new_values = self.db_api.image_member_update(self.context,
+
+
+diff --git glance-2013.2.3/glance/domain/proxy.py glance-2013.2.3/glance/domain/proxy.py
+
+index 89f138c..b27b448 100644 (file)
+
+
+--- glance-2013.2.3/glance/domain/proxy.py
++++ glance-2013.2.3/glance/domain/proxy.py
+@@ -94,9 +94,9 @@ class Repo(object):
+ result = self.base.add(base_item)
+ return self.helper.proxy(result)
+
+- def save(self, item):
++ def save(self, item, from_state=None):
+ base_item = self.helper.unproxy(item)
+- result = self.base.save(base_item)
++ result = self.base.save(base_item, from_state=from_state)
+ return self.helper.proxy(result)
+
+ def remove(self, item):
+
+
+
+diff --git glance-2013.2.3/glance/store/__init__.py glance-2013.2.3/glance/store/__init__.py
+
+index 273b7c7..ae3b4c8 100644 (file)
+
+
+--- glance-2013.2.3/glance/store/__init__.py
++++ glance-2013.2.3/glance/store/__init__.py
+@@ -446,7 +446,7 @@ class ImageRepoProxy(glance.domain.proxy.Repo):
+ self._set_acls(image)
+ return result
+
+- def save(self, image):
++ def save(self, image, from_state=None):
+ result = super(ImageRepoProxy, self).save(image)
+ self._set_acls(image)
+ return result
+
+--- glance-2013.2.3.orginal/glance/quota/__init__.py 2015-02-20 03:57:20.466150810 -0600
++++ glance-2013.2.3/glance/quota/__init__.py 2015-02-25 04:44:45.714636070 -0600
+@@ -36,6 +36,28 @@
+ item_proxy_class=ImageProxy,
+ item_proxy_kwargs=proxy_kwargs)
+
++ def _enforce_image_property_quota(self, attempted):
++ if CONF.image_property_quota < 0:
++ # If value is negative, allow unlimited number of properties
++ return
++
++ maximum = CONF.image_property_quota
++ if attempted > maximum:
++ kwargs = {'attempted': attempted, 'maximum': maximum}
++ exc = exception.ImagePropertyLimitExceeded(**kwargs)
++ LOG.debug(six.text_type(exc))
++ raise exc
++
++ def save(self, image, from_state=None):
++ if image.added_new_properties():
++ self._enforce_image_property_quota(len(image.extra_properties))
++ return super(ImageRepoProxy, self).save(image, from_state=from_state)
++
++ def add(self, image):
++ self._enforce_image_property_quota(len(image.extra_properties))
++ return super(ImageRepoProxy, self).add(image)
++
++
+
+ class ImageFactoryProxy(glance.domain.proxy.ImageFactory):
+ def __init__(self, factory, context, db_api):
+
+--- glance-2013.2.3.orginal/glance/registry/client/v1/api.py 2015-02-20 03:57:20.477473040 -0600
++++ glance-2013.2.3/glance/registry/client/v1/api.py 2015-02-26 02:15:02.437773030 -0600
+@@ -164,11 +164,11 @@
+
+
+ def update_image_metadata(context, image_id, image_meta,
+- purge_props=False):
++ purge_props=False, from_state=None):
+ LOG.debug(_("Updating image metadata for image %s..."), image_id)
+ c = get_registry_client(context)
+- return c.update_image(image_id, image_meta, purge_props)
+-
++ return c.update_image(image_id, image_meta, purge_props,
++ from_state=from_state)
+
+ def delete_image_metadata(context, image_id):
+ LOG.debug(_("Deleting image metadata for image %s..."), image_id)
+
+--- glance-2013.2.3.orginal/glance/registry/client/v1/client.py 2015-02-20 03:57:20.477107680 -0600
++++ glance-2013.2.3/glance/registry/client/v1/client.py 2015-02-26 02:25:21.498753360 -0600
+@@ -165,7 +165,8 @@
+ image = data['image']
+ return self.decrypt_metadata(image)
+
+- def update_image(self, image_id, image_metadata, purge_props=False):
++ def update_image(self, image_id, image_metadata, purge_props=False,
++ from_state=None):
+ """
+ Updates Registry's information about an image
+ """
+@@ -174,6 +175,7 @@
+
+ encrypted_metadata = self.encrypt_metadata(image_metadata['image'])
+ image_metadata['image'] = encrypted_metadata
++ image_metadata['from_state'] = from_state
+ body = json.dumps(image_metadata)
+
+ headers = {
+