summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Thode <prometheanfire@gentoo.org>2013-11-17 22:35:55 +0000
committerMatthew Thode <prometheanfire@gentoo.org>2013-11-17 22:35:55 +0000
commit25da27f45cea05d184289cf15b61305607315cd8 (patch)
tree693590f93f05b82b7edec940e5e8e7c70365ad2b /sys-cluster
parentVersion bump. (diff)
downloadgentoo-2-25da27f45cea05d184289cf15b61305607315cd8.tar.gz
gentoo-2-25da27f45cea05d184289cf15b61305607315cd8.tar.bz2
gentoo-2-25da27f45cea05d184289cf15b61305607315cd8.zip
YAY CVE's
(Portage version: 2.2.7/cvs/Linux x86_64, signed Manifest commit with key 0x2471eb3e40ac5ac3)
Diffstat (limited to 'sys-cluster')
-rw-r--r--sys-cluster/nova/ChangeLog19
-rw-r--r--sys-cluster/nova/files/2012.2.4-CVE-2013-2256.patch327
-rw-r--r--sys-cluster/nova/files/2012.2.4-CVE-2013-4185.patch101
-rw-r--r--sys-cluster/nova/files/2012.2.4-CVE-2013-4261.patch114
-rw-r--r--sys-cluster/nova/files/2012.2.4-CVE-2013-4278.patch95
-rw-r--r--sys-cluster/nova/files/2013.1.3-CVE-2013-4261.patch79
-rw-r--r--sys-cluster/nova/files/2013.1.3-CVE-2013-4278.patch87
-rw-r--r--sys-cluster/nova/files/CVE-2013-4463_4469-grizzly.patch432
-rw-r--r--sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch452
-rw-r--r--sys-cluster/nova/files/CVE-2013-4497-grizzly-1.patch111
-rw-r--r--sys-cluster/nova/files/CVE-2013-4497-grizzly-2.patch51
-rw-r--r--sys-cluster/nova/files/nova-folsom-4-CVE-2013-2030.patch36
-rw-r--r--sys-cluster/nova/files/nova-folsom-4-CVE-2013-2096.patch115
-rw-r--r--sys-cluster/nova/files/nova-grizzly-1-CVE-2013-2096.patch96
-rw-r--r--sys-cluster/nova/nova-2013.1.4-r1.ebuild (renamed from sys-cluster/nova/nova-2013.1.4.ebuild)5
-rw-r--r--sys-cluster/nova/nova-2013.2-r2.ebuild (renamed from sys-cluster/nova/nova-2013.2-r1.ebuild)3
16 files changed, 1070 insertions, 1053 deletions
diff --git a/sys-cluster/nova/ChangeLog b/sys-cluster/nova/ChangeLog
index 039d4e187043..0b5b6993a469 100644
--- a/sys-cluster/nova/ChangeLog
+++ b/sys-cluster/nova/ChangeLog
@@ -1,6 +1,23 @@
# ChangeLog for sys-cluster/nova
# Copyright 1999-2013 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.38 2013/11/14 06:54:23 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.39 2013/11/17 22:35:55 prometheanfire Exp $
+
+*nova-2013.2-r2 (17 Nov 2013)
+*nova-2013.1.4-r1 (17 Nov 2013)
+
+ 17 Nov 2013; Matthew Thode <prometheanfire@gentoo.org>
+ +files/CVE-2013-4463_4469-grizzly.patch,
+ +files/CVE-2013-4463_4469-havana.patch, +files/CVE-2013-4497-1.patch,
+ +files/CVE-2013-4497-2.patch, +files/CVE-2013-4497-grizzly-1.patch,
+ +files/CVE-2013-4497-grizzly-2.patch, +nova-2013.1.4-r1.ebuild,
+ +nova-2013.2-r2.ebuild, -files/2012.2.4-CVE-2013-2256.patch,
+ -files/2012.2.4-CVE-2013-4185.patch, -files/2012.2.4-CVE-2013-4261.patch,
+ -files/2012.2.4-CVE-2013-4278.patch, -files/2013.1.3-CVE-2013-4261.patch,
+ -files/2013.1.3-CVE-2013-4278.patch, -files/nova-folsom-4-CVE-2013-2030.patch,
+ -files/nova-folsom-4-CVE-2013-2096.patch,
+ -files/nova-grizzly-1-CVE-2013-2096.patch, -nova-2013.1.4.ebuild,
+ -nova-2013.2-r1.ebuild:
+ YAY CVE's
14 Nov 2013; Matthew Thode <prometheanfire@gentoo.org> nova-2013.1.4.ebuild,
nova-2013.1.9999.ebuild, nova-2013.2-r1.ebuild, nova-2013.2.9999.ebuild,
diff --git a/sys-cluster/nova/files/2012.2.4-CVE-2013-2256.patch b/sys-cluster/nova/files/2012.2.4-CVE-2013-2256.patch
deleted file mode 100644
index 7b2f90663a8c..000000000000
--- a/sys-cluster/nova/files/2012.2.4-CVE-2013-2256.patch
+++ /dev/null
@@ -1,327 +0,0 @@
-From f7aaf1fa04331522aee2158e372940df92f45cb0 Mon Sep 17 00:00:00 2001
-From: Russell Bryant <rbryant@redhat.com>
-Date: Thu, 27 Jun 2013 21:00:05 +0000
-Subject: [PATCH] Make flavors is_public option actually work
-
-When you create a flavor, you can set an is_public flag to be True or
-False. It is True by default. When False, the intention is that the
-flavor is only accessible by an admin, unless you use the flavor_access
-API extension to grant access to specific tenants.
-
-Unfortunately, the only place in the code where this was being enforced
-was when listing flavors through the API. It would filter out the
-non-public ones for a non-admin. Otherwise, the flavor was accessible.
-You could get the details, and you could boot an instance with it, if
-you figured out a valid flavor ID.
-
-This patch adds enforcement down in the db layer. It also fixes one
-place in the API where the context wasn't passed down to enable the
-enforcement to happen.
-
-Fix bug 1194093.
-
-master -> grizzly
-(cherry picked from commit b65d506a5f9d9b2b20777a9aceb44a8ffed6a5de)
-
-Conflicts:
- nova/api/openstack/compute/contrib/flavor_access.py
- nova/api/openstack/compute/contrib/flavormanage.py
- nova/api/openstack/compute/flavors.py
- nova/compute/api.py
- nova/db/sqlalchemy/api.py
- nova/tests/api/openstack/compute/contrib/test_flavor_access.py
- nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py
- nova/tests/api/openstack/compute/contrib/test_flavor_manage.py
- nova/tests/api/openstack/compute/contrib/test_flavor_rxtx.py
- nova/tests/api/openstack/compute/contrib/test_flavor_swap.py
- nova/tests/api/openstack/compute/contrib/test_flavorextradata.py
- nova/tests/api/openstack/compute/test_flavors.py
- nova/tests/db/test_db_api.py
-
-grizzly -> folsom
-(cherry picked from commit 6df1b7a2a1413a98bffc8b8e0b947f3c90e3bbf5)
-
-Conflicts:
- nova/db/sqlalchemy/api.py
- nova/tests/api/openstack/compute/test_flavors.py
-
-Change-Id: I5b37fa0bb19683fe1642fd81222547d4a317054e
----
- .../api/openstack/compute/contrib/flavor_access.py | 3 ++-
- nova/api/openstack/compute/contrib/flavormanage.py | 2 +-
- nova/api/openstack/compute/flavors.py | 4 +++-
- nova/compute/api.py | 2 +-
- nova/compute/instance_types.py | 2 +-
- nova/db/api.py | 4 ++--
- nova/db/sqlalchemy/api.py | 26 +++++++++++++++-------
- .../compute/contrib/test_flavor_access.py | 2 +-
- .../compute/contrib/test_flavor_disabled.py | 2 +-
- .../compute/contrib/test_flavor_manage.py | 3 ++-
- .../openstack/compute/contrib/test_flavor_rxtx.py | 2 +-
- .../openstack/compute/contrib/test_flavor_swap.py | 2 +-
- .../compute/contrib/test_flavorextradata.py | 2 +-
- nova/tests/api/openstack/compute/test_flavors.py | 4 ++--
- 14 files changed, 37 insertions(+), 23 deletions(-)
-
-diff --git a/nova/api/openstack/compute/contrib/flavor_access.py b/nova/api/openstack/compute/contrib/flavor_access.py
-index 9991408..26cd77f 100644
---- a/nova/api/openstack/compute/contrib/flavor_access.py
-+++ b/nova/api/openstack/compute/contrib/flavor_access.py
-@@ -99,7 +99,8 @@ class FlavorAccessController(object):
- authorize(context)
-
- try:
-- flavor = instance_types.get_instance_type_by_flavor_id(flavor_id)
-+ flavor = instance_types.get_instance_type_by_flavor_id(flavor_id,
-+ ctxt=context)
- except exception.FlavorNotFound:
- explanation = _("Flavor not found.")
- raise webob.exc.HTTPNotFound(explanation=explanation)
-diff --git a/nova/api/openstack/compute/contrib/flavormanage.py b/nova/api/openstack/compute/contrib/flavormanage.py
-index e7731cc..79551b1 100644
---- a/nova/api/openstack/compute/contrib/flavormanage.py
-+++ b/nova/api/openstack/compute/contrib/flavormanage.py
-@@ -43,7 +43,7 @@ class FlavorManageController(wsgi.Controller):
-
- try:
- flavor = instance_types.get_instance_type_by_flavor_id(
-- id, read_deleted="no")
-+ id, ctxt=context, read_deleted="no")
- except exception.NotFound, e:
- raise webob.exc.HTTPNotFound(explanation=e.format_message())
-
-diff --git a/nova/api/openstack/compute/flavors.py b/nova/api/openstack/compute/flavors.py
-index 8aa57a2..d51b48a 100644
---- a/nova/api/openstack/compute/flavors.py
-+++ b/nova/api/openstack/compute/flavors.py
-@@ -84,7 +84,9 @@ class Controller(wsgi.Controller):
- def show(self, req, id):
- """Return data about the given flavor id."""
- try:
-- flavor = instance_types.get_instance_type_by_flavor_id(id)
-+ context = req.environ['nova.context']
-+ flavor = instance_types.get_instance_type_by_flavor_id(id,
-+ ctxt=context)
- req.cache_db_flavor(flavor)
- except exception.NotFound:
- raise webob.exc.HTTPNotFound()
-diff --git a/nova/compute/api.py b/nova/compute/api.py
-index 5319d04..ca78830 100644
---- a/nova/compute/api.py
-+++ b/nova/compute/api.py
-@@ -1080,7 +1080,7 @@ class API(base.Base):
- #NOTE(bcwaldon): this doesn't really belong in this class
- def get_instance_type(self, context, instance_type_id):
- """Get an instance type by instance type id."""
-- return instance_types.get_instance_type(instance_type_id)
-+ return instance_types.get_instance_type(instance_type_id, ctxt=context)
-
- def get(self, context, instance_id):
- """Get a single instance with the given instance_id."""
-diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py
-index 6869672..5be97c1 100644
---- a/nova/compute/instance_types.py
-+++ b/nova/compute/instance_types.py
-@@ -163,7 +163,7 @@ def get_instance_type_by_flavor_id(flavorid, ctxt=None, read_deleted="yes"):
- if ctxt is None:
- ctxt = context.get_admin_context(read_deleted=read_deleted)
-
-- return db.instance_type_get_by_flavor_id(ctxt, flavorid)
-+ return db.instance_type_get_by_flavor_id(ctxt, flavorid, read_deleted)
-
-
- def get_instance_type_access_by_flavor_id(flavorid, ctxt=None):
-diff --git a/nova/db/api.py b/nova/db/api.py
-index 9f2ff73..40db686 100644
---- a/nova/db/api.py
-+++ b/nova/db/api.py
-@@ -1460,9 +1460,9 @@ def instance_type_get_by_name(context, name):
- return IMPL.instance_type_get_by_name(context, name)
-
-
--def instance_type_get_by_flavor_id(context, id):
-+def instance_type_get_by_flavor_id(context, id, read_deleted=None):
- """Get instance type by flavor id."""
-- return IMPL.instance_type_get_by_flavor_id(context, id)
-+ return IMPL.instance_type_get_by_flavor_id(context, id, read_deleted)
-
-
- def instance_type_destroy(context, name):
-diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
-index 7fcc4f8..ea32168 100644
---- a/nova/db/sqlalchemy/api.py
-+++ b/nova/db/sqlalchemy/api.py
-@@ -3910,7 +3910,7 @@ def instance_type_create(context, values):
- pass
- try:
- instance_type_get_by_flavor_id(context, values['flavorid'],
-- session)
-+ read_deleted='no', session=session)
- raise exception.InstanceTypeExists(name=values['name'])
- except exception.FlavorNotFound:
- pass
-@@ -3952,9 +3952,16 @@ def _dict_with_extra_specs(inst_type_query):
-
-
- def _instance_type_get_query(context, session=None, read_deleted=None):
-- return model_query(context, models.InstanceTypes, session=session,
-+ query = model_query(context, models.InstanceTypes, session=session,
- read_deleted=read_deleted).\
-- options(joinedload('extra_specs'))
-+ options(joinedload('extra_specs'))
-+ if not context.is_admin:
-+ the_filter = [models.InstanceTypes.is_public == True]
-+ the_filter.extend([
-+ models.InstanceTypes.projects.any(project_id=context.project_id)
-+ ])
-+ query = query.filter(or_(*the_filter))
-+ return query
-
-
- @require_context
-@@ -4029,9 +4036,11 @@ def instance_type_get_by_name(context, name, session=None):
-
-
- @require_context
--def instance_type_get_by_flavor_id(context, flavor_id, session=None):
-+def instance_type_get_by_flavor_id(context, flavor_id, read_deleted,
-+ session=None):
- """Returns a dict describing specific flavor_id"""
-- result = _instance_type_get_query(context, session=session).\
-+ result = _instance_type_get_query(context, read_deleted=read_deleted,
-+ session=session).\
- filter_by(flavorid=flavor_id).\
- first()
-
-@@ -4083,7 +4092,7 @@ def instance_type_access_add(context, flavor_id, project_id):
- session = get_session()
- with session.begin():
- instance_type_ref = instance_type_get_by_flavor_id(context, flavor_id,
-- session=session)
-+ read_deleted='no', session=session)
- instance_type_id = instance_type_ref['id']
- access_ref = _instance_type_access_query(context, session=session).\
- filter_by(instance_type_id=instance_type_id).\
-@@ -4111,7 +4120,7 @@ def instance_type_access_remove(context, flavor_id, project_id):
- session = get_session()
- with session.begin():
- instance_type_ref = instance_type_get_by_flavor_id(context, flavor_id,
-- session=session)
-+ read_deleted='no', session=session)
- instance_type_id = instance_type_ref['id']
- access_ref = _instance_type_access_query(context, session=session).\
- filter_by(instance_type_id=instance_type_id).\
-@@ -4447,7 +4456,8 @@ def instance_type_extra_specs_update_or_create(context, flavor_id,
- specs):
- session = get_session()
- spec_ref = None
-- instance_type = instance_type_get_by_flavor_id(context, flavor_id)
-+ instance_type = instance_type_get_by_flavor_id(context, flavor_id,
-+ read_deleted='no')
- for key, value in specs.iteritems():
- try:
- spec_ref = instance_type_extra_specs_get_item(
-diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_access.py b/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
-index 0bf1f1b..075810b 100644
---- a/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
-+++ b/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
-@@ -68,7 +68,7 @@ def fake_get_instance_type_access_by_flavor_id(flavorid):
- return res
-
-
--def fake_get_instance_type_by_flavor_id(flavorid):
-+def fake_get_instance_type_by_flavor_id(flavorid, ctxt=None):
- return INSTANCE_TYPES[flavorid]
-
-
-diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py b/nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py
-index 1225b56..933178a 100644
---- a/nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py
-+++ b/nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py
-@@ -44,7 +44,7 @@ FAKE_FLAVORS = {
- }
-
-
--def fake_instance_type_get_by_flavor_id(flavorid):
-+def fake_instance_type_get_by_flavor_id(flavorid, ctxt=None):
- return FAKE_FLAVORS['flavor %s' % flavorid]
-
-
-diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py b/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py
-index 70fd5e4..7174ed2 100644
---- a/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py
-+++ b/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py
-@@ -25,7 +25,8 @@ from nova import test
- from nova.tests.api.openstack import fakes
-
-
--def fake_get_instance_type_by_flavor_id(flavorid, read_deleted='yes'):
-+def fake_get_instance_type_by_flavor_id(flavorid, ctxt=None,
-+ read_deleted='yes'):
- if flavorid == 'failtest':
- raise exception.NotFound("Not found sucka!")
- elif not str(flavorid) == '1234':
-diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_rxtx.py b/nova/tests/api/openstack/compute/contrib/test_flavor_rxtx.py
-index 52163c7..afa2259 100644
---- a/nova/tests/api/openstack/compute/contrib/test_flavor_rxtx.py
-+++ b/nova/tests/api/openstack/compute/contrib/test_flavor_rxtx.py
-@@ -43,7 +43,7 @@ FAKE_FLAVORS = {
- }
-
-
--def fake_instance_type_get_by_flavor_id(flavorid):
-+def fake_instance_type_get_by_flavor_id(flavorid, ctxt=None):
- return FAKE_FLAVORS['flavor %s' % flavorid]
-
-
-diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_swap.py b/nova/tests/api/openstack/compute/contrib/test_flavor_swap.py
-index 75e9cd7..3fd1ae9 100644
---- a/nova/tests/api/openstack/compute/contrib/test_flavor_swap.py
-+++ b/nova/tests/api/openstack/compute/contrib/test_flavor_swap.py
-@@ -43,7 +43,7 @@ FAKE_FLAVORS = {
- }
-
-
--def fake_instance_type_get_by_flavor_id(flavorid):
-+def fake_instance_type_get_by_flavor_id(flavorid, ctxt=None):
- return FAKE_FLAVORS['flavor %s' % flavorid]
-
-
-diff --git a/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py b/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py
-index 8f5301a..9654605 100644
---- a/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py
-+++ b/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py
-@@ -23,7 +23,7 @@ from nova import test
- from nova.tests.api.openstack import fakes
-
-
--def fake_get_instance_type_by_flavor_id(flavorid):
-+def fake_get_instance_type_by_flavor_id(flavorid, ctxt=None):
- return {
- 'id': flavorid,
- 'flavorid': str(flavorid),
-diff --git a/nova/tests/api/openstack/compute/test_flavors.py b/nova/tests/api/openstack/compute/test_flavors.py
-index 77d40df..cfa3429 100644
---- a/nova/tests/api/openstack/compute/test_flavors.py
-+++ b/nova/tests/api/openstack/compute/test_flavors.py
-@@ -54,7 +54,7 @@ FAKE_FLAVORS = {
- }
-
-
--def fake_instance_type_get_by_flavor_id(flavorid):
-+def fake_instance_type_get_by_flavor_id(flavorid, ctxt=None):
- return FAKE_FLAVORS['flavor %s' % flavorid]
-
-
-@@ -80,7 +80,7 @@ def empty_instance_type_get_all(inactive=False, filters=None):
- return {}
-
-
--def return_instance_type_not_found(flavor_id):
-+def return_instance_type_not_found(flavor_id, ctxt=None):
- raise exception.InstanceTypeNotFound(flavor_id=flavor_id)
-
-
---
-1.8.1.5
-
diff --git a/sys-cluster/nova/files/2012.2.4-CVE-2013-4185.patch b/sys-cluster/nova/files/2012.2.4-CVE-2013-4185.patch
deleted file mode 100644
index 3e02ae10a473..000000000000
--- a/sys-cluster/nova/files/2012.2.4-CVE-2013-4185.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From d4ee081c5c0a5132781235177c430ebcf72b0b0b Mon Sep 17 00:00:00 2001
-From: Vishvananda Ishaya <vishvananda@gmail.com>
-Date: Fri, 19 Jul 2013 10:23:59 -0700
-Subject: [PATCH] Use cached nwinfo for secgroup rules
-
-This stops a potential DOS with source security groups by using the
-db cached version of the network info instead of calling out to
-the network api multiple times.
-
-Fixes bug 1184041
-
-Change-Id: Id5f24ecf0e8cce60c27a9aecbc6e606c4c44d6b6
-(cherry picked from commit 85aac04704350566d6b06aa7a3b99649946c672c)
----
- nova/db/sqlalchemy/api.py | 2 ++
- nova/tests/test_libvirt.py | 4 +++-
- nova/tests/test_xenapi.py | 5 +++--
- nova/virt/firewall.py | 12 +++---------
- 4 files changed, 11 insertions(+), 12 deletions(-)
-
-diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
-index 7fcc4f8..6d3b139 100644
---- a/nova/db/sqlalchemy/api.py
-+++ b/nova/db/sqlalchemy/api.py
-@@ -3649,6 +3649,8 @@ def security_group_rule_get_by_security_group(context, security_group_id,
- return _security_group_rule_get_query(context, session=session).\
- filter_by(parent_group_id=security_group_id).\
- options(joinedload_all('grantee_group.instances.instance_type')).\
-+ options(joinedload('grantee_group.instances.'
-+ 'info_cache')).\
- all()
-
-
-diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
-index b26a006..e956eb0 100644
---- a/nova/tests/test_libvirt.py
-+++ b/nova/tests/test_libvirt.py
-@@ -3240,7 +3240,9 @@ class IptablesFirewallTestCase(test.TestCase):
- from nova.network import linux_net
- linux_net.iptables_manager.execute = fake_iptables_execute
-
-- _fake_stub_out_get_nw_info(self.stubs, lambda *a, **kw: network_model)
-+ from nova.compute import utils as compute_utils
-+ self.stubs.Set(compute_utils, 'get_nw_info_for_instance',
-+ lambda instance: network_model)
-
- network_info = network_model.legacy()
- self.fw.prepare_instance_filter(instance_ref, network_info)
-diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
-index 0cf69d6..7a8f9b4 100644
---- a/nova/tests/test_xenapi.py
-+++ b/nova/tests/test_xenapi.py
-@@ -1690,8 +1690,9 @@ class XenAPIDom0IptablesFirewallTestCase(stubs.XenAPITestBase):
- network_model = fake_network.fake_get_instance_nw_info(self.stubs,
- 1, spectacular=True)
-
-- fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs,
-- lambda *a, **kw: network_model)
-+ from nova.compute import utils as compute_utils
-+ self.stubs.Set(compute_utils, 'get_nw_info_for_instance',
-+ lambda instance: network_model)
-
- network_info = network_model.legacy()
- self.fw.prepare_instance_filter(instance_ref, network_info)
-diff --git a/nova/virt/firewall.py b/nova/virt/firewall.py
-index a093a35..7c22c86 100644
---- a/nova/virt/firewall.py
-+++ b/nova/virt/firewall.py
-@@ -17,10 +17,10 @@
- # License for the specific language governing permissions and limitations
- # under the License.
-
-+from nova.compute import utils as compute_utils
- from nova import context
- from nova import db
- from nova import flags
--from nova import network
- from nova.network import linux_net
- from nova.openstack.common import cfg
- from nova.openstack.common import importutils
-@@ -405,15 +405,9 @@ class IptablesFirewallDriver(FirewallDriver):
- fw_rules += [' '.join(args)]
- else:
- if rule['grantee_group']:
-- # FIXME(jkoelker) This needs to be ported up into
-- # the compute manager which already
-- # has access to a nw_api handle,
-- # and should be the only one making
-- # making rpc calls.
-- nw_api = network.API()
- for instance in rule['grantee_group']['instances']:
-- nw_info = nw_api.get_instance_nw_info(ctxt,
-- instance)
-+ nw_info = compute_utils.get_nw_info_for_instance(
-+ instance)
-
- ips = [ip['address']
- for ip in nw_info.fixed_ips()
---
-1.8.1.5
-
diff --git a/sys-cluster/nova/files/2012.2.4-CVE-2013-4261.patch b/sys-cluster/nova/files/2012.2.4-CVE-2013-4261.patch
deleted file mode 100644
index eacc6286fb98..000000000000
--- a/sys-cluster/nova/files/2012.2.4-CVE-2013-4261.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From ef5730a4620b409a3b46e46966e3bc6f3a306464 Mon Sep 17 00:00:00 2001
-From: Ben Nemec <bnemec@us.ibm.com>
-Date: Thu, 9 May 2013 19:06:45 +0000
-Subject: [PATCH] Fix problem with long messages in Qpid (from oslo)
-
-This is commit 478ac3a3e in oslo-incubator
-
-Qpid has a limitation where it cannot serialize a dict containing a
-string greater than 65535 characters. This change alters the Qpid
-implementation to JSON encode the dict before sending it, but only if
-Qpid would fail to serialize it. This maintains as much backward
-compatibility as possible, though long messages will still fail if they
-are sent to an older receiver.
-
-Even though this change will modify the message format, it will only do
-it when messages are longer than 65K which would be broken anyway and
-could cause serious bugs like the one linked below.
-
-Fixes bug 1215091
-
-Change-Id: I2f0e88435748bab631d969573d3a598d9e1f7fef
----
- nova/openstack/common/rpc/impl_qpid.py | 47 ++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
-diff --git a/nova/openstack/common/rpc/impl_qpid.py b/nova/openstack/common/rpc/impl_qpid.py
-index e579316..67388fd 100644
---- a/nova/openstack/common/rpc/impl_qpid.py
-+++ b/nova/openstack/common/rpc/impl_qpid.py
-@@ -23,6 +23,7 @@ import uuid
-
- import eventlet
- import greenlet
-+import qpid.codec010 as qpid_codec
- import qpid.messaging
- import qpid.messaging.exceptions
-
-@@ -63,6 +64,8 @@ qpid_opts = [
-
- cfg.CONF.register_opts(qpid_opts)
-
-+JSON_CONTENT_TYPE = 'application/json; charset=utf8'
-+
-
- class ConsumerBase(object):
- """Consumer base class."""
-@@ -117,10 +120,27 @@ class ConsumerBase(object):
- self.receiver = session.receiver(self.address)
- self.receiver.capacity = 1
-
-+ def _unpack_json_msg(self, msg):
-+ """Load the JSON data in msg if msg.content_type indicates that it
-+ is necessary. Put the loaded data back into msg.content and
-+ update msg.content_type appropriately.
-+
-+ A Qpid Message containing a dict will have a content_type of
-+ 'amqp/map', whereas one containing a string that needs to be converted
-+ back from JSON will have a content_type of JSON_CONTENT_TYPE.
-+
-+ :param msg: a Qpid Message object
-+ :returns: None
-+ """
-+ if msg.content_type == JSON_CONTENT_TYPE:
-+ msg.content = jsonutils.loads(msg.content)
-+ msg.content_type = 'amqp/map'
-+
- def consume(self):
- """Fetch the message and pass it to the callback object"""
- message = self.receiver.fetch()
- try:
-+ self._unpack_json_msg(message)
- self.callback(message.content)
- except Exception:
- LOG.exception(_("Failed to process message... skipping it."))
-@@ -220,8 +240,35 @@ class Publisher(object):
- """Re-establish the Sender after a reconnection"""
- self.sender = session.sender(self.address)
-
-+ def _pack_json_msg(self, msg):
-+ """Qpid cannot serialize dicts containing strings longer than 65535
-+ characters. This function dumps the message content to a JSON
-+ string, which Qpid is able to handle.
-+
-+ :param msg: May be either a Qpid Message object or a bare dict.
-+ :returns: A Qpid Message with its content field JSON encoded.
-+ """
-+ try:
-+ msg.content = jsonutils.dumps(msg.content)
-+ except AttributeError:
-+ # Need to have a Qpid message so we can set the content_type.
-+ msg = qpid.messaging.Message(jsonutils.dumps(msg))
-+ msg.content_type = JSON_CONTENT_TYPE
-+ return msg
-+
- def send(self, msg):
- """Send a message"""
-+ try:
-+ # Check if Qpid can encode the message
-+ check_msg = msg
-+ if not hasattr(check_msg, 'content_type'):
-+ check_msg = qpid.messaging.Message(msg)
-+ content_type = check_msg.content_type
-+ enc, dec = qpid.messaging.message.get_codec(content_type)
-+ enc(check_msg.content)
-+ except qpid_codec.CodecException:
-+ # This means the message couldn't be serialized as a dict.
-+ msg = self._pack_json_msg(msg)
- self.sender.send(msg)
-
-
---
-1.8.1.2
-
-
diff --git a/sys-cluster/nova/files/2012.2.4-CVE-2013-4278.patch b/sys-cluster/nova/files/2012.2.4-CVE-2013-4278.patch
deleted file mode 100644
index a0b9b4119741..000000000000
--- a/sys-cluster/nova/files/2012.2.4-CVE-2013-4278.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 6825959560e06725d26625fd21f5c0b78b305492 Mon Sep 17 00:00:00 2001
-From: Russell Bryant <rbryant@redhat.com>
-Date: Tue, 20 Aug 2013 11:06:12 -0400
-Subject: [PATCH] Enforce flavor access during instance boot
-
-The code in the servers API did not pass the context when retrieving
-flavor details. That means it would use an admin context instead,
-bypassing all flavor access control checks.
-
-This patch includes the fix, and the corresponding unit test for the v2
-API.
-
-Closes-bug: #1212179
-
-(cherry picked from commit 4054cc4a22a1fea997dec76afb5646fd6c6ea6b9)
-
-Conflicts:
- nova/api/openstack/compute/plugins/v3/servers.py
- nova/api/openstack/compute/servers.py
- nova/tests/api/openstack/compute/plugins/v3/test_servers.py
- nova/tests/api/openstack/compute/test_servers.py
-
-Change-Id: I681ae9965e19767df22fa74c3315e4e03a459d3b
----
- nova/api/openstack/compute/servers.py | 3 ++-
- nova/tests/api/openstack/compute/test_servers.py | 23 +++++++++++++++++++++--
- 2 files changed, 23 insertions(+), 3 deletions(-)
-
-diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py
-index 6908262..ab06595 100644
---- a/nova/api/openstack/compute/servers.py
-+++ b/nova/api/openstack/compute/servers.py
-@@ -844,7 +844,8 @@ class Controller(wsgi.Controller):
-
- try:
- _get_inst_type = instance_types.get_instance_type_by_flavor_id
-- inst_type = _get_inst_type(flavor_id, read_deleted="no")
-+ inst_type = _get_inst_type(flavor_id, ctxt=context,
-+ read_deleted="no")
-
- (instances, resv_id) = self.compute_api.create(context,
- inst_type,
-diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py
-index cd88a2a..5cb26bd 100644
---- a/nova/tests/api/openstack/compute/test_servers.py
-+++ b/nova/tests/api/openstack/compute/test_servers.py
-@@ -34,6 +34,7 @@ import nova.compute.api
- from nova.compute import instance_types
- from nova.compute import task_states
- from nova.compute import vm_states
-+import nova.context
- import nova.db
- from nova.db.sqlalchemy import models
- from nova import flags
-@@ -1703,10 +1704,10 @@ class ServersControllerCreateTest(test.TestCase):
- """
- self.assertTrue("adminPass" not in server_dict)
-
-- def _test_create_instance(self):
-+ def _test_create_instance(self, flavor=2):
- image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
- body = dict(server=dict(
-- name='server_test', imageRef=image_uuid, flavorRef=2,
-+ name='server_test', imageRef=image_uuid, flavorRef=flavor,
- metadata={'hello': 'world', 'open': 'stack'},
- personality={}))
- req = fakes.HTTPRequest.blank('/v2/fake/servers')
-@@ -1718,6 +1719,24 @@ class ServersControllerCreateTest(test.TestCase):
- self._check_admin_pass_len(server)
- self.assertEqual(FAKE_UUID, server['id'])
-
-+ def test_create_instance_private_flavor(self):
-+ values = {
-+ 'name': 'fake_name',
-+ 'memory_mb': 512,
-+ 'vcpus': 1,
-+ 'root_gb': 10,
-+ 'ephemeral_gb': 10,
-+ 'flavorid': '1324',
-+ 'swap': 0,
-+ 'rxtx_factor': 0.5,
-+ 'vcpu_weight': 1,
-+ 'disabled': False,
-+ 'is_public': False,
-+ }
-+ nova.db.instance_type_create(nova.context.get_admin_context(), values)
-+ self.assertRaises(webob.exc.HTTPBadRequest, self._test_create_instance,
-+ flavor=1324)
-+
- def test_create_server_bad_image_href(self):
- image_href = 1
- flavor_ref = 'http://localhost/123/flavors/3'
---
-1.8.1.5
-
diff --git a/sys-cluster/nova/files/2013.1.3-CVE-2013-4261.patch b/sys-cluster/nova/files/2013.1.3-CVE-2013-4261.patch
deleted file mode 100644
index ce266d4dd453..000000000000
--- a/sys-cluster/nova/files/2013.1.3-CVE-2013-4261.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 2d949c415b97ed9649e78c880ab149d0d39c1152 Mon Sep 17 00:00:00 2001
-From: Xavier Queralt <xqueralt@redhat.com>
-Date: Thu, 5 Sep 2013 10:08:29 +0200
-Subject: [PATCH] Fix Qpid when sending long messages (from oslo)
-
-This is commit 4f97479ad in oslo-incubator
-
-Qpid has a limitation where it cannot serialize a dict containing a
-string greater than 65535 characters. This change alters the Qpid
-implementation to JSON encode the dict before sending it, but only if
-Qpid would fail to serialize it. This maintains as much backward
-compatibility as possible, though long messages will still fail if they
-are sent to an older receiver.
-
-The first part of this fix was ported to Grizzly in Ib52e9458a to allow
-receiving messages from Havana using the new format. Even though this
-change will modify the message format, it will only do it when messages
-are longer than 65K which would be broken anyway and could cause serious
-bugs like the one linked below.
-
-Fixes bug 1215091
-
-Change-Id: I505b648c3d0e1176ec7a3fc7d1646fa5a5232261
----
- nova/openstack/common/rpc/impl_qpid.py | 28 ++++++++++++++++++++++++++++
- 1 file changed, 28 insertions(+)
-
-diff --git a/nova/openstack/common/rpc/impl_qpid.py b/nova/openstack/common/rpc/impl_qpid.py
-index 0044088..a7aebc1 100644
---- a/nova/openstack/common/rpc/impl_qpid.py
-+++ b/nova/openstack/common/rpc/impl_qpid.py
-@@ -31,6 +31,7 @@ from nova.openstack.common import log as logging
- from nova.openstack.common.rpc import amqp as rpc_amqp
- from nova.openstack.common.rpc import common as rpc_common
-
-+qpid_codec = importutils.try_import("qpid.codec010")
- qpid_messaging = importutils.try_import("qpid.messaging")
- qpid_exceptions = importutils.try_import("qpid.messaging.exceptions")
-
-@@ -247,8 +248,35 @@ class Publisher(object):
- """Re-establish the Sender after a reconnection"""
- self.sender = session.sender(self.address)
-
-+ def _pack_json_msg(self, msg):
-+ """Qpid cannot serialize dicts containing strings longer than 65535
-+ characters. This function dumps the message content to a JSON
-+ string, which Qpid is able to handle.
-+
-+ :param msg: May be either a Qpid Message object or a bare dict.
-+ :returns: A Qpid Message with its content field JSON encoded.
-+ """
-+ try:
-+ msg.content = jsonutils.dumps(msg.content)
-+ except AttributeError:
-+ # Need to have a Qpid message so we can set the content_type.
-+ msg = qpid_messaging.Message(jsonutils.dumps(msg))
-+ msg.content_type = JSON_CONTENT_TYPE
-+ return msg
-+
- def send(self, msg):
- """Send a message"""
-+ try:
-+ # Check if Qpid can encode the message
-+ check_msg = msg
-+ if not hasattr(check_msg, 'content_type'):
-+ check_msg = qpid_messaging.Message(msg)
-+ content_type = check_msg.content_type
-+ enc, dec = qpid_messaging.message.get_codec(content_type)
-+ enc(check_msg.content)
-+ except qpid_codec.CodecException:
-+ # This means the message couldn't be serialized as a dict.
-+ msg = self._pack_json_msg(msg)
- self.sender.send(msg)
-
-
---
-1.8.1.2
-
-
diff --git a/sys-cluster/nova/files/2013.1.3-CVE-2013-4278.patch b/sys-cluster/nova/files/2013.1.3-CVE-2013-4278.patch
deleted file mode 100644
index 51c3af50a144..000000000000
--- a/sys-cluster/nova/files/2013.1.3-CVE-2013-4278.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From 8b686195afe7e6dfb46c56c1ef2fe9c993d8e495 Mon Sep 17 00:00:00 2001
-From: Russell Bryant <rbryant@redhat.com>
-Date: Tue, 20 Aug 2013 11:06:12 -0400
-Subject: [PATCH] Enforce flavor access during instance boot
-
-The code in the servers API did not pass the context when retrieving
-flavor details. That means it would use an admin context instead,
-bypassing all flavor access control checks.
-
-This patch includes the fix, and the corresponding unit test for the v2
-API.
-
-Closes-bug: #1212179
-
-(cherry picked from commit 4054cc4a22a1fea997dec76afb5646fd6c6ea6b9)
-
-Conflicts:
- nova/api/openstack/compute/plugins/v3/servers.py
- nova/api/openstack/compute/servers.py
- nova/tests/api/openstack/compute/plugins/v3/test_servers.py
- nova/tests/api/openstack/compute/test_servers.py
-
-Change-Id: I681ae9965e19767df22fa74c3315e4e03a459d3b
----
- nova/api/openstack/compute/servers.py | 3 ++-
- nova/tests/api/openstack/compute/test_servers.py | 22 ++++++++++++++++++++--
- 2 files changed, 22 insertions(+), 3 deletions(-)
-
-diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py
-index 85ef080..6c38219 100644
---- a/nova/api/openstack/compute/servers.py
-+++ b/nova/api/openstack/compute/servers.py
-@@ -873,7 +873,8 @@ class Controller(wsgi.Controller):
-
- try:
- _get_inst_type = instance_types.get_instance_type_by_flavor_id
-- inst_type = _get_inst_type(flavor_id, read_deleted="no")
-+ inst_type = _get_inst_type(flavor_id, ctxt=context,
-+ read_deleted="no")
-
- (instances, resv_id) = self.compute_api.create(context,
- inst_type,
-diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py
-index 7748c2e..89d0f8a 100644
---- a/nova/tests/api/openstack/compute/test_servers.py
-+++ b/nova/tests/api/openstack/compute/test_servers.py
-@@ -1822,10 +1822,10 @@ class ServersControllerCreateTest(test.TestCase):
- """utility function - check server_dict for absence of adminPass."""
- self.assertTrue("adminPass" not in server_dict)
-
-- def _test_create_instance(self):
-+ def _test_create_instance(self, flavor=2):
- image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
- body = dict(server=dict(
-- name='server_test', imageRef=image_uuid, flavorRef=2,
-+ name='server_test', imageRef=image_uuid, flavorRef=flavor,
- metadata={'hello': 'world', 'open': 'stack'},
- personality={}))
- req = fakes.HTTPRequest.blank('/v2/fake/servers')
-@@ -1837,6 +1837,24 @@ class ServersControllerCreateTest(test.TestCase):
- self._check_admin_pass_len(server)
- self.assertEqual(FAKE_UUID, server['id'])
-
-+ def test_create_instance_private_flavor(self):
-+ values = {
-+ 'name': 'fake_name',
-+ 'memory_mb': 512,
-+ 'vcpus': 1,
-+ 'root_gb': 10,
-+ 'ephemeral_gb': 10,
-+ 'flavorid': '1324',
-+ 'swap': 0,
-+ 'rxtx_factor': 0.5,
-+ 'vcpu_weight': 1,
-+ 'disabled': False,
-+ 'is_public': False,
-+ }
-+ db.instance_type_create(context.get_admin_context(), values)
-+ self.assertRaises(webob.exc.HTTPBadRequest, self._test_create_instance,
-+ flavor=1324)
-+
- def test_create_server_bad_image_href(self):
- image_href = 1
- flavor_ref = 'http://localhost/123/flavors/3'
---
-1.8.1.5
-
diff --git a/sys-cluster/nova/files/CVE-2013-4463_4469-grizzly.patch b/sys-cluster/nova/files/CVE-2013-4463_4469-grizzly.patch
new file mode 100644
index 000000000000..f2dd6cdca46c
--- /dev/null
+++ b/sys-cluster/nova/files/CVE-2013-4463_4469-grizzly.patch
@@ -0,0 +1,432 @@
+From 135faa7b5d9855312bedc19e5e1ecebae34d3d18 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?= <pbrady@redhat.com>
+Date: Fri, 27 Sep 2013 04:07:14 +0100
+Subject: [PATCH] ensure we don't boot oversized images
+
+Since we can't generally shrink incoming images, add extra checks
+to ensure oversized images are not allowed through.
+All cases when populating the libvirt image cache are now handled,
+including the initial download from glance, where we avoid
+converting to raw, as that could generate non sparse images
+much larger than the downloaded image.
+
+* nova/virt/libvirt/utils.py (fetch_image): Allow passing through
+of the max_size parameter.
+* nova/virt/images.py (fetch_to_raw): Accept the max_size parameter,
+and use it to discard images with larger (virtual) sizes.
+* nova/virt/libvirt/imagebackend.py (verify_base_size): A new
+refactored function to identify and raise exception to oversized images.
+(Raw.create_image): Pass the max_size to the fetch function.
+Also enforce virtual image size checking for already fetched images,
+as this class (despite the name) can be handling qcow files.
+(Qcow2.create_image): Pass the max_size to the fetch function,
+or verify the virtual size for the instance as done previously.
+(Lvm.create_image): Pass the max_size to the fetch function.
+Also check the size before transferring to the volume to improve
+efficiency by not even attempting the transfer of oversized images.
+(Rbd.create_image): Likewise.
+* nova/tests/fake_libvirt_utils.py: Support max_size arg.
+* nova/tests/test_libvirt.py (test_fetch_raw_image):
+Add a case to check oversized images are discarded.
+* nova/tests/test_imagebackend.py (test_create_image_too_small):
+Adjust to avoid the fetch size check.
+
+Fixes bug: 1177830
+Fixes bug: 1206081
+
+Conflicts:
+
+ nova/tests/test_imagebackend.py
+ nova/virt/libvirt/imagebackend.py
+
+Change-Id: Idc35fce580be4f74e23883d1b4bea6475c3f6e30
+---
+ nova/tests/fake_libvirt_utils.py | 2 +-
+ nova/tests/test_imagebackend.py | 35 ++++++++++-------------------
+ nova/tests/test_libvirt.py | 24 +++++++++++++++++---
+ nova/virt/images.py | 24 +++++++++++++++++---
+ nova/virt/libvirt/imagebackend.py | 47 ++++++++++++++++++++++++++++++---------
+ nova/virt/libvirt/utils.py | 5 +++--
+ 6 files changed, 95 insertions(+), 42 deletions(-)
+
+diff --git a/nova/tests/fake_libvirt_utils.py b/nova/tests/fake_libvirt_utils.py
+index 23b758e..ecf357a 100644
+--- a/nova/tests/fake_libvirt_utils.py
++++ b/nova/tests/fake_libvirt_utils.py
+@@ -193,7 +193,7 @@ def get_fs_info(path):
+ 'free': 84 * (1024 ** 3)}
+
+
+-def fetch_image(context, target, image_id, user_id, project_id):
++def fetch_image(context, target, image_id, user_id, project_id, max_size=0):
+ pass
+
+
+diff --git a/nova/tests/test_imagebackend.py b/nova/tests/test_imagebackend.py
+index 77446e8..93ed23d 100644
+--- a/nova/tests/test_imagebackend.py
++++ b/nova/tests/test_imagebackend.py
+@@ -189,7 +189,7 @@ def prepare_mocks(self):
+
+ def test_create_image(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH, image_id=None)
++ fn(target=self.TEMPLATE_PATH, max_size=None, image_id=None)
+ imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH, self.PATH)
+ self.mox.ReplayAll()
+
+@@ -210,7 +210,7 @@ def test_create_image_generated(self):
+
+ def test_create_image_extend(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH, image_id=None)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH, image_id=None)
+ imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH, self.PATH)
+ imagebackend.disk.extend(self.PATH, self.SIZE)
+ self.mox.ReplayAll()
+@@ -260,7 +260,7 @@ def prepare_mocks(self):
+
+ def test_create_image(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=None, target=self.TEMPLATE_PATH)
+ imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH,
+ self.PATH)
+ self.mox.ReplayAll()
+@@ -272,15 +272,12 @@ def test_create_image(self):
+
+ def test_create_image_with_size(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ if self.OLD_STYLE_INSTANCE_PATH:
+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
+ os.path.exists(self.PATH).AndReturn(False)
+- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+- ).AndReturn(self.SIZE)
+ os.path.exists(self.PATH).AndReturn(False)
+ imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH,
+ self.PATH)
+@@ -294,27 +291,24 @@ def test_create_image_with_size(self):
+
+ def test_create_image_too_small(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+ self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ if self.OLD_STYLE_INSTANCE_PATH:
+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
+- os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
+- os.path.exists(self.PATH).AndReturn(False)
++ os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
+ imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+ ).AndReturn(self.SIZE)
+ self.mox.ReplayAll()
+
+ image = self.image_class(self.INSTANCE, self.NAME)
+- self.assertRaises(exception.ImageTooLarge, image.create_image, fn,
+- self.TEMPLATE_PATH, 1)
++ self.assertRaises(exception.InstanceTypeDiskTooSmall,
++ image.create_image, fn, self.TEMPLATE_PATH, 1)
+ self.mox.VerifyAll()
+
+ def test_generate_resized_backing_files(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ self.mox.StubOutWithMock(imagebackend.libvirt_utils,
+ 'get_disk_backing_file')
+ if self.OLD_STYLE_INSTANCE_PATH:
+@@ -329,8 +323,6 @@ def test_generate_resized_backing_files(self):
+ self.QCOW2_BASE)
+ imagebackend.disk.extend(self.QCOW2_BASE, self.SIZE)
+
+- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+- ).AndReturn(self.SIZE)
+ os.path.exists(self.PATH).AndReturn(True)
+ self.mox.ReplayAll()
+
+@@ -341,9 +333,8 @@ def test_generate_resized_backing_files(self):
+
+ def test_qcow2_exists_and_has_no_backing_file(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ self.mox.StubOutWithMock(imagebackend.libvirt_utils,
+ 'get_disk_backing_file')
+ if self.OLD_STYLE_INSTANCE_PATH:
+@@ -353,8 +344,6 @@ def test_qcow2_exists_and_has_no_backing_file(self):
+
+ imagebackend.libvirt_utils.get_disk_backing_file(self.PATH)\
+ .AndReturn(None)
+- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+- ).AndReturn(self.SIZE)
+ os.path.exists(self.PATH).AndReturn(True)
+ self.mox.ReplayAll()
+
+@@ -391,7 +380,7 @@ def prepare_mocks(self):
+
+ def _create_image(self, sparse):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=None, target=self.TEMPLATE_PATH)
+ self.libvirt_utils.create_lvm_image(self.VG,
+ self.LV,
+ self.TEMPLATE_SIZE,
+@@ -423,7 +412,7 @@ def _create_image_generated(self, sparse):
+
+ def _create_image_resize(self, sparse):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.libvirt_utils.create_lvm_image(self.VG, self.LV,
+ self.SIZE, sparse=sparse)
+ self.disk.get_disk_size(self.TEMPLATE_PATH
+@@ -462,7 +451,7 @@ def test_create_image_resize_sparsed(self):
+
+ def test_create_image_negative(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.libvirt_utils.create_lvm_image(self.VG,
+ self.LV,
+ self.SIZE,
+diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
+index d8c4cf2..e422ec7 100644
+--- a/nova/tests/test_libvirt.py
++++ b/nova/tests/test_libvirt.py
+@@ -4826,7 +4826,8 @@ def test_fetch_image(self):
+ image_id = '4'
+ user_id = 'fake'
+ project_id = 'fake'
+- images.fetch_to_raw(context, image_id, target, user_id, project_id)
++ images.fetch_to_raw(context, image_id, target, user_id, project_id,
++ max_size=0)
+
+ self.mox.ReplayAll()
+ libvirt_utils.fetch_image(context, target, image_id,
+@@ -4856,20 +4857,27 @@ class FakeImgInfo(object):
+ file_format = path.split('.')[-2]
+ elif file_format == 'converted':
+ file_format = 'raw'
++
+ if 'backing' in path:
+ backing_file = 'backing'
+ else:
+ backing_file = None
+
++ if 'big' in path:
++ virtual_size = 2
++ else:
++ virtual_size = 1
++
+ FakeImgInfo.file_format = file_format
+ FakeImgInfo.backing_file = backing_file
++ FakeImgInfo.virtual_size = virtual_size
+
+ return FakeImgInfo()
+
+ self.stubs.Set(utils, 'execute', fake_execute)
+ self.stubs.Set(os, 'rename', fake_rename)
+ self.stubs.Set(os, 'unlink', fake_unlink)
+- self.stubs.Set(images, 'fetch', lambda *_: None)
++ self.stubs.Set(images, 'fetch', lambda *_, **__: None)
+ self.stubs.Set(images, 'qemu_img_info', fake_qemu_img_info)
+ self.stubs.Set(utils, 'delete_if_exists', fake_rm_on_errror)
+
+@@ -4884,7 +4892,8 @@ class FakeImgInfo(object):
+ 't.qcow2.part', 't.qcow2.converted'),
+ ('rm', 't.qcow2.part'),
+ ('mv', 't.qcow2.converted', 't.qcow2')]
+- images.fetch_to_raw(context, image_id, target, user_id, project_id)
++ images.fetch_to_raw(context, image_id, target, user_id, project_id,
++ max_size=1)
+ self.assertEqual(self.executes, expected_commands)
+
+ target = 't.raw'
+@@ -4901,6 +4910,15 @@ class FakeImgInfo(object):
+ context, image_id, target, user_id, project_id)
+ self.assertEqual(self.executes, expected_commands)
+
++ target = 'big.qcow2'
++ self.executes = []
++ expected_commands = [('rm', '-f', 'big.qcow2.part')]
++ self.assertRaises(exception.InstanceTypeDiskTooSmall,
++ images.fetch_to_raw,
++ context, image_id, target, user_id, project_id,
++ max_size=1)
++ self.assertEqual(self.executes, expected_commands)
++
+ del self.executes
+
+ def test_get_disk_backing_file(self):
+diff --git a/nova/virt/images.py b/nova/virt/images.py
+index b40f566..541779a 100755
+--- a/nova/virt/images.py
++++ b/nova/virt/images.py
+@@ -190,7 +190,7 @@ def convert_image(source, dest, out_format, run_as_root=False):
+ utils.execute(*cmd, run_as_root=run_as_root)
+
+
+-def fetch(context, image_href, path, _user_id, _project_id):
++def fetch(context, image_href, path, _user_id, _project_id, max_size=0):
+ # TODO(vish): Improve context handling and add owner and auth data
+ # when it is added to glance. Right now there is no
+ # auth checking in glance, so we assume that access was
+@@ -202,9 +202,10 @@ def fetch(context, image_href, path, _user_id, _project_id):
+ image_service.download(context, image_id, image_file)
+
+
+-def fetch_to_raw(context, image_href, path, user_id, project_id):
++def fetch_to_raw(context, image_href, path, user_id, project_id, max_size=0):
+ path_tmp = "%s.part" % path
+- fetch(context, image_href, path_tmp, user_id, project_id)
++ fetch(context, image_href, path_tmp, user_id, project_id,
++ max_size=max_size)
+
+ with utils.remove_path_on_error(path_tmp):
+ data = qemu_img_info(path_tmp)
+@@ -220,6 +221,23 @@ def fetch_to_raw(context, image_href, path, user_id, project_id):
+ raise exception.ImageUnacceptable(image_id=image_href,
+ reason=_("fmt=%(fmt)s backed by: %(backing_file)s") % locals())
+
++ # We can't generally shrink incoming images, so disallow
++ # images > size of the flavor we're booting. Checking here avoids
++ # an immediate DoS where we convert large qcow images to raw
++ # (which may compress well but not be sparse).
++ # TODO(p-draigbrady): loop through all flavor sizes, so that
++ # we might continue here and not discard the download.
++ # If we did that we'd have to do the higher level size checks
++ # irrespective of whether the base image was prepared or not.
++ disk_size = data.virtual_size
++ if max_size and max_size < disk_size:
++ msg = _('%(base)s virtual size %(disk_size)s '
++ 'larger than flavor root disk size %(size)s')
++ LOG.error(msg % {'base': path,
++ 'disk_size': disk_size,
++ 'size': max_size})
++ raise exception.InstanceTypeDiskTooSmall()
++
+ if fmt != "raw" and CONF.force_raw_images:
+ staged = "%s.converted" % path
+ LOG.debug("%s was %s, converting to raw" % (image_href, fmt))
+diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py
+index e2c7ccf..dc85c97 100755
+--- a/nova/virt/libvirt/imagebackend.py
++++ b/nova/virt/libvirt/imagebackend.py
+@@ -177,6 +177,36 @@ def _can_fallocate(self):
+ (CONF.preallocate_images, self.path))
+ return can_fallocate
+
++ @staticmethod
++ def verify_base_size(base, size, base_size=0):
++ """Check that the base image is not larger than size.
++ Since images can't be generally shrunk, enforce this
++ constraint taking account of virtual image size.
++ """
++
++ # Note(pbrady): The size and min_disk parameters of a glance
++ # image are checked against the instance size before the image
++ # is even downloaded from glance, but currently min_disk is
++ # adjustable and doesn't currently account for virtual disk size,
++ # so we need this extra check here.
++ # NOTE(cfb): Having a flavor that sets the root size to 0 and having
++ # nova effectively ignore that size and use the size of the
++ # image is considered a feature at this time, not a bug.
++
++ if size is None:
++ return
++
++ if size and not base_size:
++ base_size = disk.get_disk_size(base)
++
++ if size < base_size:
++ msg = _('%(base)s virtual size %(base_size)s '
++ 'larger than flavor root disk size %(size)s')
++ LOG.error(msg % {'base': base,
++ 'base_size': base_size,
++ 'size': size})
++ raise exception.InstanceTypeDiskTooSmall()
++
+ def snapshot_create(self):
+ raise NotImplementedError
+
+@@ -217,7 +247,8 @@ def copy_raw_image(base, target, size):
+ #Generating image in place
+ prepare_template(target=self.path, *args, **kwargs)
+ else:
+- prepare_template(target=base, *args, **kwargs)
++ prepare_template(target=base, max_size=size, *args, **kwargs)
++ self.verify_base_size(base, size)
+ if not os.path.exists(self.path):
+ with utils.remove_path_on_error(self.path):
+ copy_raw_image(base, self.path, size)
+@@ -257,7 +288,9 @@ def copy_qcow2_image(base, target, size):
+
+ # Download the unmodified base image unless we already have a copy.
+ if not os.path.exists(base):
+- prepare_template(target=base, *args, **kwargs)
++ prepare_template(target=base, max_size=size, *args, **kwargs)
++ else:
++ self.verify_base_size(base, size)
+
+ legacy_backing_size = None
+ legacy_base = base
+@@ -283,13 +316,6 @@ def copy_qcow2_image(base, target, size):
+ libvirt_utils.copy_image(base, legacy_base)
+ disk.extend(legacy_base, legacy_backing_size)
+
+- # NOTE(cfb): Having a flavor that sets the root size to 0 and having
+- # nova effectively ignore that size and use the size of the
+- # image is considered a feature at this time, not a bug.
+- if size and size < disk.get_disk_size(base):
+- LOG.error('%s virtual size larger than flavor root disk size %s' %
+- (base, size))
+- raise exception.ImageTooLarge()
+ if not os.path.exists(self.path):
+ with utils.remove_path_on_error(self.path):
+ copy_qcow2_image(base, self.path, size)
+@@ -348,6 +374,7 @@ def create_image(self, prepare_template, base, size, *args, **kwargs):
+ lock_path=self.lock_path)
+ def create_lvm_image(base, size):
+ base_size = disk.get_disk_size(base)
++ self.verify_base_size(base, size, base_size=base_size)
+ resize = size > base_size
+ size = size if resize else base_size
+ libvirt_utils.create_lvm_image(self.vg, self.lv,
+@@ -365,7 +392,7 @@ def create_lvm_image(base, size):
+ with self.remove_volume_on_error(self.path):
+ prepare_template(target=self.path, *args, **kwargs)
+ else:
+- prepare_template(target=base, *args, **kwargs)
++ prepare_template(target=base, max_size=size, *args, **kwargs)
+ with self.remove_volume_on_error(self.path):
+ create_lvm_image(base, size)
+
+diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py
+index 6972243..4c31fcb 100755
+--- a/nova/virt/libvirt/utils.py
++++ b/nova/virt/libvirt/utils.py
+@@ -592,9 +592,10 @@ def get_fs_info(path):
+ 'used': used}
+
+
+-def fetch_image(context, target, image_id, user_id, project_id):
++def fetch_image(context, target, image_id, user_id, project_id, max_size=0):
+ """Grab image."""
+- images.fetch_to_raw(context, image_id, target, user_id, project_id)
++ images.fetch_to_raw(context, image_id, target, user_id, project_id,
++ max_size=max_size)
+
+
+ def get_instance_path(instance, forceold=False, relative=False):
+--
+1.8.4
+
diff --git a/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch b/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch
new file mode 100644
index 000000000000..575b11d9bbdf
--- /dev/null
+++ b/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch
@@ -0,0 +1,452 @@
+From 3cdfe894ab58f7b91bf7fb690fc5bc724e44066f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?= <pbrady@redhat.com>
+Date: Fri, 27 Sep 2013 04:07:14 +0100
+Subject: [PATCH] ensure we don't boot oversized images
+
+Since we can't generally shrink incoming images, add extra checks
+to ensure oversized images are not allowed through.
+All cases when populating the libvirt image cache are now handled,
+including the initial download from glance, where we avoid
+converting to raw, as that could generate non sparse images
+much larger than the downloaded image.
+
+* nova/virt/libvirt/utils.py (fetch_image): Allow passing through
+of the max_size parameter.
+* nova/virt/images.py (fetch_to_raw): Accept the max_size parameter,
+and use it to discard images with larger (virtual) sizes.
+* nova/virt/libvirt/imagebackend.py (verify_base_size): A new
+refactored function to identify and raise exception to oversized images.
+(Raw.create_image): Pass the max_size to the fetch function.
+Also enforce virtual image size checking for already fetched images,
+as this class (despite the name) can be handling qcow files.
+(Qcow2.create_image): Pass the max_size to the fetch function,
+or verify the virtual size for the instance as done previously.
+(Lvm.create_image): Pass the max_size to the fetch function.
+Also check the size before transferring to the volume to improve
+efficiency by not even attempting the transfer of oversized images.
+(Rbd.create_image): Likewise.
+* nova/tests/virt/libvirt/fake_libvirt_utils.py: Support max_size arg.
+* nova/tests/virt/libvirt/test_libvirt.py (test_fetch_raw_image):
+Add a case to check oversized images are discarded.
+* nova/tests/virt/libvirt/test_imagebackend.py
+(test_create_image_too_small): Adjust to avoid the fetch size check.
+
+Fixes bug: 1177830
+Fixes bug: 1206081
+Change-Id: I3d47adaa2ad07434853f447feb27d7aae0e2e717
+---
+ nova/tests/virt/libvirt/fake_libvirt_utils.py | 2 +-
+ nova/tests/virt/libvirt/test_imagebackend.py | 34 ++++++-----------
+ nova/tests/virt/libvirt/test_libvirt.py | 24 ++++++++++--
+ nova/virt/images.py | 24 ++++++++++--
+ nova/virt/libvirt/imagebackend.py | 55 +++++++++++++++++++--------
+ nova/virt/libvirt/utils.py | 5 ++-
+ 6 files changed, 98 insertions(+), 46 deletions(-)
+
+diff --git a/nova/tests/virt/libvirt/fake_libvirt_utils.py b/nova/tests/virt/libvirt/fake_libvirt_utils.py
+index e18f9df..4799837 100644
+--- a/nova/tests/virt/libvirt/fake_libvirt_utils.py
++++ b/nova/tests/virt/libvirt/fake_libvirt_utils.py
+@@ -197,7 +197,7 @@ def get_fs_info(path):
+ 'free': 84 * (1024 ** 3)}
+
+
+-def fetch_image(context, target, image_id, user_id, project_id):
++def fetch_image(context, target, image_id, user_id, project_id, max_size=0):
+ pass
+
+
+diff --git a/nova/tests/virt/libvirt/test_imagebackend.py b/nova/tests/virt/libvirt/test_imagebackend.py
+index b862510..2455ec8 100644
+--- a/nova/tests/virt/libvirt/test_imagebackend.py
++++ b/nova/tests/virt/libvirt/test_imagebackend.py
+@@ -190,7 +190,7 @@ def prepare_mocks(self):
+
+ def test_create_image(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH, image_id=None)
++ fn(target=self.TEMPLATE_PATH, max_size=None, image_id=None)
+ imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH, self.PATH)
+ self.mox.ReplayAll()
+
+@@ -211,7 +211,7 @@ def test_create_image_generated(self):
+
+ def test_create_image_extend(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH, image_id=None)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH, image_id=None)
+ imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH, self.PATH)
+ imagebackend.disk.extend(self.PATH, self.SIZE, use_cow=False)
+ self.mox.ReplayAll()
+@@ -261,7 +261,7 @@ def prepare_mocks(self):
+
+ def test_create_image(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=None, target=self.TEMPLATE_PATH)
+ imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH,
+ self.PATH)
+ self.mox.ReplayAll()
+@@ -273,15 +273,12 @@ def test_create_image(self):
+
+ def test_create_image_with_size(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ if self.OLD_STYLE_INSTANCE_PATH:
+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
+ os.path.exists(self.PATH).AndReturn(False)
+- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+- ).AndReturn(self.SIZE)
+ os.path.exists(self.PATH).AndReturn(False)
+ imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH,
+ self.PATH)
+@@ -295,13 +292,11 @@ def test_create_image_with_size(self):
+
+ def test_create_image_too_small(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+ self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ if self.OLD_STYLE_INSTANCE_PATH:
+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
+- os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
+- os.path.exists(self.PATH).AndReturn(False)
++ os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
+ imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+ ).AndReturn(self.SIZE)
+ self.mox.ReplayAll()
+@@ -313,9 +308,8 @@ def test_create_image_too_small(self):
+
+ def test_generate_resized_backing_files(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ self.mox.StubOutWithMock(imagebackend.libvirt_utils,
+ 'get_disk_backing_file')
+ if self.OLD_STYLE_INSTANCE_PATH:
+@@ -330,8 +324,6 @@ def test_generate_resized_backing_files(self):
+ self.QCOW2_BASE)
+ imagebackend.disk.extend(self.QCOW2_BASE, self.SIZE, use_cow=True)
+
+- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+- ).AndReturn(self.SIZE)
+ os.path.exists(self.PATH).AndReturn(True)
+ self.mox.ReplayAll()
+
+@@ -342,9 +334,8 @@ def test_generate_resized_backing_files(self):
+
+ def test_qcow2_exists_and_has_no_backing_file(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.mox.StubOutWithMock(os.path, 'exists')
+- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
+ self.mox.StubOutWithMock(imagebackend.libvirt_utils,
+ 'get_disk_backing_file')
+ if self.OLD_STYLE_INSTANCE_PATH:
+@@ -354,8 +345,6 @@ def test_qcow2_exists_and_has_no_backing_file(self):
+
+ imagebackend.libvirt_utils.get_disk_backing_file(self.PATH)\
+ .AndReturn(None)
+- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
+- ).AndReturn(self.SIZE)
+ os.path.exists(self.PATH).AndReturn(True)
+ self.mox.ReplayAll()
+
+@@ -392,7 +381,7 @@ def prepare_mocks(self):
+
+ def _create_image(self, sparse):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=None, target=self.TEMPLATE_PATH)
+ self.libvirt_utils.create_lvm_image(self.VG,
+ self.LV,
+ self.TEMPLATE_SIZE,
+@@ -424,7 +413,7 @@ def _create_image_generated(self, sparse):
+
+ def _create_image_resize(self, sparse):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.libvirt_utils.create_lvm_image(self.VG, self.LV,
+ self.SIZE, sparse=sparse)
+ self.disk.get_disk_size(self.TEMPLATE_PATH
+@@ -463,7 +452,7 @@ def test_create_image_resize_sparsed(self):
+
+ def test_create_image_negative(self):
+ fn = self.prepare_mocks()
+- fn(target=self.TEMPLATE_PATH)
++ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH)
+ self.libvirt_utils.create_lvm_image(self.VG,
+ self.LV,
+ self.SIZE,
+@@ -607,7 +596,7 @@ def test_cache_template_exists(self):
+
+ def test_create_image(self):
+ fn = self.prepare_mocks()
+- fn(rbd=self.rbd, target=self.TEMPLATE_PATH)
++ fn(max_size=None, rbd=self.rbd, target=self.TEMPLATE_PATH)
+
+ self.rbd.RBD_FEATURE_LAYERING = 1
+
+@@ -635,6 +624,7 @@ def fake_fetch(target, *args, **kwargs):
+ return
+
+ self.stubs.Set(os.path, 'exists', lambda _: True)
++ self.stubs.Set(image, 'check_image_exists', lambda: True)
+
+ image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
+
+diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py
+index ac36be4..5d1361e 100644
+--- a/nova/tests/virt/libvirt/test_libvirt.py
++++ b/nova/tests/virt/libvirt/test_libvirt.py
+@@ -6308,7 +6308,8 @@ def test_fetch_image(self):
+ image_id = '4'
+ user_id = 'fake'
+ project_id = 'fake'
+- images.fetch_to_raw(context, image_id, target, user_id, project_id)
++ images.fetch_to_raw(context, image_id, target, user_id, project_id,
++ max_size=0)
+
+ self.mox.ReplayAll()
+ libvirt_utils.fetch_image(context, target, image_id,
+@@ -6338,20 +6339,27 @@ class FakeImgInfo(object):
+ file_format = path.split('.')[-2]
+ elif file_format == 'converted':
+ file_format = 'raw'
++
+ if 'backing' in path:
+ backing_file = 'backing'
+ else:
+ backing_file = None
+
++ if 'big' in path:
++ virtual_size = 2
++ else:
++ virtual_size = 1
++
+ FakeImgInfo.file_format = file_format
+ FakeImgInfo.backing_file = backing_file
++ FakeImgInfo.virtual_size = virtual_size
+
+ return FakeImgInfo()
+
+ self.stubs.Set(utils, 'execute', fake_execute)
+ self.stubs.Set(os, 'rename', fake_rename)
+ self.stubs.Set(os, 'unlink', fake_unlink)
+- self.stubs.Set(images, 'fetch', lambda *_: None)
++ self.stubs.Set(images, 'fetch', lambda *_, **__: None)
+ self.stubs.Set(images, 'qemu_img_info', fake_qemu_img_info)
+ self.stubs.Set(fileutils, 'delete_if_exists', fake_rm_on_error)
+
+@@ -6373,7 +6381,8 @@ class FakeImgInfo(object):
+ 't.qcow2.part', 't.qcow2.converted'),
+ ('rm', 't.qcow2.part'),
+ ('mv', 't.qcow2.converted', 't.qcow2')]
+- images.fetch_to_raw(context, image_id, target, user_id, project_id)
++ images.fetch_to_raw(context, image_id, target, user_id, project_id,
++ max_size=1)
+ self.assertEqual(self.executes, expected_commands)
+
+ target = 't.raw'
+@@ -6390,6 +6399,15 @@ class FakeImgInfo(object):
+ context, image_id, target, user_id, project_id)
+ self.assertEqual(self.executes, expected_commands)
+
++ target = 'big.qcow2'
++ self.executes = []
++ expected_commands = [('rm', '-f', 'big.qcow2.part')]
++ self.assertRaises(exception.InstanceTypeDiskTooSmall,
++ images.fetch_to_raw,
++ context, image_id, target, user_id, project_id,
++ max_size=1)
++ self.assertEqual(self.executes, expected_commands)
++
+ del self.executes
+
+ def test_get_disk_backing_file(self):
+diff --git a/nova/virt/images.py b/nova/virt/images.py
+index 9c4c101..6d20e65 100644
+--- a/nova/virt/images.py
++++ b/nova/virt/images.py
+@@ -179,7 +179,7 @@ def convert_image(source, dest, out_format, run_as_root=False):
+ utils.execute(*cmd, run_as_root=run_as_root)
+
+
+-def fetch(context, image_href, path, _user_id, _project_id):
++def fetch(context, image_href, path, _user_id, _project_id, max_size=0):
+ # TODO(vish): Improve context handling and add owner and auth data
+ # when it is added to glance. Right now there is no
+ # auth checking in glance, so we assume that access was
+@@ -190,9 +190,10 @@ def fetch(context, image_href, path, _user_id, _project_id):
+ image_service.download(context, image_id, dst_path=path)
+
+
+-def fetch_to_raw(context, image_href, path, user_id, project_id):
++def fetch_to_raw(context, image_href, path, user_id, project_id, max_size=0):
+ path_tmp = "%s.part" % path
+- fetch(context, image_href, path_tmp, user_id, project_id)
++ fetch(context, image_href, path_tmp, user_id, project_id,
++ max_size=max_size)
+
+ with fileutils.remove_path_on_error(path_tmp):
+ data = qemu_img_info(path_tmp)
+@@ -209,6 +210,23 @@ def fetch_to_raw(context, image_href, path, user_id, project_id):
+ reason=(_("fmt=%(fmt)s backed by: %(backing_file)s") %
+ {'fmt': fmt, 'backing_file': backing_file}))
+
++ # We can't generally shrink incoming images, so disallow
++ # images > size of the flavor we're booting. Checking here avoids
++ # an immediate DoS where we convert large qcow images to raw
++ # (which may compress well but not be sparse).
++ # TODO(p-draigbrady): loop through all flavor sizes, so that
++ # we might continue here and not discard the download.
++ # If we did that we'd have to do the higher level size checks
++ # irrespective of whether the base image was prepared or not.
++ disk_size = data.virtual_size
++ if max_size and max_size < disk_size:
++ msg = _('%(base)s virtual size %(disk_size)s '
++ 'larger than flavor root disk size %(size)s')
++ LOG.error(msg % {'base': path,
++ 'disk_size': disk_size,
++ 'size': max_size})
++ raise exception.InstanceTypeDiskTooSmall()
++
+ if fmt != "raw" and CONF.force_raw_images:
+ staged = "%s.converted" % path
+ LOG.debug("%s was %s, converting to raw" % (image_href, fmt))
+diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py
+index 84c46e8..e900789 100644
+--- a/nova/virt/libvirt/imagebackend.py
++++ b/nova/virt/libvirt/imagebackend.py
+@@ -193,6 +193,36 @@ def _can_fallocate(self):
+ (CONF.preallocate_images, self.path))
+ return can_fallocate
+
++ @staticmethod
++ def verify_base_size(base, size, base_size=0):
++ """Check that the base image is not larger than size.
++ Since images can't be generally shrunk, enforce this
++ constraint taking account of virtual image size.
++ """
++
++ # Note(pbrady): The size and min_disk parameters of a glance
++ # image are checked against the instance size before the image
++ # is even downloaded from glance, but currently min_disk is
++ # adjustable and doesn't currently account for virtual disk size,
++ # so we need this extra check here.
++ # NOTE(cfb): Having a flavor that sets the root size to 0 and having
++ # nova effectively ignore that size and use the size of the
++ # image is considered a feature at this time, not a bug.
++
++ if size is None:
++ return
++
++ if size and not base_size:
++ base_size = disk.get_disk_size(base)
++
++ if size < base_size:
++ msg = _('%(base)s virtual size %(base_size)s '
++ 'larger than flavor root disk size %(size)s')
++ LOG.error(msg % {'base': base,
++ 'base_size': base_size,
++ 'size': size})
++ raise exception.InstanceTypeDiskTooSmall()
++
+ def snapshot_create(self):
+ raise NotImplementedError()
+
+@@ -234,7 +264,8 @@ def copy_raw_image(base, target, size):
+ #Generating image in place
+ prepare_template(target=self.path, *args, **kwargs)
+ else:
+- prepare_template(target=base, *args, **kwargs)
++ prepare_template(target=base, max_size=size, *args, **kwargs)
++ self.verify_base_size(base, size)
+ if not os.path.exists(self.path):
+ with fileutils.remove_path_on_error(self.path):
+ copy_raw_image(base, self.path, size)
+@@ -273,7 +304,9 @@ def copy_qcow2_image(base, target, size):
+
+ # Download the unmodified base image unless we already have a copy.
+ if not os.path.exists(base):
+- prepare_template(target=base, *args, **kwargs)
++ prepare_template(target=base, max_size=size, *args, **kwargs)
++ else:
++ self.verify_base_size(base, size)
+
+ legacy_backing_size = None
+ legacy_base = base
+@@ -299,17 +332,6 @@ def copy_qcow2_image(base, target, size):
+ libvirt_utils.copy_image(base, legacy_base)
+ disk.extend(legacy_base, legacy_backing_size, use_cow=True)
+
+- # NOTE(cfb): Having a flavor that sets the root size to 0 and having
+- # nova effectively ignore that size and use the size of the
+- # image is considered a feature at this time, not a bug.
+- disk_size = disk.get_disk_size(base)
+- if size and size < disk_size:
+- msg = _('%(base)s virtual size %(disk_size)s'
+- 'larger than flavor root disk size %(size)s')
+- LOG.error(msg % {'base': base,
+- 'disk_size': disk_size,
+- 'size': size})
+- raise exception.InstanceTypeDiskTooSmall()
+ if not os.path.exists(self.path):
+ with fileutils.remove_path_on_error(self.path):
+ copy_qcow2_image(base, self.path, size)
+@@ -367,6 +389,7 @@ def create_image(self, prepare_template, base, size, *args, **kwargs):
+ @utils.synchronized(base, external=True, lock_path=self.lock_path)
+ def create_lvm_image(base, size):
+ base_size = disk.get_disk_size(base)
++ self.verify_base_size(base, size, base_size=base_size)
+ resize = size > base_size
+ size = size if resize else base_size
+ libvirt_utils.create_lvm_image(self.vg, self.lv,
+@@ -384,7 +407,7 @@ def create_lvm_image(base, size):
+ with self.remove_volume_on_error(self.path):
+ prepare_template(target=self.path, *args, **kwargs)
+ else:
+- prepare_template(target=base, *args, **kwargs)
++ prepare_template(target=base, max_size=size, *args, **kwargs)
+ with self.remove_volume_on_error(self.path):
+ create_lvm_image(base, size)
+
+@@ -514,7 +537,9 @@ def create_image(self, prepare_template, base, size, *args, **kwargs):
+ features = self.rbd.RBD_FEATURE_LAYERING
+
+ if not os.path.exists(base):
+- prepare_template(target=base, *args, **kwargs)
++ prepare_template(target=base, max_size=size, *args, **kwargs)
++ else:
++ self.verify_base_size(base, size)
+
+ # keep using the command line import instead of librbd since it
+ # detects zeroes to preserve sparseness in the image
+diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py
+index 66ff83e..d7c92b7 100644
+--- a/nova/virt/libvirt/utils.py
++++ b/nova/virt/libvirt/utils.py
+@@ -639,9 +639,10 @@ def get_fs_info(path):
+ 'used': used}
+
+
+-def fetch_image(context, target, image_id, user_id, project_id):
++def fetch_image(context, target, image_id, user_id, project_id, max_size=0):
+ """Grab image."""
+- images.fetch_to_raw(context, image_id, target, user_id, project_id)
++ images.fetch_to_raw(context, image_id, target, user_id, project_id,
++ max_size=max_size)
+
+
+ def get_instance_path(instance, forceold=False, relative=False):
+--
+1.8.4
+
diff --git a/sys-cluster/nova/files/CVE-2013-4497-grizzly-1.patch b/sys-cluster/nova/files/CVE-2013-4497-grizzly-1.patch
new file mode 100644
index 000000000000..e8e14c0ab747
--- /dev/null
+++ b/sys-cluster/nova/files/CVE-2013-4497-grizzly-1.patch
@@ -0,0 +1,111 @@
+From df2ea2e3acdede21b40d47b7adbeac04213d031b Mon Sep 17 00:00:00 2001
+From: John Garbutt <john.garbutt@rackspace.com>
+Date: Thu, 12 Sep 2013 18:11:49 +0100
+Subject: [PATCH] xenapi: enforce filters after live-migration
+
+Currently and network filters, including security groups, are
+lost after a server has been live-migrated.
+
+This partially fixes the issue by ensuring that security groups are
+re-applied to the VM once it reached the destination, and been started.
+
+This leaves a small amount of time during the live-migrate where the VM
+is not protected. There is a further bug raised to close the rest of
+this whole, but this helps keep the VM protected for the majority of the
+time.
+
+Fixes bug 1202266
+
+(Cherry picked from commit: 5cced7a6dd32d231c606e25dbf762d199bf9cca7)
+
+Change-Id: I66bc7af1c6da74e18dce47180af0cb6020ba2c1a
+---
+ nova/tests/test_xenapi.py | 22 +++++++++++++++++++++-
+ nova/virt/xenapi/driver.py | 4 ++--
+ nova/virt/xenapi/vmops.py | 18 ++++++++++++++++++
+ 3 files changed, 41 insertions(+), 3 deletions(-)
+
+diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
+index f7fb81d..d4c19a4 100644
+--- a/nova/tests/test_xenapi.py
++++ b/nova/tests/test_xenapi.py
+@@ -2723,7 +2723,27 @@ def test_post_live_migration_at_destination(self):
+ # ensure method is present
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
+ self.conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
+- self.conn.post_live_migration_at_destination(None, None, None, None)
++
++ fake_instance = "instance"
++ fake_network_info = "network_info"
++
++ def fake_fw(instance, network_info):
++ self.assertEquals(instance, fake_instance)
++ self.assertEquals(network_info, fake_network_info)
++ fake_fw.called += 1
++
++ fake_fw.called = 0
++ _vmops = self.conn._vmops
++ self.stubs.Set(_vmops.firewall_driver,
++ 'setup_basic_filtering', fake_fw)
++ self.stubs.Set(_vmops.firewall_driver,
++ 'prepare_instance_filter', fake_fw)
++ self.stubs.Set(_vmops.firewall_driver,
++ 'apply_instance_filter', fake_fw)
++
++ self.conn.post_live_migration_at_destination(None, fake_instance,
++ fake_network_info, None)
++ self.assertEqual(fake_fw.called, 3)
+
+ def test_check_can_live_migrate_destination_with_block_migration(self):
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
+diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
+index 128f67f..564c587 100755
+--- a/nova/virt/xenapi/driver.py
++++ b/nova/virt/xenapi/driver.py
+@@ -1,4 +1,3 @@
+-# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+ # Copyright (c) 2010 Citrix Systems, Inc.
+ # Copyright 2010 OpenStack Foundation
+@@ -514,7 +513,8 @@ def post_live_migration_at_destination(self, ctxt, instance_ref,
+ :params : block_migration: if true, post operation of block_migraiton.
+ """
+ # TODO(JohnGarbutt) look at moving/downloading ramdisk and kernel
+- pass
++ self._vmops.post_live_migration_at_destination(ctxt, instance_ref,
++ network_info, block_device_info, block_device_info)
+
+ def unfilter_instance(self, instance_ref, network_info):
+ """Removes security groups configured for an instance."""
+diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
+index eccf3e0..ae5c697 100644
+--- a/nova/virt/xenapi/vmops.py
++++ b/nova/virt/xenapi/vmops.py
+@@ -1737,6 +1737,24 @@ def live_migrate(self, context, instance, destination_hostname,
+ recover_method(context, instance, destination_hostname,
+ block_migration)
+
++ def post_live_migration_at_destination(self, context, instance,
++ network_info, block_migration,
++ block_device_info):
++ # FIXME(johngarbutt): we should block all traffic until we have
++ # applied security groups, however this requires changes to XenServer
++ try:
++ self.firewall_driver.setup_basic_filtering(
++ instance, network_info)
++ except NotImplementedError:
++ # NOTE(salvatore-orlando): setup_basic_filtering might be
++ # empty or not implemented at all, as basic filter could
++ # be implemented with VIF rules created by xapi plugin
++ pass
++
++ self.firewall_driver.prepare_instance_filter(instance,
++ network_info)
++ self.firewall_driver.apply_instance_filter(instance, network_info)
++
+ def get_per_instance_usage(self):
+ """Get usage info about each active instance."""
+ usage = {}
+--
+1.8.4
+
diff --git a/sys-cluster/nova/files/CVE-2013-4497-grizzly-2.patch b/sys-cluster/nova/files/CVE-2013-4497-grizzly-2.patch
new file mode 100644
index 000000000000..28fbbca758c8
--- /dev/null
+++ b/sys-cluster/nova/files/CVE-2013-4497-grizzly-2.patch
@@ -0,0 +1,51 @@
+From 01de658210fd65171bfbf5450c93673b5ce0bd9e Mon Sep 17 00:00:00 2001
+From: John Garbutt <john.garbutt@rackspace.com>
+Date: Mon, 21 Oct 2013 19:34:43 +0100
+Subject: [PATCH] xenapi: apply firewall rules in finish_migrate
+
+When security groups were added, the rules were not re-applied to
+servers that have been migrated to a new hypervisor.
+
+This change ensures the firewall rules are applied as part of creating
+the new VM in finish_migrate. This code follows a very similar pattern
+to the code in spawn, and that is where the cut and paste code comes
+from. This code duplication was removed in Havana.
+
+Fixes bug 1073306
+
+Change-Id: I6295a782df328a759e358fb82b76dd3f7bd4b39e
+---
+ nova/virt/xenapi/vmops.py | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
+index eccf3e0..7a96ac2 100644
+--- a/nova/virt/xenapi/vmops.py
++++ b/nova/virt/xenapi/vmops.py
+@@ -277,8 +277,23 @@ def finish_migration(self, context, migration, instance, disk_info,
+
+ self._attach_mapped_block_devices(instance, block_device_info)
+
++ try:
++ self.firewall_driver.setup_basic_filtering(
++ instance, network_info)
++ except NotImplementedError:
++ # NOTE(salvatore-orlando): setup_basic_filtering might be
++ # empty or not implemented at all, as basic filter could
++ # be implemented with VIF rules created by xapi plugin
++ pass
++
++ self.firewall_driver.prepare_instance_filter(instance,
++ network_info)
++
+ # 5. Start VM
+ self._start(instance, vm_ref=vm_ref)
++
++ self.firewall_driver.apply_instance_filter(instance, network_info)
++
+ self._update_instance_progress(context, instance,
+ step=5,
+ total_steps=RESIZE_TOTAL_STEPS)
+--
+1.8.4
+
diff --git a/sys-cluster/nova/files/nova-folsom-4-CVE-2013-2030.patch b/sys-cluster/nova/files/nova-folsom-4-CVE-2013-2030.patch
deleted file mode 100644
index a862cb8e477d..000000000000
--- a/sys-cluster/nova/files/nova-folsom-4-CVE-2013-2030.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 74aa04e2ca7942cb1e1a86dcbaffeb72d260ccd7 Mon Sep 17 00:00:00 2001
-From: Russell Bryant <rbryant@redhat.com>
-Date: Wed, 1 May 2013 09:41:57 -0400
-Subject: [PATCH] Remove insecure default for signing_dir option.
-
-The sample api-paste.ini file included an insecure value for the
-signing_dir option for the keystone authtoken middleware. Comment out
-the option so that we just rely on the default behavior by default.
-
-Fix bug 1174608.
-
-Conflicts:
- etc/nova/api-paste.ini
-
-Change-Id: I6189788953d789c34456bbe150b8ed6ce6f68403
-(cherry picked from commit 58d6879b1caaa750c39c8e452a0634c24ffef2ce)
----
- etc/nova/api-paste.ini | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/etc/nova/api-paste.ini b/etc/nova/api-paste.ini
-index 3970974..95307b2 100644
---- a/etc/nova/api-paste.ini
-+++ b/etc/nova/api-paste.ini
-@@ -124,4 +124,7 @@ auth_protocol = http
- admin_tenant_name = %SERVICE_TENANT_NAME%
- admin_user = %SERVICE_USER%
- admin_password = %SERVICE_PASSWORD%
--signing_dir = /tmp/keystone-signing-nova
-+# signing_dir is configurable, but the default behavior of the authtoken
-+# middleware should be sufficient. It will create a temporary directory
-+# in the home directory for the user the nova process is running as.
-+#signing_dir = /var/lib/nova/keystone-signing
---
-1.8.1.5
-
diff --git a/sys-cluster/nova/files/nova-folsom-4-CVE-2013-2096.patch b/sys-cluster/nova/files/nova-folsom-4-CVE-2013-2096.patch
deleted file mode 100644
index 304a61f9d20f..000000000000
--- a/sys-cluster/nova/files/nova-folsom-4-CVE-2013-2096.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 6740c4141ea1152529b82cbf6e5b808eaba912e7 Mon Sep 17 00:00:00 2001
-From: Chet Burgess <cfb@metacloud.com>
-Date: Thu, 9 May 2013 09:57:28 +0000
-Subject: [PATCH] Check QCOW2 image size during root disk creation
-
-glance can only tell us the size of the file, not the virtual
-size of the QCOW2. As such we need to check the virtual size of
-the image once its cached and ensure it's <= to the flavor's
-root disk size.
-
-Change-Id: I833467284126557eb598b8350a84e10c06292fa9
-Fixes: bug 1177830
-(cherry picked from commit 44a8aba1d5da87d54db48079103fdef946666d80)
----
- nova/tests/test_imagebackend.py | 18 ++++++++++++++++++
- nova/virt/libvirt/imagebackend.py | 12 ++++++++++++
- 2 files changed, 30 insertions(+)
-
-diff --git a/nova/tests/test_imagebackend.py b/nova/tests/test_imagebackend.py
-index f0bb718..da14f20 100644
---- a/nova/tests/test_imagebackend.py
-+++ b/nova/tests/test_imagebackend.py
-@@ -17,6 +17,7 @@
-
- import os
-
-+from nova import exception
- from nova import flags
- from nova import test
- from nova.tests import fake_libvirt_utils
-@@ -190,7 +191,10 @@ class Qcow2TestCase(_ImageTestCase):
- fn = self.prepare_mocks()
- fn(target=self.TEMPLATE_PATH)
- self.mox.StubOutWithMock(os.path, 'exists')
-+ self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
- os.path.exists(self.QCOW2_BASE).AndReturn(False)
-+ imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
-+ ).AndReturn(self.SIZE)
- imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH,
- self.QCOW2_BASE)
- imagebackend.disk.extend(self.QCOW2_BASE, self.SIZE)
-@@ -203,11 +207,25 @@ class Qcow2TestCase(_ImageTestCase):
-
- self.mox.VerifyAll()
-
-+ def test_create_image_too_small(self):
-+ self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
-+ imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
-+ ).AndReturn(self.SIZE)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.assertRaises(exception.ImageTooLarge, image.create_image, None,
-+ self.TEMPLATE_PATH, 1)
-+ self.mox.VerifyAll()
-+
- def test_create_image_with_size_template_exists(self):
- fn = self.prepare_mocks()
- fn(target=self.TEMPLATE_PATH)
- self.mox.StubOutWithMock(os.path, 'exists')
-+ self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
- os.path.exists(self.QCOW2_BASE).AndReturn(True)
-+ imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
-+ ).AndReturn(self.SIZE)
- imagebackend.libvirt_utils.create_cow_image(self.QCOW2_BASE,
- self.PATH)
- self.mox.ReplayAll()
-diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py
-index 0f2f044..5e7023e 100644
---- a/nova/virt/libvirt/imagebackend.py
-+++ b/nova/virt/libvirt/imagebackend.py
-@@ -19,14 +19,17 @@ import abc
- import contextlib
- import os
-
-+from nova import exception
- from nova import flags
- from nova.openstack.common import cfg
- from nova.openstack.common import excutils
-+from nova.openstack.common import log as logging
- from nova import utils
- from nova.virt.disk import api as disk
- from nova.virt.libvirt import config
- from nova.virt.libvirt import utils as libvirt_utils
-
-+
- __imagebackend_opts = [
- cfg.StrOpt('libvirt_images_type',
- default='default',
-@@ -46,6 +49,8 @@ __imagebackend_opts = [
- FLAGS = flags.FLAGS
- FLAGS.register_opts(__imagebackend_opts)
-
-+LOG = logging.getLogger(__name__)
-+
-
- class Image(object):
- __metaclass__ = abc.ABCMeta
-@@ -170,6 +175,13 @@ class Qcow2(Image):
- disk.extend(qcow2_base, size)
- libvirt_utils.create_cow_image(qcow2_base, target)
-
-+ # NOTE(cfb): Having a flavor that sets the root size to 0 and having
-+ # nova effectively ignore that size and use the size of the
-+ # image is considered a feature at this time, not a bug.
-+ if size and size < disk.get_disk_size(base):
-+ LOG.error('%s virtual size larger than flavor root disk size %s' %
-+ (base, size))
-+ raise exception.ImageTooLarge()
- prepare_template(target=base, *args, **kwargs)
- with utils.remove_path_on_error(self.path):
- copy_qcow2_image(base, self.path, size)
---
-1.8.1.5
-
diff --git a/sys-cluster/nova/files/nova-grizzly-1-CVE-2013-2096.patch b/sys-cluster/nova/files/nova-grizzly-1-CVE-2013-2096.patch
deleted file mode 100644
index 5067ca97d77f..000000000000
--- a/sys-cluster/nova/files/nova-grizzly-1-CVE-2013-2096.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From a4fc0c800502338e4530cad910efb64a5483e1ea Mon Sep 17 00:00:00 2001
-From: Chet Burgess <cfb@metacloud.com>
-Date: Thu, 9 May 2013 09:57:28 +0000
-Subject: [PATCH] Check QCOW2 image size during root disk creation
-
-glance can only tell us the size of the file, not the virtual
-size of the QCOW2. As such we need to check the virtual size of
-the image once its cached and ensure it's <= to the flavor's
-root disk size.
-
-Change-Id: I833467284126557eb598b8350a84e10c06292fa9
-Fixes: bug 1177830
-(cherry picked from commit 44a8aba1d5da87d54db48079103fdef946666d80)
----
- nova/tests/test_imagebackend.py | 21 +++++++++++++++++++++
- nova/virt/libvirt/imagebackend.py | 8 ++++++++
- 2 files changed, 29 insertions(+)
-
-diff --git a/nova/tests/test_imagebackend.py b/nova/tests/test_imagebackend.py
-index d571bbf..4ec36da 100644
---- a/nova/tests/test_imagebackend.py
-+++ b/nova/tests/test_imagebackend.py
-@@ -20,6 +20,7 @@ import os
- import fixtures
- from oslo.config import cfg
-
-+from nova import exception
- from nova.openstack.common import uuidutils
- from nova import test
- from nova.tests import fake_libvirt_utils
-@@ -253,9 +254,12 @@ class Qcow2TestCase(_ImageTestCase, test.TestCase):
- fn = self.prepare_mocks()
- fn(target=self.TEMPLATE_PATH)
- self.mox.StubOutWithMock(os.path, 'exists')
-+ self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
- if self.OLD_STYLE_INSTANCE_PATH:
- os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
- os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+ imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
-+ ).AndReturn(self.SIZE)
- os.path.exists(self.PATH).AndReturn(False)
- imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH,
- self.PATH)
-@@ -267,6 +271,23 @@ class Qcow2TestCase(_ImageTestCase, test.TestCase):
-
- self.mox.VerifyAll()
-
-+ def test_create_image_too_small(self):
-+ fn = self.prepare_mocks()
-+ fn(target=self.TEMPLATE_PATH)
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+ imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
-+ ).AndReturn(self.SIZE)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.assertRaises(exception.ImageTooLarge, image.create_image, fn,
-+ self.TEMPLATE_PATH, 1)
-+ self.mox.VerifyAll()
-+
-
- class LvmTestCase(_ImageTestCase, test.TestCase):
- VG = 'FakeVG'
-diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py
-index b6b1b88..2ca71cc 100755
---- a/nova/virt/libvirt/imagebackend.py
-+++ b/nova/virt/libvirt/imagebackend.py
-@@ -21,6 +21,7 @@ import os
-
- from oslo.config import cfg
-
-+from nova import exception
- from nova.openstack.common import excutils
- from nova.openstack.common import fileutils
- from nova.openstack.common import lockutils
-@@ -255,6 +256,13 @@ class Qcow2(Image):
-
- if not os.path.exists(base):
- prepare_template(target=base, *args, **kwargs)
-+ # NOTE(cfb): Having a flavor that sets the root size to 0 and having
-+ # nova effectively ignore that size and use the size of the
-+ # image is considered a feature at this time, not a bug.
-+ if size and size < disk.get_disk_size(base):
-+ LOG.error('%s virtual size larger than flavor root disk size %s' %
-+ (base, size))
-+ raise exception.ImageTooLarge()
- if not os.path.exists(self.path):
- with utils.remove_path_on_error(self.path):
- copy_qcow2_image(base, self.path, size)
---
-1.8.1.5
-
diff --git a/sys-cluster/nova/nova-2013.1.4.ebuild b/sys-cluster/nova/nova-2013.1.4-r1.ebuild
index 8f41ae9724da..e2a1d44941e4 100644
--- a/sys-cluster/nova/nova-2013.1.4.ebuild
+++ b/sys-cluster/nova/nova-2013.1.4-r1.ebuild
@@ -1,6 +1,6 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.1.4.ebuild,v 1.3 2013/11/14 06:54:23 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.1.4-r1.ebuild,v 1.1 2013/11/17 22:35:55 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -70,6 +70,9 @@ RDEPEND=">=dev-python/amqplib-0.6.1[${PYTHON_USEDEP}]
app-emulation/xen-tools )"
PATCHES=(
+ "${FILESDIR}/CVE-2013-4463_4469-grizzly.patch"
+ "${FILESDIR}/CVE-2013-4497-grizzly-1.patch"
+ "${FILESDIR}/CVE-2013-4497-grizzly-2.patch"
)
pkg_setup() {
diff --git a/sys-cluster/nova/nova-2013.2-r1.ebuild b/sys-cluster/nova/nova-2013.2-r2.ebuild
index e0279c6e8ee9..4498e44fccbc 100644
--- a/sys-cluster/nova/nova-2013.2-r1.ebuild
+++ b/sys-cluster/nova/nova-2013.2-r2.ebuild
@@ -1,6 +1,6 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2-r1.ebuild,v 1.2 2013/11/14 06:54:23 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2-r2.ebuild,v 1.1 2013/11/17 22:35:55 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -72,6 +72,7 @@ RDEPEND="sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}]
app-emulation/xen-tools )"
PATCHES=(
+ "${FILESDIR}/CVE-2013-4463_4469-havana.patch"
)
pkg_setup() {