~ubuntu-branches/ubuntu/saucy/nova/saucy-proposed

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2012-2101.patch

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-05-24 13:12:53 UTC
  • mfrom: (1.1.55)
  • Revision ID: package-import@ubuntu.com-20120524131253-ommql08fg1en06ut
Tags: 2012.2~f1-0ubuntu1
* New upstream release.
* Prepare for quantal:
  - Dropped debian/patches/upstream/0006-Use-project_id-in-ec2.cloud._format_image.patch
  - Dropped debian/patches/upstream/0005-Populate-image-properties-with-project_id-again.patch
  - Dropped debian/patches/upstream/0004-Fixed-bug-962840-added-a-test-case.patch
  - Dropped debian/patches/upstream/0003-Allow-unprivileged-RADOS-users-to-access-rbd-volumes.patch
  - Dropped debian/patches/upstream/0002-Stop-libvirt-test-from-deleting-instances-dir.patch
  - Dropped debian/patches/upstream/0001-fix-bug-where-nova-ignores-glance-host-in-imageref.patch 
  - Dropped debian/patches/0001-fix-useexisting-deprecation-warnings.patch
* debian/control: Add python-keystone as a dependency. (LP: #907197)
* debian/patches/kombu_tests_timeout.patch: Refreshed.
* debian/nova.conf, debian/nova-common.postinst: Convert to new ini
  file configuration
* debian/patches/nova-manage_flagfile_location.patch: Refreshed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Origin: Pre-disclosure from upstream
2
 
Description: Place limit on number of security groups a user may create
3
 
Index: nova-2012.1/nova/api/ec2/cloud.py
4
 
===================================================================
5
 
--- nova-2012.1.orig/nova/api/ec2/cloud.py      2012-05-03 15:24:56.000000000 -0500
6
 
+++ nova-2012.1/nova/api/ec2/cloud.py   2012-05-03 15:39:18.000000000 -0500
7
 
@@ -42,6 +42,7 @@
8
 
 from nova import log as logging
9
 
 from nova import network
10
 
 from nova.rpc import common as rpc_common
11
 
+from nova import quota
12
 
 from nova import utils
13
 
 from nova import volume
14
 
 
15
 
@@ -727,6 +728,13 @@
16
 
                     raise exception.EC2APIError(err % values_for_rule)
17
 
                 postvalues.append(values_for_rule)
18
 
 
19
 
+        allowed = quota.allowed_security_group_rules(context,
20
 
+                                                   security_group['id'],
21
 
+                                                   1)
22
 
+        if allowed < 1:
23
 
+            msg = _("Quota exceeded, too many security group rules.")
24
 
+            raise exception.EC2APIError(msg)
25
 
+
26
 
         rule_ids = []
27
 
         for values_for_rule in postvalues:
28
 
             security_group_rule = db.security_group_rule_create(
29
 
@@ -784,6 +792,10 @@
30
 
             msg = _('group %s already exists')
31
 
             raise exception.EC2APIError(msg % group_name)
32
 
 
33
 
+        if quota.allowed_security_groups(context, 1) < 1:
34
 
+            msg = _("Quota exceeded, too many security groups.")
35
 
+            raise exception.EC2APIError(msg)
36
 
+
37
 
         group = {'user_id': context.user_id,
38
 
                  'project_id': context.project_id,
39
 
                  'name': group_name,
40
 
Index: nova-2012.1/nova/api/openstack/compute/contrib/quotas.py
41
 
===================================================================
42
 
--- nova-2012.1.orig/nova/api/openstack/compute/contrib/quotas.py       2012-04-04 13:29:56.000000000 -0500
43
 
+++ nova-2012.1/nova/api/openstack/compute/contrib/quotas.py    2012-05-03 15:39:18.000000000 -0500
44
 
@@ -31,7 +31,7 @@
45
 
 
46
 
 quota_resources = ['metadata_items', 'injected_file_content_bytes',
47
 
         'volumes', 'gigabytes', 'ram', 'floating_ips', 'instances',
48
 
-        'injected_files', 'cores']
49
 
+        'injected_files', 'cores', 'security_groups', 'security_group_rules']
50
 
 
51
 
 
52
 
 class QuotaTemplate(xmlutil.TemplateBuilder):
53
 
Index: nova-2012.1/nova/api/openstack/compute/contrib/security_groups.py
54
 
===================================================================
55
 
--- nova-2012.1.orig/nova/api/openstack/compute/contrib/security_groups.py      2012-04-04 13:29:54.000000000 -0500
56
 
+++ nova-2012.1/nova/api/openstack/compute/contrib/security_groups.py   2012-05-03 15:39:18.000000000 -0500
57
 
@@ -31,6 +31,7 @@
58
 
 from nova import exception
59
 
 from nova import flags
60
 
 from nova import log as logging
61
 
+from nova import quota
62
 
 from nova import utils
63
 
 
64
 
 
65
 
@@ -289,6 +290,10 @@
66
 
         group_name = group_name.strip()
67
 
         group_description = group_description.strip()
68
 
 
69
 
+        if quota.allowed_security_groups(context, 1) < 1:
70
 
+            msg = _("Quota exceeded, too many security groups.")
71
 
+            raise exc.HTTPBadRequest(explanation=msg)
72
 
+
73
 
         LOG.audit(_("Create Security Group %s"), group_name, context=context)
74
 
         self.compute_api.ensure_default_security_group(context)
75
 
         if db.security_group_exists(context, context.project_id, group_name):
76
 
@@ -376,6 +381,13 @@
77
 
             msg = _('This rule already exists in group %s') % parent_group_id
78
 
             raise exc.HTTPBadRequest(explanation=msg)
79
 
 
80
 
+        allowed = quota.allowed_security_group_rules(context,
81
 
+                                                   parent_group_id,
82
 
+                                                   1)
83
 
+        if allowed < 1:
84
 
+            msg = _("Quota exceeded, too many security group rules.")
85
 
+            raise exc.HTTPBadRequest(explanation=msg)
86
 
+
87
 
         security_group_rule = db.security_group_rule_create(context, values)
88
 
         self.sgh.trigger_security_group_rule_create_refresh(
89
 
             context, [security_group_rule['id']])
90
 
Index: nova-2012.1/nova/db/api.py
91
 
===================================================================
92
 
--- nova-2012.1.orig/nova/db/api.py     2012-04-04 13:29:56.000000000 -0500
93
 
+++ nova-2012.1/nova/db/api.py  2012-05-03 15:39:18.000000000 -0500
94
 
@@ -1118,6 +1118,11 @@
95
 
     return IMPL.security_group_destroy(context, security_group_id)
96
 
 
97
 
 
98
 
+def security_group_count_by_project(context, project_id):
99
 
+    """Count number of security groups in a project."""
100
 
+    return IMPL.security_group_count_by_project(context, project_id)
101
 
+
102
 
+
103
 
 ####################
104
 
 
105
 
 
106
 
@@ -1149,6 +1154,11 @@
107
 
     return IMPL.security_group_rule_get(context, security_group_rule_id)
108
 
 
109
 
 
110
 
+def security_group_rule_count_by_group(context, security_group_id):
111
 
+    """Count rules in a given security group."""
112
 
+    return IMPL.security_group_rule_count_by_group(context, security_group_id)
113
 
+
114
 
+
115
 
 ###################
116
 
 
117
 
 
118
 
Index: nova-2012.1/nova/db/sqlalchemy/api.py
119
 
===================================================================
120
 
--- nova-2012.1.orig/nova/db/sqlalchemy/api.py  2012-04-04 13:29:56.000000000 -0500
121
 
+++ nova-2012.1/nova/db/sqlalchemy/api.py       2012-05-03 15:39:18.000000000 -0500
122
 
@@ -2813,6 +2813,13 @@
123
 
                         'updated_at': literal_column('updated_at')})
124
 
 
125
 
 
126
 
+@require_context
127
 
+def security_group_count_by_project(context, project_id):
128
 
+    authorize_project_context(context, project_id)
129
 
+    return model_query(context, models.SecurityGroup, read_deleted="no").\
130
 
+                   filter_by(project_id=project_id).\
131
 
+                   count()
132
 
+
133
 
 ###################
134
 
 
135
 
 
136
 
@@ -2871,6 +2878,14 @@
137
 
         security_group_rule.delete(session=session)
138
 
 
139
 
 
140
 
+@require_context
141
 
+def security_group_rule_count_by_group(context, security_group_id):
142
 
+    return model_query(context, models.SecurityGroupIngressRule,
143
 
+                   read_deleted="no").\
144
 
+                   filter_by(parent_group_id=security_group_id).\
145
 
+                   count()
146
 
+
147
 
+#
148
 
 ###################
149
 
 
150
 
 
151
 
@@ -3018,6 +3033,7 @@
152
 
         user_ref.save(session=session)
153
 
 
154
 
 
155
 
+#
156
 
 ###################
157
 
 
158
 
 
159
 
Index: nova-2012.1/nova/quota.py
160
 
===================================================================
161
 
--- nova-2012.1.orig/nova/quota.py      2012-04-04 13:29:56.000000000 -0500
162
 
