components/openstack/nova/patches/05-CVE-2014-0167.patch
changeset 1944 56ac2df1785b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openstack/nova/patches/05-CVE-2014-0167.patch	Wed Jun 11 17:13:12 2014 -0700
@@ -0,0 +1,146 @@
+This upstream patch addresses CVE-2014-0167 and is tracked under
+Launchpad bug 1290537. It is addressed in Icehouse 2014.1 and Havana
+2013.2.4.
+
+commit dbb7dd03fea68120ef5ac9bbb1b3f184e3f2eacc
+Author: Andrew Laski <[email protected]>
+Date:   Wed Apr 9 09:27:44 2014 -0400
+
+    Add RBAC policy for ec2 API security groups calls
+    
+    The revoke_security_group_ingress, revoke_security_group_ingress, and
+    delete_security_group calls in the ec2 API were not restricted by policy
+    checks.  This prevented a deployer from restricting their usage via
+    roles or other checks.  Checks have been added for these calls.
+    
+    Based on commit d4056f8723cc6cefb28ff6e5a7c0df5ea77f82ef but modified
+    for the backport.
+    
+    Closes-Bug: #1290537
+    Change-Id: I4bf681bedd68ed2216b429d34db735823e0a6189
+
+diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
+index 94ff160..36c2f12 100644
+--- a/nova/api/ec2/cloud.py
++++ b/nova/api/ec2/cloud.py
+@@ -30,6 +30,7 @@ from oslo.config import cfg
+ from nova.api.ec2 import ec2utils
+ from nova.api.ec2 import inst_state
+ from nova.api.metadata import password
++from nova.api.openstack import extensions
+ from nova.api import validator
+ from nova import availability_zones
+ from nova import block_device
+@@ -85,6 +86,9 @@ LOG = logging.getLogger(__name__)
+ 
+ QUOTAS = quota.QUOTAS
+ 
++security_group_authorizer = extensions.extension_authorizer('compute',
++                                                            'security_groups')
++
+ 
+ def validate_ec2_id(val):
+     if not validator.validate_str()(val):
+@@ -631,6 +635,8 @@ class CloudController(object):
+         security_group = self.security_group_api.get(context, group_name,
+                                                      group_id)
+ 
++        security_group_authorizer(context, security_group)
++
+         prevalues = kwargs.get('ip_permissions', [kwargs])
+ 
+         rule_ids = []
+@@ -665,6 +671,8 @@ class CloudController(object):
+         security_group = self.security_group_api.get(context, group_name,
+                                                      group_id)
+ 
++        security_group_authorizer(context, security_group)
++
+         prevalues = kwargs.get('ip_permissions', [kwargs])
+         postvalues = []
+         for values in prevalues:
+@@ -737,6 +745,8 @@ class CloudController(object):
+         security_group = self.security_group_api.get(context, group_name,
+                                                      group_id)
+ 
++        security_group_authorizer(context, security_group)
++
+         self.security_group_api.destroy(context, security_group)
+ 
+         return True
+diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py
+index 269a738..b28d194 100644
+--- a/nova/tests/api/ec2/test_cloud.py
++++ b/nova/tests/api/ec2/test_cloud.py
+@@ -23,6 +23,7 @@ import copy
+ import datetime
+ import functools
+ import iso8601
++import mock
+ import os
+ import string
+ import tempfile
+@@ -47,6 +48,7 @@ from nova.image import s3
+ from nova.network import api as network_api
+ from nova.network import neutronv2
+ from nova.openstack.common import log as logging
++from nova.openstack.common import policy as common_policy
+ from nova.openstack.common import timeutils
+ from nova import test
+ from nova.tests.api.openstack.compute.contrib import (
+@@ -471,6 +473,34 @@ class CloudTestCase(test.TestCase):
+         delete = self.cloud.delete_security_group
+         self.assertRaises(exception.MissingParameter, delete, self.context)
+ 
++    def test_delete_security_group_policy_not_allowed(self):
++        rules = common_policy.Rules(
++                {'compute_extension:security_groups':
++                    common_policy.parse_rule('project_id:%(project_id)s')})
++        common_policy.set_rules(rules)
++
++        with mock.patch.object(self.cloud.security_group_api,
++                'get') as get:
++            get.return_value = {'project_id': 'invalid'}
++
++            self.assertRaises(exception.PolicyNotAuthorized,
++                    self.cloud.delete_security_group, self.context,
++                    'fake-name', 'fake-id')
++
++    def test_authorize_security_group_ingress_policy_not_allowed(self):
++        rules = common_policy.Rules(
++                {'compute_extension:security_groups':
++                    common_policy.parse_rule('project_id:%(project_id)s')})
++        common_policy.set_rules(rules)
++
++        with mock.patch.object(self.cloud.security_group_api,
++                'get') as get:
++            get.return_value = {'project_id': 'invalid'}
++
++            self.assertRaises(exception.PolicyNotAuthorized,
++                    self.cloud.authorize_security_group_ingress, self.context,
++                    'fake-name', 'fake-id')
++
+     def test_authorize_security_group_ingress(self):
+         kwargs = {'project_id': self.context.project_id, 'name': 'test'}
+         sec = db.security_group_create(self.context, kwargs)
+@@ -575,6 +605,20 @@ class CloudTestCase(test.TestCase):
+         db.security_group_destroy(self.context, sec2['id'])
+         db.security_group_destroy(self.context, sec1['id'])
+ 
++    def test_revoke_security_group_ingress_policy_not_allowed(self):
++        rules = common_policy.Rules(
++                {'compute_extension:security_groups':
++                    common_policy.parse_rule('project_id:%(project_id)s')})
++        common_policy.set_rules(rules)
++
++        with mock.patch.object(self.cloud.security_group_api,
++                'get') as get:
++            get.return_value = {'project_id': 'invalid'}
++
++            self.assertRaises(exception.PolicyNotAuthorized,
++                    self.cloud.revoke_security_group_ingress, self.context,
++                    'fake-name', 'fake-id')
++
+     def test_revoke_security_group_ingress(self):
+         kwargs = {'project_id': self.context.project_id, 'name': 'test'}
+         sec = db.security_group_create(self.context, kwargs)