summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Thode <prometheanfire@gentoo.org>2013-12-19 03:18:20 +0000
committerMatthew Thode <prometheanfire@gentoo.org>2013-12-19 03:18:20 +0000
commitd035941f830b65b294370ca5c7341517e48231b2 (patch)
treea4eb435f668d5a02e4cc029263feacd886a15bb2 /sys-cluster
parentRemove old. (diff)
downloadgentoo-2-d035941f830b65b294370ca5c7341517e48231b2.tar.gz
gentoo-2-d035941f830b65b294370ca5c7341517e48231b2.tar.bz2
gentoo-2-d035941f830b65b294370ca5c7341517e48231b2.zip
update for CVE-2013-2096
(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/ChangeLog9
-rw-r--r--sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch452
-rw-r--r--sys-cluster/nova/files/CVE-2013-6419_2013.2.patch186
-rw-r--r--sys-cluster/nova/nova-2013.2.1.ebuild126
-rw-r--r--sys-cluster/nova/nova-2013.2.9999.ebuild6
5 files changed, 137 insertions, 642 deletions
diff --git a/sys-cluster/nova/ChangeLog b/sys-cluster/nova/ChangeLog
index af13d2e11ea1..f889d7a7ab01 100644
--- a/sys-cluster/nova/ChangeLog
+++ b/sys-cluster/nova/ChangeLog
@@ -1,6 +1,13 @@
# 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.44 2013/12/13 21:10:35 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.45 2013/12/19 03:18:19 prometheanfire Exp $
+
+*nova-2013.2.1 (19 Dec 2013)
+
+ 19 Dec 2013; Matthew Thode <prometheanfire@gentoo.org> +nova-2013.2.1.ebuild,
+ -files/CVE-2013-4463_4469-havana.patch, -files/CVE-2013-6419_2013.2.patch,
+ nova-2013.2.9999.ebuild:
+ update for CVE-2013-2096
*nova-2013.2-r3 (13 Dec 2013)
*nova-2013.1.4-r2 (13 Dec 2013)
diff --git a/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch b/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch
deleted file mode 100644
index 575b11d9bbdf..000000000000
--- a/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch
+++ /dev/null
@@ -1,452 +0,0 @@
-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-6419_2013.2.patch b/sys-cluster/nova/files/CVE-2013-6419_2013.2.patch
deleted file mode 100644
index 1dcfe1b9b68f..000000000000
--- a/sys-cluster/nova/files/CVE-2013-6419_2013.2.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-commit 2a95eee992b66cd65e401e31785c080f811476cf
-Author: Aaron Rosen <arosen@nicira.com>
-Date: Mon Oct 7 13:33:31 2013 -0700
-
- Prevent spoofing instance_id from neturon to nova
-
- Previously, one could update a port's device_id in neutron to be that
- of another tenant's instance_id and then be able to retrieve that instance's
- metadata. This patch prevents this from occuring by checking that X-Tenant-ID
- received from the metadata request matches the tenant_id in the nova database.
-
- DocImpact - This patch is dependent on another patch in neutron which adds
- X-Tenant-ID to the request. Therefore to minimize downtime one
- should upgrade Neutron first (then restart neutron-metadata-agent)
- and lastly update nova.
-
- Fixes bug: 1235450
-
-diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py
-index 27f4d4e..7ac9023 100644
---- a/nova/api/metadata/handler.py
-+++ b/nova/api/metadata/handler.py
-@@ -140,29 +140,34 @@ class MetadataRequestHandler(wsgi.Application):
- 'Please try your request again.')
- raise webob.exc.HTTPInternalServerError(explanation=unicode(msg))
-
- if meta_data is None:
- LOG.error(_('Failed to get metadata for ip: %s'), remote_address)
-
- return meta_data
-
- def _handle_instance_id_request(self, req):
- instance_id = req.headers.get('X-Instance-ID')
-+ tenant_id = req.headers.get('X-Tenant-ID')
- signature = req.headers.get('X-Instance-ID-Signature')
- remote_address = req.headers.get('X-Forwarded-For')
-
- # Ensure that only one header was passed
-
- if instance_id is None:
- msg = _('X-Instance-ID header is missing from request.')
-+ elif tenant_id is None:
-+ msg = _('X-Tenant-ID header is missing from request.')
- elif not isinstance(instance_id, basestring):
- msg = _('Multiple X-Instance-ID headers found within request.')
-+ elif not isinstance(tenant_id, basestring):
-+ msg = _('Multiple X-Tenant-ID headers found within request.')
- else:
- msg = None
-
- if msg:
- raise webob.exc.HTTPBadRequest(explanation=msg)
-
- expected_signature = hmac.new(
- CONF.neutron_metadata_proxy_shared_secret,
- instance_id,
- hashlib.sha256).hexdigest()
-@@ -188,11 +193,19 @@ class MetadataRequestHandler(wsgi.Application):
- LOG.exception(_('Failed to get metadata for instance id: %s'),
- instance_id)
- msg = _('An unknown error has occurred. '
- 'Please try your request again.')
- raise webob.exc.HTTPInternalServerError(explanation=unicode(msg))
-
- if meta_data is None:
- LOG.error(_('Failed to get metadata for instance id: %s'),
- instance_id)
-
-+ if meta_data.instance['project_id'] != tenant_id:
-+ LOG.warning(_("Tenant_id %(tenant_id)s does not match tenant_id "
-+ "of instance %(instance_id)s."),
-+ {'tenant_id': tenant_id,
-+ 'instance_id': instance_id})
-+ # causes a 404 to be raised
-+ meta_data = None
-+
- return meta_data
-diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py
-index 50f0d07..e75b51f 100644
---- a/nova/tests/test_metadata.py
-+++ b/nova/tests/test_metadata.py
-@@ -594,74 +594,104 @@ class MetadataHandlerTestCase(test.TestCase):
- CONF.neutron_metadata_proxy_shared_secret,
- expected_instance_id,
- hashlib.sha256).hexdigest()
-
- # try a request with service disabled
- response = fake_request(
- self.stubs, self.mdinst,
- relpath="/2009-04-04/user-data",
- address="192.192.192.2",
- headers={'X-Instance-ID': 'a-b-c-d',
-+ 'X-Tenant-ID': 'test',
- 'X-Instance-ID-Signature': signed})
- self.assertEqual(response.status_int, 200)
-
- # now enable the service
- self.flags(service_neutron_metadata_proxy=True)
- response = fake_request(
- self.stubs, self.mdinst,
- relpath="/2009-04-04/user-data",
- address="192.192.192.2",
- fake_get_metadata_by_instance_id=fake_get_metadata,
- headers={'X-Forwarded-For': '192.192.192.2',
- 'X-Instance-ID': 'a-b-c-d',
-+ 'X-Tenant-ID': 'test',
- 'X-Instance-ID-Signature': signed})
-
- self.assertEqual(response.status_int, 200)
- self.assertEqual(response.body,
- base64.b64decode(self.instance['user_data']))
-
- # mismatched signature
- response = fake_request(
- self.stubs, self.mdinst,
- relpath="/2009-04-04/user-data",
- address="192.192.192.2",
- fake_get_metadata_by_instance_id=fake_get_metadata,
- headers={'X-Forwarded-For': '192.192.192.2',
- 'X-Instance-ID': 'a-b-c-d',
-+ 'X-Tenant-ID': 'test',
- 'X-Instance-ID-Signature': ''})
-
- self.assertEqual(response.status_int, 403)
-
-+ # missing X-Tenant-ID from request
-+ response = fake_request(
-+ self.stubs, self.mdinst,
-+ relpath="/2009-04-04/user-data",
-+ address="192.192.192.2",
-+ fake_get_metadata_by_instance_id=fake_get_metadata,
-+ headers={'X-Forwarded-For': '192.192.192.2',
-+ 'X-Instance-ID': 'a-b-c-d',
-+ 'X-Instance-ID-Signature': signed})
-+
-+ self.assertEqual(response.status_int, 400)
-+
-+ # mismatched X-Tenant-ID
-+ response = fake_request(
-+ self.stubs, self.mdinst,
-+ relpath="/2009-04-04/user-data",
-+ address="192.192.192.2",
-+ fake_get_metadata_by_instance_id=fake_get_metadata,
-+ headers={'X-Forwarded-For': '192.192.192.2',
-+ 'X-Instance-ID': 'a-b-c-d',
-+ 'X-Tenant-ID': 'FAKE',
-+ 'X-Instance-ID-Signature': signed})
-+
-+ self.assertEqual(response.status_int, 404)
-+
- # without X-Forwarded-For
- response = fake_request(
- self.stubs, self.mdinst,
- relpath="/2009-04-04/user-data",
- address="192.192.192.2",
- fake_get_metadata_by_instance_id=fake_get_metadata,
- headers={'X-Instance-ID': 'a-b-c-d',
-+ 'X-Tenant-ID': 'test',
- 'X-Instance-ID-Signature': signed})
-
- self.assertEqual(response.status_int, 500)
-
- # unexpected Instance-ID
- signed = hmac.new(
- CONF.neutron_metadata_proxy_shared_secret,
- 'z-z-z-z',
- hashlib.sha256).hexdigest()
-
- response = fake_request(
- self.stubs, self.mdinst,
- relpath="/2009-04-04/user-data",
- address="192.192.192.2",
- fake_get_metadata_by_instance_id=fake_get_metadata,
- headers={'X-Forwarded-For': '192.192.192.2',
- 'X-Instance-ID': 'z-z-z-z',
-+ 'X-Tenant-ID': 'test',
- 'X-Instance-ID-Signature': signed})
- self.assertEqual(response.status_int, 500)
-
-
- class MetadataPasswordTestCase(test.TestCase):
- def setUp(self):
- super(MetadataPasswordTestCase, self).setUp()
- fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs)
- self.instance = copy.copy(INSTANCES[0])
- self.instance['system_metadata'] = get_default_sys_meta()
diff --git a/sys-cluster/nova/nova-2013.2.1.ebuild b/sys-cluster/nova/nova-2013.2.1.ebuild
new file mode 100644
index 000000000000..bd9f21fda68e
--- /dev/null
+++ b/sys-cluster/nova/nova-2013.2.1.ebuild
@@ -0,0 +1,126 @@
+# 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.1.ebuild,v 1.1 2013/12/19 03:18:19 prometheanfire Exp $
+
+EAPI=5
+PYTHON_COMPAT=( python2_7 )
+
+inherit distutils-r1 eutils multilib
+
+DESCRIPTION="A cloud computing fabric controller (main part of an IaaS system) written in Python."
+HOMEPAGE="https://launchpad.net/nova"
+SRC_URI="http://launchpad.net/${PN}/havana/${PV}/+download/${P}.tar.gz"
+
+LICENSE="Apache-2.0"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE="+api +cert +compute +conductor +consoleauth +kvm +network +novncproxy +scheduler +spicehtml5proxy +xvpvncproxy sqlite mysql postgres xen"
+REQUIRED_USE="|| ( mysql postgres sqlite )
+ || ( kvm xen )"
+
+DEPEND="dev-python/setuptools[${PYTHON_USEDEP}]
+ >=dev-python/pbr-0.5.21[${PYTHON_USEDEP}]
+ <dev-python/pbr-1.0[${PYTHON_USEDEP}]
+ app-admin/sudo"
+
+RDEPEND="sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}]
+ <dev-python/sqlalchemy-0.7.99[sqlite,${PYTHON_USEDEP}] )
+ mysql? ( >=dev-python/sqlalchemy-0.7.8[mysql,${PYTHON_USEDEP}]
+ <dev-python/sqlalchemy-0.7.99[mysql,${PYTHON_USEDEP}] )
+ postgres? ( >=dev-python/sqlalchemy-0.7.8[postgres,${PYTHON_USEDEP}]
+ <dev-python/sqlalchemy-0.7.99[postgres,${PYTHON_USEDEP}] )
+ >=dev-python/amqplib-0.6.1[${PYTHON_USEDEP}]
+ >=dev-python/anyjson-0.3.3[${PYTHON_USEDEP}]
+ virtual/python-argparse[${PYTHON_USEDEP}]
+ >=dev-python/boto-2.4.0[${PYTHON_USEDEP}]
+ !~dev-python/boto-2.13.0[${PYTHON_USEDEP}]
+ >=dev-python/eventlet-0.13.0[${PYTHON_USEDEP}]
+ dev-python/jinja[${PYTHON_USEDEP}]
+ >=dev-python/kombu-2.4.8[${PYTHON_USEDEP}]
+ >=dev-python/lxml-2.3[${PYTHON_USEDEP}]
+ >=dev-python/routes-1.12.3-r1[${PYTHON_USEDEP}]
+ >=dev-python/webob-1.2.3[${PYTHON_USEDEP}]
+ <dev-python/webob-1.3[${PYTHON_USEDEP}]
+ >=dev-python/greenlet-0.3.2[${PYTHON_USEDEP}]
+ >=dev-python/pastedeploy-1.5.0-r1[${PYTHON_USEDEP}]
+ dev-python/paste[${PYTHON_USEDEP}]
+ >=dev-python/sqlalchemy-migrate-0.7.2[${PYTHON_USEDEP}]
+ dev-python/netaddr[${PYTHON_USEDEP}]
+ >=dev-python/suds-0.4[${PYTHON_USEDEP}]
+ >=dev-python/paramiko-1.8.0[${PYTHON_USEDEP}]
+ dev-python/pyasn1[${PYTHON_USEDEP}]
+ >=dev-python/Babel-1.3[${PYTHON_USEDEP}]
+ >=dev-python/iso8601-0.1.8[${PYTHON_USEDEP}]
+ >=dev-python/python-cinderclient-1.0.5[${PYTHON_USEDEP}]
+ >=dev-python/python-neutronclient-2.3.0[${PYTHON_USEDEP}]
+ <=dev-python/python-neutronclient-3.0.0[${PYTHON_USEDEP}]
+ >=dev-python/python-glanceclient-0.9.0[${PYTHON_USEDEP}]
+ >=dev-python/python-keystoneclient-0.3.2[${PYTHON_USEDEP}]
+ >=dev-python/stevedore-0.10[${PYTHON_USEDEP}]
+ >=dev-python/websockify-0.5.1[${PYTHON_USEDEP}]
+ <dev-python/websockify-0.6[${PYTHON_USEDEP}]
+ >=dev-python/oslo-config-1.2.0[${PYTHON_USEDEP}]
+ dev-python/libvirt-python[${PYTHON_USEDEP}]
+ novncproxy? ( www-apps/novnc )
+ sys-apps/iproute2
+ net-misc/openvswitch
+ sys-fs/sysfsutils
+ sys-fs/multipath-tools
+ kvm? ( app-emulation/qemu )
+ xen? ( app-emulation/xen
+ app-emulation/xen-tools )"
+
+PATCHES=(
+)
+
+pkg_setup() {
+ enewgroup nova
+ enewuser nova -1 -1 /var/lib/nova nova
+}
+
+python_install() {
+ distutils-r1_python_install
+ newconfd "${FILESDIR}/nova-confd" "nova"
+ newinitd "${FILESDIR}/nova-initd" "nova"
+ use api && dosym /etc/init.d/nova /etc/init.d/nova-api
+ use cert && dosym /etc/init.d/nova /etc/init.d/nova-cert
+ use compute && dosym /etc/init.d/nova /etc/init.d/nova-compute
+ use conductor && dosym /etc/init.d/nova /etc/init.d/nova-conductor
+ use consoleauth && dosym /etc/init.d/nova /etc/init.d/nova-consoleauth
+ use network && dosym /etc/init.d/nova /etc/init.d/nova-network
+ use novncproxy &&dosym /etc/init.d/nova /etc/init.d/nova-novncproxy
+ use scheduler && dosym /etc/init.d/nova /etc/init.d/nova-scheduler
+ use spicehtml5proxy && dosym /etc/init.d/nova /etc/init.d/nova-spicehtml5proxy
+ use xvpvncproxy && dosym /etc/init.d/nova /etc/init.d/nova-xvpncproxy
+
+ diropts -m 0750
+ dodir /var/run/nova /var/log/nova /var/lock/nova
+ fowners nova:nova /var/log/nova /var/lock/nova /var/run/nova
+
+ diropts -m 0755
+ dodir /var/lib/nova/instances
+ fowners nova:nova /var/lib/nova/instances
+
+ keepdir /etc/nova
+ insinto /etc/nova
+ newins "etc/nova/nova.conf.sample" "nova.conf"
+ doins "etc/nova/api-paste.ini"
+ doins "etc/nova/logging_sample.conf"
+ doins "etc/nova/policy.json"
+ doins "etc/nova/rootwrap.conf"
+ insinto /etc/nova/rootwrap.d
+ doins "etc/nova/rootwrap.d/api-metadata.filters"
+ doins "etc/nova/rootwrap.d/compute.filters"
+ doins "etc/nova/rootwrap.d/network.filters"
+
+ #copy migration conf file (not coppied on install via setup.py script)
+ insinto /usr/$(get_libdir)/python2.7/site-packages/nova/db/sqlalchemy/migrate_repo/
+ doins "nova/db/sqlalchemy/migrate_repo/migrate.cfg"
+
+ #copy the CA cert dir (not coppied on install via setup.py script)
+ cp -R "${S}/nova/CA" "${D}/usr/$(get_libdir)/python2.7/site-packages/nova/" || die "isntalling CA files failed"
+
+ #add sudoers definitions for user nova
+ insinto /etc/sudoers.d/
+ doins "${FILESDIR}/nova-sudoers"
+}
diff --git a/sys-cluster/nova/nova-2013.2.9999.ebuild b/sys-cluster/nova/nova-2013.2.9999.ebuild
index d9a76c3f19c6..fdd850c93456 100644
--- a/sys-cluster/nova/nova-2013.2.9999.ebuild
+++ b/sys-cluster/nova/nova-2013.2.9999.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.9999.ebuild,v 1.8 2013/12/03 20:14:39 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2.9999.ebuild,v 1.9 2013/12/19 03:18:19 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -50,8 +50,8 @@ RDEPEND="sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}]
>=dev-python/suds-0.4[${PYTHON_USEDEP}]
>=dev-python/paramiko-1.8.0[${PYTHON_USEDEP}]
dev-python/pyasn1[${PYTHON_USEDEP}]
- >=dev-python/Babel-0.9.6[${PYTHON_USEDEP}]
- >=dev-python/iso8601-0.1.4[${PYTHON_USEDEP}]
+ >=dev-python/Babel-1.3[${PYTHON_USEDEP}]
+ >=dev-python/iso8601-0.1.8[${PYTHON_USEDEP}]
>=dev-python/python-cinderclient-1.0.5[${PYTHON_USEDEP}]
>=dev-python/python-neutronclient-2.3.0[${PYTHON_USEDEP}]
<=dev-python/python-neutronclient-3.0.0[${PYTHON_USEDEP}]