19715056 problem in SERVICE/NOVA
authorDanek Duvall <danek.duvall@oracle.com>
Tue, 30 Sep 2014 13:39:00 -0700
changeset 2127 9574188edd5d
parent 2126 ed5bd3655098
child 2128 ea2364416471
19715056 problem in SERVICE/NOVA
components/openstack/nova/patches/08-CVE-2014-3608.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openstack/nova/patches/08-CVE-2014-3608.patch	Tue Sep 30 13:39:00 2014 -0700
@@ -0,0 +1,169 @@
+This upstream patch addresses CVE-2014-3608 and is tracked under Launchpad
+bug 1319182.  It is addressed in Juno 2014.2 and Icehouse 2014.1.3.  It has
+been modified to apply cleanly into our current Havana implementation.
+
+From 8ff170dc95bf3101fe38a2624e941bfa3b7c1138 Mon Sep 17 00:00:00 2001
+From: "Leandro I. Costantino" <[email protected]>
+Date: Mon, 19 May 2014 19:58:47 -0300
+Subject: [PATCH] VM in rescue state must have a restricted set of actions
+
+Right now it is possible to pause, suspend and stop a VM in state RESCUED,
+so after the state is changed, it's not possible to trigger unrescue anymore
+since the original state is lost.
+
+This patch remove vm_states.RESCUED as valid state from stop,
+pause and suspend actions.
+
+The vm_states devref is also updated to reflect this change including the
+current reboot flow.( vm_states.RESCUED cannot be rebooted as per
+today code)
+
+DocImpact
+Closes-Bug: #1319182
+Co-Authored-By: Cyril Roelandt <[email protected]>
+Change-Id: I531dea5a5499bf93c24bea37850d562134dee281
+---
+ doc/source/devref/vmstates.rst         |  7 ++++--
+ nova/compute/api.py                    |  7 +++---
+ nova/tests/compute/test_compute_api.py | 46 ++++++++++++++++++++++++++++++++--
+ 3 files changed, 52 insertions(+), 8 deletions(-)
+
+--- nova-2013.2.3/doc/source/devref/vmstates.rst	2014-04-03 11:49:38.000000000 -0700
++++ nova-2013.2.3/doc/source/devref/vmstates.rst	2014-09-29 10:32:35.921504377 -0700
[email protected]@ -88,6 +88,7 @@
+     rescue -> error
+     active -> rescue
+     stopped -> rescue
++    error -> rescue
+ 
+     unrescue [shape="rectangle"]
+     unrescue -> active
[email protected]@ -139,7 +140,9 @@
+     reboot -> error
+     active -> reboot
+     stopped -> reboot
+-    rescued -> reboot
++    paused -> reboot
++    suspended -> reboot
++    error -> reboot
+ 
+     live_migrate [shape="rectangle"]
+     live_migrate -> active
[email protected]@ -159,4 +162,4 @@
+ power states when a new VM instance is created.
+ 
+ 
+-.. image:: /images/run_instance_walkthrough.png
+\ No newline at end of file
++.. image:: /images/run_instance_walkthrough.png
+--- nova-2013.2.3/nova/compute/api.py	2014-04-03 11:49:46.000000000 -0700
++++ nova-2013.2.3/nova/compute/api.py	2014-09-29 10:32:50.868945930 -0700
[email protected]@ -1619,8 +1619,7 @@
+     @check_instance_lock
+     @check_instance_host
+     @check_instance_cell
+-    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED,
+-                                    vm_states.ERROR],
++    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED],
+                           task_state=[None])
+     def stop(self, context, instance, do_cast=True):
+         """Stop an instance."""
[email protected]@ -2429,7 +2428,7 @@
+     @wrap_check_policy
+     @check_instance_lock
+     @check_instance_cell
+-    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED])
++    @check_instance_state(vm_state=[vm_states.ACTIVE])
+     def pause(self, context, instance):
+         """Pause the given instance."""
+         instance.task_state = task_states.PAUSING
[email protected]@ -2456,7 +2455,7 @@
+     @wrap_check_policy
+     @check_instance_lock
+     @check_instance_cell
+-    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED])
++    @check_instance_state(vm_state=[vm_states.ACTIVE])
+     def suspend(self, context, instance):
+         """Suspend the given instance."""
+         instance.task_state = task_states.SUSPENDING
+--- nova-2013.2.3/nova/tests/compute/test_compute_api.py	2014-04-03 11:49:46.000000000 -0700
++++ nova-2013.2.3/nova/tests/compute/test_compute_api.py	2014-09-29 10:32:35.926521781 -0700
[email protected]@ -56,6 +56,16 @@
+         self.context = context.RequestContext(self.user_id,
+                                               self.project_id)
+ 
++    def _get_vm_states(self, exclude_states=None):
++        vm_state = set([vm_states.ACTIVE, vm_states.BUILDING, vm_states.PAUSED,
++                    vm_states.SUSPENDED, vm_states.RESCUED, vm_states.STOPPED,
++                    vm_states.RESIZED, vm_states.SOFT_DELETED,
++                    vm_states.DELETED, vm_states.ERROR, vm_states.SHELVED,
++                    vm_states.SHELVED_OFFLOADED])
++        if not exclude_states:
++            exclude_states = set()
++        return vm_state - exclude_states
++
+     def _create_flavor(self, params=None):
+         flavor = {'id': 1,
+                   'flavorid': 1,
[email protected]@ -193,6 +203,19 @@
+         self.assertEqual(task_states.SUSPENDING,
+                          instance.task_state)
+ 
++    def _test_suspend_fails(self, vm_state):
++        params = dict(vm_state=vm_state)
++        instance = self._create_instance_obj(params=params)
++        self.assertIsNone(instance.task_state)
++        self.assertRaises(exception.InstanceInvalidState,
++                          self.compute_api.suspend,
++                          self.context, instance)
++
++    def test_suspend_fails_invalid_states(self):
++        invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE]))
++        for state in invalid_vm_states:
++            self._test_suspend_fails(state)
++
+     def test_resume(self):
+         # Ensure instance can be resumed (if suspended).
+         instance = self._create_instance_obj(
[email protected]@ -298,13 +321,19 @@
+     def test_stop_stopped_instance_with_bypass(self):
+         self._test_stop(vm_states.STOPPED, force=True)
+ 
+-    def test_stop_invalid_state(self):
+-        params = dict(vm_state=vm_states.PAUSED)
++    def _test_stop_invalid_state(self, vm_state):
++        params = dict(vm_state=vm_state)
+         instance = self._create_instance_obj(params=params)
+         self.assertRaises(exception.InstanceInvalidState,
+                           self.compute_api.stop,
+                           self.context, instance)
+ 
++    def test_stop_fails_invalid_states(self):
++        invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE,
++                                                     vm_states.ERROR]))
++        for state in invalid_vm_states:
++            self._test_stop_invalid_state(state)
++
+     def test_stop_a_stopped_inst(self):
+         params = {'vm_state': vm_states.STOPPED}
+         instance = self._create_instance_obj(params=params)
[email protected]@ -1075,6 +1104,19 @@
+         self.assertEqual(task_states.PAUSING,
+                          instance.task_state)
+ 
++    def _test_pause_fails(self, vm_state):
++        params = dict(vm_state=vm_state)
++        instance = self._create_instance_obj(params=params)
++        self.assertIsNone(instance.task_state)
++        self.assertRaises(exception.InstanceInvalidState,
++                          self.compute_api.pause,
++                          self.context, instance)
++
++    def test_pause_fails_invalid_states(self):
++        invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE]))
++        for state in invalid_vm_states:
++            self._test_pause_fails(state)
++
+     def test_unpause(self):
+         # Ensure instance can be unpaused.
+         params = dict(vm_state=vm_states.PAUSED)