public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] gentoo-x86 commit in sys-cluster/nova/files: CVE-2013-6419_2013.2.patch CVE-2013-6419_2013.1.4.patch
@ 2013-12-13 21:10 Matt Thode (prometheanfire)
  0 siblings, 0 replies; only message in thread
From: Matt Thode (prometheanfire) @ 2013-12-13 21:10 UTC (permalink / raw
  To: gentoo-commits

prometheanfire    13/12/13 21:10:36

  Added:                CVE-2013-6419_2013.2.patch
                        CVE-2013-6419_2013.1.4.patch
  Log:
  fixes for CVE-2013-6419
  
  (Portage version: 2.2.7/cvs/Linux x86_64, signed Manifest commit with key 0x2471eb3e40ac5ac3)

Revision  Changes    Path
1.1                  sys-cluster/nova/files/CVE-2013-6419_2013.2.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/nova/files/CVE-2013-6419_2013.2.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/nova/files/CVE-2013-6419_2013.2.patch?rev=1.1&content-type=text/plain

Index: CVE-2013-6419_2013.2.patch
===================================================================
commit 2a95eee992b66cd65e401e31785c080f811476cf
Author: Aaron Rosen <arosen@nicira.com>
Date:   Mon Oct 7 13:33:31 2013 -0700

    Prevent spoofing instance_id from neturon to nova
    
    Previously, one could update a port's device_id in neutron to be that
    of another tenant's instance_id and then be able to retrieve that instance's
    metadata. This patch prevents this from occuring by checking that X-Tenant-ID
    received from the metadata request matches the tenant_id in the nova database.
    
    DocImpact - This patch is dependent on another patch in neutron which adds
                X-Tenant-ID to the request. Therefore to minimize downtime one
                should upgrade Neutron first (then restart neutron-metadata-agent)
                and lastly update nova.
    
    Fixes bug: 1235450

diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py
index 27f4d4e..7ac9023 100644
--- a/nova/api/metadata/handler.py
+++ b/nova/api/metadata/handler.py
@@ -140,29 +140,34 @@ class MetadataRequestHandler(wsgi.Application):
                     'Please try your request again.')
             raise webob.exc.HTTPInternalServerError(explanation=unicode(msg))
 
         if meta_data is None:
             LOG.error(_('Failed to get metadata for ip: %s'), remote_address)
 
         return meta_data
 
     def _handle_instance_id_request(self, req):
         instance_id = req.headers.get('X-Instance-ID')
+        tenant_id = req.headers.get('X-Tenant-ID')
         signature = req.headers.get('X-Instance-ID-Signature')
         remote_address = req.headers.get('X-Forwarded-For')
 
         # Ensure that only one header was passed
 
         if instance_id is None:
             msg = _('X-Instance-ID header is missing from request.')
+        elif tenant_id is None:
+            msg = _('X-Tenant-ID header is missing from request.')
         elif not isinstance(instance_id, basestring):
             msg = _('Multiple X-Instance-ID headers found within request.')
+        elif not isinstance(tenant_id, basestring):
+            msg = _('Multiple X-Tenant-ID headers found within request.')
         else:
             msg = None
 
         if msg:
             raise webob.exc.HTTPBadRequest(explanation=msg)
 
         expected_signature = hmac.new(
             CONF.neutron_metadata_proxy_shared_secret,
             instance_id,
             hashlib.sha256).hexdigest()
@@ -188,11 +193,19 @@ class MetadataRequestHandler(wsgi.Application):
             LOG.exception(_('Failed to get metadata for instance id: %s'),
                           instance_id)
             msg = _('An unknown error has occurred. '
                     'Please try your request again.')
             raise webob.exc.HTTPInternalServerError(explanation=unicode(msg))
 
         if meta_data is None:
             LOG.error(_('Failed to get metadata for instance id: %s'),
                       instance_id)
 
+        if meta_data.instance['project_id'] != tenant_id:
+            LOG.warning(_("Tenant_id %(tenant_id)s does not match tenant_id "
+                          "of instance %(instance_id)s."),
+                        {'tenant_id': tenant_id,
+                         'instance_id': instance_id})
+            # causes a 404 to be raised
+            meta_data = None
+
         return meta_data
diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py
index 50f0d07..e75b51f 100644
--- a/nova/tests/test_metadata.py
+++ b/nova/tests/test_metadata.py
@@ -594,74 +594,104 @@ class MetadataHandlerTestCase(test.TestCase):
             CONF.neutron_metadata_proxy_shared_secret,
             expected_instance_id,
             hashlib.sha256).hexdigest()
 
         # try a request with service disabled
         response = fake_request(
             self.stubs, self.mdinst,
             relpath="/2009-04-04/user-data",
             address="192.192.192.2",
             headers={'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
         self.assertEqual(response.status_int, 200)
 
         # now enable the service
         self.flags(service_neutron_metadata_proxy=True)
         response = fake_request(
             self.stubs, self.mdinst,
             relpath="/2009-04-04/user-data",
             address="192.192.192.2",
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Forwarded-For': '192.192.192.2',
                      'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
 
         self.assertEqual(response.status_int, 200)
         self.assertEqual(response.body,
                          base64.b64decode(self.instance['user_data']))
 
         # mismatched signature
         response = fake_request(
             self.stubs, self.mdinst,
             relpath="/2009-04-04/user-data",
             address="192.192.192.2",
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Forwarded-For': '192.192.192.2',
                      'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': ''})
 
         self.assertEqual(response.status_int, 403)
 
+        # missing X-Tenant-ID from request
+        response = fake_request(
+            self.stubs, self.mdinst,
+            relpath="/2009-04-04/user-data",
+            address="192.192.192.2",
+            fake_get_metadata_by_instance_id=fake_get_metadata,
+            headers={'X-Forwarded-For': '192.192.192.2',
+                     'X-Instance-ID': 'a-b-c-d',
+                     'X-Instance-ID-Signature': signed})
+
+        self.assertEqual(response.status_int, 400)
+
+        # mismatched X-Tenant-ID
+        response = fake_request(
+            self.stubs, self.mdinst,
+            relpath="/2009-04-04/user-data",
+            address="192.192.192.2",
+            fake_get_metadata_by_instance_id=fake_get_metadata,
+            headers={'X-Forwarded-For': '192.192.192.2',
+                     'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'FAKE',
+                     'X-Instance-ID-Signature': signed})
+
+        self.assertEqual(response.status_int, 404)
+
         # without X-Forwarded-For
         response = fake_request(
             self.stubs, self.mdinst,
             relpath="/2009-04-04/user-data",
             address="192.192.192.2",
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
 
         self.assertEqual(response.status_int, 500)
 
         # unexpected Instance-ID
         signed = hmac.new(
             CONF.neutron_metadata_proxy_shared_secret,
            'z-z-z-z',
            hashlib.sha256).hexdigest()
 
         response = fake_request(
             self.stubs, self.mdinst,
             relpath="/2009-04-04/user-data",
             address="192.192.192.2",
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Forwarded-For': '192.192.192.2',
                      'X-Instance-ID': 'z-z-z-z',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
         self.assertEqual(response.status_int, 500)
 
 
 class MetadataPasswordTestCase(test.TestCase):
     def setUp(self):
         super(MetadataPasswordTestCase, self).setUp()
         fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs)
         self.instance = copy.copy(INSTANCES[0])
         self.instance['system_metadata'] = get_default_sys_meta()



1.1                  sys-cluster/nova/files/CVE-2013-6419_2013.1.4.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/nova/files/CVE-2013-6419_2013.1.4.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/nova/files/CVE-2013-6419_2013.1.4.patch?rev=1.1&content-type=text/plain

Index: CVE-2013-6419_2013.1.4.patch
===================================================================
commit d4155b806f52f2168742ceb37988fc7f405b44cd
Author: Aaron Rosen <arosen@nicira.com>
Date:   Mon Oct 7 13:33:31 2013 -0700

    Prevent spoofing instance_id from neturon to nova
    
    Previously, one could update a port's device_id in neutron to be that
    of another tenant's instance_id and then be able to retrieve that instance's
    metadata. This patch prevents this from occuring by checking that X-Tenant-ID
    received from the metadata request matches the tenant_id in the nova database.
    
    DocImpact - This patch is dependent on another patch in neutron which adds
                X-Tenant-ID to the request. Therefore to minimize downtime one
                should upgrade Neutron first (then restart neutron-metadata-agent)
                and lastly update nova.
    
    Fixes bug: 1235450

diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py
index bbaeba5..2b7f659 100644
--- a/nova/api/metadata/handler.py
+++ b/nova/api/metadata/handler.py
@@ -144,6 +144,7 @@ class MetadataRequestHandler(wsgi.Application):
 
     def _handle_instance_id_request(self, req):
         instance_id = req.headers.get('X-Instance-ID')
+        tenant_id = req.headers.get('X-Tenant-ID')
         signature = req.headers.get('X-Instance-ID-Signature')
         remote_address = req.headers.get('X-Forwarded-For')
 
@@ -151,8 +152,12 @@ class MetadataRequestHandler(wsgi.Application):
 
         if instance_id is None:
             msg = _('X-Instance-ID header is missing from request.')
+        elif tenant_id is None:
+            msg = _('X-Tenant-ID header is missing from request.')
         elif not isinstance(instance_id, basestring):
             msg = _('Multiple X-Instance-ID headers found within request.')
+        elif not isinstance(tenant_id, basestring):
+            msg = _('Multiple X-Tenant-ID headers found within request.')
         else:
             msg = None
 
@@ -188,4 +193,12 @@ class MetadataRequestHandler(wsgi.Application):
             LOG.error(_('Failed to get metadata for instance id: %s'),
                       instance_id)
 
+        if meta_data.instance['project_id'] != tenant_id:
+            LOG.warning(_("Tenant_id %(tenant_id)s does not match tenant_id "
+                          "of instance %(instance_id)s."),
+                        {'tenant_id': tenant_id,
+                         'instance_id': instance_id})
+            # causes a 404 to be raised
+            meta_data = None
+
         return meta_data
diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py
index 01f274f..51b6f72 100644
--- a/nova/tests/test_metadata.py
+++ b/nova/tests/test_metadata.py
@@ -510,6 +510,7 @@ class MetadataHandlerTestCase(test.TestCase):
             relpath="/2009-04-04/user-data",
             address="192.192.192.2",
             headers={'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
         self.assertEqual(response.status_int, 200)
 
@@ -522,6 +523,7 @@ class MetadataHandlerTestCase(test.TestCase):
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Forwarded-For': '192.192.192.2',
                      'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
 
         self.assertEqual(response.status_int, 200)
@@ -536,10 +538,36 @@ class MetadataHandlerTestCase(test.TestCase):
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Forwarded-For': '192.192.192.2',
                      'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': ''})
 
         self.assertEqual(response.status_int, 403)
 
+        # missing X-Tenant-ID from request
+        response = fake_request(
+            self.stubs, self.mdinst,
+            relpath="/2009-04-04/user-data",
+            address="192.192.192.2",
+            fake_get_metadata_by_instance_id=fake_get_metadata,
+            headers={'X-Forwarded-For': '192.192.192.2',
+                     'X-Instance-ID': 'a-b-c-d',
+                     'X-Instance-ID-Signature': signed})
+
+        self.assertEqual(response.status_int, 400)
+
+        # mismatched X-Tenant-ID
+        response = fake_request(
+            self.stubs, self.mdinst,
+            relpath="/2009-04-04/user-data",
+            address="192.192.192.2",
+            fake_get_metadata_by_instance_id=fake_get_metadata,
+            headers={'X-Forwarded-For': '192.192.192.2',
+                     'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'FAKE',
+                     'X-Instance-ID-Signature': signed})
+
+        self.assertEqual(response.status_int, 404)
+
         # without X-Forwarded-For
         response = fake_request(
             self.stubs, self.mdinst,
@@ -547,6 +575,7 @@ class MetadataHandlerTestCase(test.TestCase):
             address="192.192.192.2",
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Instance-ID': 'a-b-c-d',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
 
         self.assertEqual(response.status_int, 500)
@@ -564,6 +593,7 @@ class MetadataHandlerTestCase(test.TestCase):
             fake_get_metadata_by_instance_id=fake_get_metadata,
             headers={'X-Forwarded-For': '192.192.192.2',
                      'X-Instance-ID': 'z-z-z-z',
+                     'X-Tenant-ID': 'test',
                      'X-Instance-ID-Signature': signed})
         self.assertEqual(response.status_int, 500)
 





^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2013-12-13 21:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-13 21:10 [gentoo-commits] gentoo-x86 commit in sys-cluster/nova/files: CVE-2013-6419_2013.2.patch CVE-2013-6419_2013.1.4.patch Matt Thode (prometheanfire)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox