# HG changeset patch # User Drew Fisher # Date 1420839935 28800 # Node ID 72fb7b8866fd302804b64a829f121756ea1ac8ee # Parent b2728fae8d90a13dae0c56cd9a8e3bf360dcc614 20222847 problem in SERVICE/GLANCE diff -r b2728fae8d90 -r 72fb7b8866fd components/openstack/glance/patches/07-CVE-2014-9493.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/openstack/glance/patches/07-CVE-2014-9493.patch Fri Jan 09 13:45:35 2015 -0800 @@ -0,0 +1,140 @@ +This patch fixes bug 1400966 for Havana. +https://bugs.launchpad.net/glance/+bug/1400966 + +commit 8bdb7ed9f5beaf816e7abba726904646bf3680dd +Author: Zhi Yan Liu +Date: Mon Dec 15 12:29:55 2014 +0800 + + To prevent client use v2 patch api to handle file and swift location + + The change will be used to restrict client to download and delete any + file in glance-api server. The same resone and logic as what we did in + v1: + https://github.com/openstack/glance/blob/master/glance/api/v1/images.py#L429 + + Closes-Bug: bug/1400966 + DocImpact + + Conflicts: + glance/api/v1/images.py + glance/common/store_utils.py + glance/location.py + glance/tests/functional/v1/test_copy_to_file.py + glance/tests/functional/v2/test_images.py + glance/tests/unit/test_store_image.py + glance/tests/unit/test_store_location.py + glance/tests/unit/utils.py + glance/tests/unit/v1/test_api.py + + (cherry picked from commit 4afdb017aa1ccef01482f117cb8d0736a6da38ed) + Signed-off-by: Zhi Yan Liu + Change-Id: I72dbead3cb2dcb87f52658ddb880e26880cc229b + +--- glance-2013.2.3/glance/api/v1/images.py.orig 2014-12-23 08:16:59.633230138 -0800 ++++ glance-2013.2.3/glance/api/v1/images.py 2014-12-23 08:19:15.059375018 -0800 +@@ -50,7 +50,8 @@ import glance.registry.client.v1.api as + from glance.store import (get_from_backend, + get_size_from_backend, + get_store_from_location, +- get_store_from_scheme) ++ get_store_from_scheme, ++ validate_external_location) + + LOG = logging.getLogger(__name__) + SUPPORTED_PARAMS = glance.api.v1.SUPPORTED_PARAMS +@@ -375,20 +376,19 @@ class Controller(controller.BaseControll + @staticmethod + def _validate_source(source, req): + """ +- External sources (as specified via the location or copy-from headers) +- are supported only over non-local store types, i.e. S3, Swift, HTTP. +- Note the absence of file:// for security reasons, see LP bug #942118. +- If the above constraint is violated, we reject with 400 "Bad Request". ++ To validate if external sources (as specified via the location ++ or copy-from headers) are supported. Otherwise we reject ++ with 400 "Bad Request". + """ + if source: +- for scheme in ['s3', 'swift', 'http', 'rbd', 'sheepdog', 'cinder']: +- if source.lower().startswith(scheme): +- return source +- msg = _("External sourcing not supported for store %s") % source +- LOG.debug(msg) +- raise HTTPBadRequest(explanation=msg, +- request=req, +- content_type="text/plain") ++ if validate_external_location(source): ++ return source ++ else: ++ msg = _("External source are not supported: '%s'") % source ++ LOG.debug(msg) ++ raise HTTPBadRequest(explanation=msg, ++ request=req, ++ content_type="text/plain") + + @staticmethod + def _copy_from(req): +--- glance-2013.2.3/glance/store/__init__.py.orig 2014-12-23 08:20:52.254600393 -0800 ++++ glance-2013.2.3/glance/store/__init__.py 2014-12-23 08:23:48.661399000 -0800 +@@ -21,6 +21,7 @@ import sys + import time + + from oslo.config import cfg ++import six.moves.urllib.parse as urlparse + + from glance.common import crypt + from glance.common import exception +@@ -369,6 +370,24 @@ def set_acls(context, location_uri, publ + LOG.debug(_("Skipping store.set_acls... not implemented.")) + + ++def validate_external_location(uri): ++ """ ++ Validate if URI of external location are supported. ++ ++ Only over non-local store types are OK, i.e. S3, Swift, ++ HTTP. Note the absence of 'file://' for security reasons, ++ see LP bug #942118, 1400966, 'swift+config://' is also ++ absent for security reasons, see LP bug #1334196. ++ ++ :param uri: The URI of external image location. ++ :return: Whether given URI of external image location are OK. ++ """ ++ pieces = urlparse.urlparse(uri) ++ valid_schemes = [scheme for scheme in location.SCHEME_TO_CLS_MAP.keys() ++ if scheme != 'file' and scheme != 'swift+config'] ++ return pieces.scheme in valid_schemes ++ ++ + class ImageRepoProxy(glance.domain.proxy.Repo): + + def __init__(self, image_repo, context, store_api): +@@ -401,22 +420,23 @@ class ImageRepoProxy(glance.domain.proxy + + + def _check_location_uri(context, store_api, uri): +- """ +- Check if an image location uri is valid. ++ """Check if an image location is valid. + + :param context: Glance request context + :param store_api: store API module + :param uri: location's uri string + """ ++ + is_ok = True + try: +- size = store_api.get_size_from_backend(context, uri) + # NOTE(zhiyan): Some stores return zero when it catch exception +- is_ok = size > 0 ++ is_ok = (store_api.validate_external_location(uri) and ++ store_api.get_size_from_backend(context, uri) > 0) + except (exception.UnknownScheme, exception.NotFound): + is_ok = False + if not is_ok: +- raise exception.BadStoreUri(_('Invalid location: %s') % uri) ++ reason = _('Invalid location') ++ raise exception.BadStoreUri(message=reason) + + + def _check_image_location(context, store_api, location):