+++ nova-2012.1/nova/quota.py   2012-05-03 15:39:18.000000000 -0500
163
 
@@ -54,6 +54,12 @@
164
 
     cfg.IntOpt('quota_max_injected_file_path_bytes',
165
 
                default=255,
166
 
                help='number of bytes allowed per injected file path'),
167
 
+    cfg.IntOpt('quota_security_groups',
168
 
+               default=10,
169
 
+               help='number of security groups per project'),
170
 
+    cfg.IntOpt('quota_security_group_rules',
171
 
+               default=20,
172
 
+               help='number of security rules per security group'),
173
 
     ]
174
 
 
175
 
 FLAGS = flags.FLAGS
176
 
@@ -72,6 +78,8 @@
177
 
         'injected_files': FLAGS.quota_max_injected_files,
178
 
         'injected_file_content_bytes':
179
 
             FLAGS.quota_max_injected_file_content_bytes,
180
 
+        'security_groups': FLAGS.quota_security_groups,
181
 
+        'security_group_rules': FLAGS.quota_security_group_rules,
182
 
     }
183
 
     # -1 in the quota flags means unlimited
184
 
     for key in defaults.keys():
185
 
@@ -152,6 +160,32 @@
186
 
     return min(requested_floating_ips, allowed_floating_ips)
187
 
 
188
 
 
189
 
+def allowed_security_groups(context, requested_security_groups):
190
 
+    """Check quota and return min(requested, allowed) security groups."""
191
 
+    project_id = context.project_id
192
 
+    context = context.elevated()
193
 
+    used_sec_groups = db.security_group_count_by_project(context, project_id)
194
 
+    quota = get_project_quotas(context, project_id)
195
 
+    allowed_sec_groups = _get_request_allotment(requested_security_groups,
196
 
+                                                  used_sec_groups,
197
 
+                                                  quota['security_groups'])
198
 
+    return min(requested_security_groups, allowed_sec_groups)
199
 
+
200
 
+
201
 
+def allowed_security_group_rules(context, security_group_id,
202
 
+        requested_rules):
203
 
+    """Check quota and return min(requested, allowed) sec group rules."""
204
 
+    project_id = context.project_id
205
 
+    context = context.elevated()
206
 
+    used_rules = db.security_group_rule_count_by_group(context,
207
 
+                                                            security_group_id)
208
 
+    quota = get_project_quotas(context, project_id)
209
 
+    allowed_rules = _get_request_allotment(requested_rules,
210
 
+                                              used_rules,
211
 
+                                              quota['security_group_rules'])
212
 
+    return min(requested_rules, allowed_rules)
213
 
+
214
 
+
215
 
 def _calculate_simple_quota(context, resource, requested):
216
 
     """Check quota for resource; return min(requested, allowed)."""
217
 
     quota = get_project_quotas(context, context.project_id)
218
 
Index: nova-2012.1/nova/tests/api/ec2/test_cloud.py
219
 
===================================================================
220
 
--- nova-2012.1.orig/nova/tests/api/ec2/test_cloud.py   2012-04-04 13:29:56.000000000 -0500
221
 
+++ nova-2012.1/nova/tests/api/ec2/test_cloud.py        2012-05-03 15:39:18.000000000 -0500
222
 
@@ -271,6 +271,18 @@
223
 
         delete = self.cloud.delete_security_group
224
 
         self.assertTrue(delete(self.context, 'testgrp'))
225
 
 
226
 
+    def test_security_group_quota_limit(self):
227
 
+        self.flags(quota_security_groups=10)
228
 
+        for i in range(1, 10):
229
 
+            name = 'test name %i' % i
230
 
+            descript = 'test description %i' % i
231
 
+            create = self.cloud.create_security_group
232
 
+            result = create(self.context, name, descript)
233
 
+
234
 
+        # 11'th group should fail
235
 
+        self.assertRaises(exception.EC2APIError,
236
 
+                          create, self.context, 'foo', 'bar')
237
 
+
238
 
     def test_delete_security_group_by_id(self):
239
 
         sec = db.security_group_create(self.context,
240
 
                                        {'project_id': self.context.project_id,
241
 
@@ -436,6 +448,19 @@
242
 
         self.assertRaises(exception.EC2APIError, authz, self.context,
243
 
                           group_name=sec['name'], **kwargs)
244
 
 
245
 
+    def test_security_group_ingress_quota_limit(self):
246
 
+        self.flags(quota_security_group_rules=20)
247
 
+        kwargs = {'project_id': self.context.project_id, 'name': 'test'}
248
 
+        sec_group = db.security_group_create(self.context, kwargs)
249
 
+        authz = self.cloud.authorize_security_group_ingress
250
 
+        for i in range(100, 120):
251
 
+            kwargs = {'to_port': i, 'from_port': i, 'ip_protocol': 'tcp'}
252
 
+            authz(self.context, group_id=sec_group['id'], **kwargs)
253
 
+
254
 
+        kwargs = {'to_port': 121, 'from_port': 121, 'ip_protocol': 'tcp'}
255
 
+        self.assertRaises(exception.EC2APIError, authz, self.context,
256
 
+                              group_id=sec_group['id'], **kwargs)
257
 
+
258
 
     def _test_authorize_security_group_no_ports_with_source_group(self, proto):
259
 
         kwargs = {'project_id': self.context.project_id, 'name': 'test'}
260
 
         sec = db.security_group_create(self.context, kwargs)
261
 
Index: nova-2012.1/nova/tests/api/openstack/compute/contrib/test_quotas.py
262
 
===================================================================
263
 
--- nova-2012.1.orig/nova/tests/api/openstack/compute/contrib/test_quotas.py    2012-04-04 13:29:56.000000000 -0500
264
 
+++ nova-2012.1/nova/tests/api/openstack/compute/contrib/test_quotas.py 2012-05-03 15:39:18.000000000 -0500
265
 
@@ -28,7 +28,8 @@
266
 
     return {'quota_set': {'id': id, 'metadata_items': 128, 'volumes': 10,
267
 
             'gigabytes': 1000, 'ram': 51200, 'floating_ips': 10,
268
 
             'instances': 10, 'injected_files': 5, 'cores': 20,
269
 
-            'injected_file_content_bytes': 10240}}
270
 
+            'injected_file_content_bytes': 10240,
271
 
+            'security_groups': 10, 'security_group_rules': 20}}
272
 
 
273
 
 
274
 
 def quota_set_list():
275
 
@@ -52,7 +53,10 @@
276
 
             'metadata_items': 128,
277
 
             'gigabytes': 1000,
278
 
             'injected_files': 5,
279
 
-            'injected_file_content_bytes': 10240}
280
 
+            'injected_file_content_bytes': 10240,
281
 
+            'security_groups': 10,
282
 
+            'security_group_rules': 20,
283
 
+            }
284
 
 
285
 
         quota_set = quotas.QuotaSetsController()._format_quota_set('1234',
286
 
                                                             raw_quota_set)
287
 
@@ -68,6 +72,8 @@
288
 
         self.assertEqual(qs['metadata_items'], 128)
289
 
         self.assertEqual(qs['injected_files'], 5)
290
 
         self.assertEqual(qs['injected_file_content_bytes'], 10240)
291
 
+        self.assertEqual(qs['security_groups'], 10)
292
 
+        self.assertEqual(qs['security_group_rules'], 20)
293
 
 
294
 
     def test_quotas_defaults(self):
295
 
         uri = '/v2/fake_tenant/os-quota-sets/fake_tenant/defaults'
296
 
@@ -85,7 +91,10 @@
297
 
                     'floating_ips': 10,
298
 
                     'metadata_items': 128,
299
 
                     'injected_files': 5,
300
 
-                    'injected_file_content_bytes': 10240}}
301
 
+                    'injected_file_content_bytes': 10240,
302
 
+                    'security_groups': 10,
303
 
+                    'security_group_rules': 20,
304
 
+                    }}
305
 
 
306
 
         self.assertEqual(res_dict, expected)
307
 
 
308
 
@@ -106,7 +115,9 @@
309
 
                               'ram': 51200, 'volumes': 10,
310
 
                               'gigabytes': 1000, 'floating_ips': 10,
311
 
                               'metadata_items': 128, 'injected_files': 5,
312
 
-                              'injected_file_content_bytes': 10240}}
313
 
+                              'injected_file_content_bytes': 10240,
314
 
+                              'security_groups': 10,
315
 
+                              'security_group_rules': 20}}
316
 
 
317
 
         req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me',
318
 
                                       use_admin_context=True)
319
 
@@ -119,7 +130,9 @@
320
 
                               'ram': 51200, 'volumes': 10,
321
 
                               'gigabytes': 1000, 'floating_ips': 10,
322
 
                               'metadata_items': 128, 'injected_files': 5,
323
 
-                              'injected_file_content_bytes': 10240}}
324
 
+                              'injected_file_content_bytes': 10240,
325
 
+                              'security_groups': 10,
326
 
+                              'security_group_rules': 20}}
327
 
 
328
 
         req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me')
329
 
         self.assertRaises(webob.exc.HTTPForbidden, self.controller.update,
330
 
@@ -143,6 +156,8 @@
331
 
                 floating_ips=60,
332
 
                 instances=70,
333
 
                 injected_files=80,
334
 
+                security_groups=10,
335
 
+                security_group_rules=20,
336
 
                 cores=90))
337
 
         text = self.serializer.serialize(exemplar)
338
 
 
339
 
@@ -166,6 +181,8 @@
340
 
                 floating_ips='60',
341
 
                 instances='70',
342
 
                 injected_files='80',
343
 
+                security_groups='10',
344
 
+                security_group_rules='20',
345
 
                 cores='90'))
346
 
         intext = ("<?xml version='1.0' encoding='UTF-8'?>\n"
347
 
                   '<quota_set>'
348
 
@@ -178,6 +195,8 @@
349
 
                   '<floating_ips>60</floating_ips>'
350
 
                   '<instances>70</instances>'
351
 
                   '<injected_files>80</injected_files>'
352
 
+                  '<security_groups>10</security_groups>'
353
 
+                  '<security_group_rules>20</security_group_rules>'
354
 
                   '<cores>90</cores>'
355
 
                   '</quota_set>')
356
 
 
357
 
Index: nova-2012.1/nova/tests/api/openstack/compute/contrib/test_security_groups.py
358
 
===================================================================
359
 
--- nova-2012.1.orig/nova/tests/api/openstack/compute/contrib/test_security_groups.py   2012-04-04 13:29:54.000000000 -0500
360
 
+++ nova-2012.1/nova/tests/api/openstack/compute/contrib/test_security_groups.py        2012-05-03 15:39:18.000000000 -0500
361
 
@@ -25,12 +25,15 @@
362
 
 from nova.api.openstack import wsgi
363
 
 import nova.db
364
 
 from nova import exception
365
 
+from nova import flags
366
 
 from nova import test
367
 
 from nova.tests.api.openstack import fakes
368
 
 
369
 
 
370
 
 FAKE_UUID = 'a47ae74e-ab08-447f-8eee-ffd43fc46c16'
371
 
 
372
 
+FLAGS = flags.FLAGS
373
 
+
374
 
 
375
 
 class AttrDict(dict):
376
 
     def __getattr__(self, k):
377
 
@@ -219,6 +222,18 @@
378
 
         self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
379
 
                           req, {'security_group': sg})
380
 
 
381
 
+    def test_create_security_group_quota_limit(self):
382
 
+        req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups')
383
 
+        for num in range(1, FLAGS.quota_security_groups):
384
 
+            name = 'test%s' % num
385
 
+            sg = security_group_template(name=name)
386
 
+            res_dict = self.controller.create(req, {'security_group': sg})
387
 
+            self.assertEqual(res_dict['security_group']['name'], name)
388
 
+
389
 
+        sg = security_group_template()
390
 
+        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
391
 
+                          req, {'security_group': sg})
392
 
+
393
 
     def test_get_security_group_list(self):
394
 
         groups = []
395
 
         for i, name in enumerate(['default', 'test']):
396
 
@@ -894,6 +909,22 @@
397
 
         self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
398
 
                           req, '22222222222222')
399
 
 
400
 
+    def test_create_rule_quota_limit(self):
401
 
+        req = fakes.HTTPRequest.blank('/v2/fake/os-security-group-rules')
402
 
+        for num in range(100, 100 + FLAGS.quota_security_group_rules):
403
 
+            rule = {
404
 
+                'ip_protocol': 'tcp', 'from_port': num,
405
 
+                'to_port': num, 'parent_group_id': '2', 'group_id': '1'
406
 
+            }
407
 
+            self.controller.create(req, {'security_group_rule': rule})
408
 
+
409
 
+        rule = {
410
 
+            'ip_protocol': 'tcp', 'from_port': '121', 'to_port': '121',
411
 
+            'parent_group_id': '2', 'group_id': '1'
412
 
+        }
413
 
+        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
414
 
+                          req, {'security_group_rule': rule})
415
 
+
416
 
 
417
 
 class TestSecurityGroupRulesXMLDeserializer(unittest.TestCase):
418
 
 
419
 
Index: nova-2012.1/nova/tests/test_quota.py
420
 
===================================================================
421
 
--- nova-2012.1.orig/nova/tests/test_quota.py   2012-04-04 13:29:56.000000000 -0500
422
 
+++ nova-2012.1/nova/tests/test_quota.py        2012-05-03 15:39:18.000000000 -0500
423
 
@@ -235,6 +235,34 @@
424
 
         floating_ips = quota.allowed_floating_ips(self.context, 101)
425
 
         self.assertEqual(floating_ips, 101)
426
 
 
427
 
+    def test_unlimited_security_groups(self):
428
 
+        self.flags(quota_security_groups=10)
429
 
+        security_groups = quota.allowed_security_groups(self.context, 100)
430
 
+        self.assertEqual(security_groups, 10)
431
 
+        db.quota_create(self.context, self.project_id, 'security_groups', None)
432
 
+        security_groups = quota.allowed_security_groups(self.context, 100)
433
 
+        self.assertEqual(security_groups, 100)
434
 
+        security_groups = quota.allowed_security_groups(self.context, 101)
435
 
+        self.assertEqual(security_groups, 101)
436
 
+
437
 
+    def test_unlimited_security_group_rules(self):
438
 
+
439
 
+        def fake_security_group_rule_count_by_group(context, sec_group_id):
440
 
+            return 0
441
 
+
442
 
+        self.stubs.Set(db, 'security_group_rule_count_by_group',
443
 
+                       fake_security_group_rule_count_by_group)
444
 
+
445
 
+        self.flags(quota_security_group_rules=20)
446
 
+        rules = quota.allowed_security_group_rules(self.context, 1234, 100)
447
 
+        self.assertEqual(rules, 20)
448
 
+        db.quota_create(self.context, self.project_id, 'security_group_rules',
449
 
+                        None)
450
 
+        rules = quota.allowed_security_group_rules(self.context, 1234, 100)
451
 
+        self.assertEqual(rules, 100)
452
 
+        rules = quota.allowed_security_group_rules(self.context, 1234, 101)
453
 
+        self.assertEqual(rules, 101)
454
 
+
455
 
     def test_unlimited_metadata_items(self):
456
 
         self.flags(quota_metadata_items=10)
457
 
         items = quota.allowed_metadata_items(self.context, 100)