components/openstack/nova/patches/05-CVE-2014-0167.patch
author Drew Fisher <drew.fisher@oracle.com>
Wed, 11 Jun 2014 17:13:12 -0700
changeset 1944 56ac2df1785b
permissions -rw-r--r--
PSARC/2014/207 OpenStack Glance Update to Havana PSARC/2014/208 OpenStack Cinder Update to Havana PSARC/2014/209 OpenStack Keystone Update to Havana PSARC/2014/210 OpenStack Nova Update to Havana 18416146 Neutron agents (L3 and DHCP) should cleanup resources when they are disabled 18562372 Failed to create a new project under Horizon 18645763 ZFSSA Cinder Driver support 18686327 evs agent silently ignores user-specified pool allocation ranges 18702697 fibre channel volumes should be supported in the cinder volume driver 18734289 nova won't terminate failed kz deployments 18738371 cinder-volume:setup should account for commented-out zfs_volume_base 18738374 cinder-volume:setup should check for existence of configuration file 18826190 nova-compute fails due to nova.utils.to_bytes 18855698 Update OpenStack to Havana 2013.2.3 18855710 Update python-cinderclient to 1.0.9 18855743 Update python-keystoneclient to 0.8.0 18855754 Update python-neutronclient to 2.3.4 18855764 Update python-novaclient to 2.17.0 18855793 Update python-swiftclient to 2.1.0 18856992 External networks can be deleted even when floating IP addresses are in use 18857784 bake in some more openstack configuration 18884923 Incorrect locale facets in python modules for openstack 18913890 the error in _get_view_and_lun may cause the failure of deleting volumes 18943044 Disable 'Security Groups' tab in Horizon dashboard

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)