components/openstack/nova/patches/08-CVE-2014-3608.patch
branchs11-update
changeset 3357 7181eb4679cd
equal deleted inserted replaced
3356:c52a5c57208c 3357:7181eb4679cd
       
     1 This upstream patch addresses CVE-2014-3608 and is tracked under Launchpad
       
     2 bug 1319182.  It is addressed in Juno 2014.2 and Icehouse 2014.1.3.  It has
       
     3 been modified to apply cleanly into our current Havana implementation.
       
     4 
       
     5 From 8ff170dc95bf3101fe38a2624e941bfa3b7c1138 Mon Sep 17 00:00:00 2001
       
     6 From: "Leandro I. Costantino" <[email protected]>
       
     7 Date: Mon, 19 May 2014 19:58:47 -0300
       
     8 Subject: [PATCH] VM in rescue state must have a restricted set of actions
       
     9 
       
    10 Right now it is possible to pause, suspend and stop a VM in state RESCUED,
       
    11 so after the state is changed, it's not possible to trigger unrescue anymore
       
    12 since the original state is lost.
       
    13 
       
    14 This patch remove vm_states.RESCUED as valid state from stop,
       
    15 pause and suspend actions.
       
    16 
       
    17 The vm_states devref is also updated to reflect this change including the
       
    18 current reboot flow.( vm_states.RESCUED cannot be rebooted as per
       
    19 today code)
       
    20 
       
    21 DocImpact
       
    22 Closes-Bug: #1319182
       
    23 Co-Authored-By: Cyril Roelandt <[email protected]>
       
    24 Change-Id: I531dea5a5499bf93c24bea37850d562134dee281
       
    25 ---
       
    26  doc/source/devref/vmstates.rst         |  7 ++++--
       
    27  nova/compute/api.py                    |  7 +++---
       
    28  nova/tests/compute/test_compute_api.py | 46 ++++++++++++++++++++++++++++++++--
       
    29  3 files changed, 52 insertions(+), 8 deletions(-)
       
    30 
       
    31 --- nova-2013.2.3/doc/source/devref/vmstates.rst	2014-04-03 11:49:38.000000000 -0700
       
    32 +++ nova-2013.2.3/doc/source/devref/vmstates.rst	2014-09-29 10:32:35.921504377 -0700
       
    33 @@ -88,6 +88,7 @@
       
    34      rescue -> error
       
    35      active -> rescue
       
    36      stopped -> rescue
       
    37 +    error -> rescue
       
    38  
       
    39      unrescue [shape="rectangle"]
       
    40      unrescue -> active
       
    41 @@ -139,7 +140,9 @@
       
    42      reboot -> error
       
    43      active -> reboot
       
    44      stopped -> reboot
       
    45 -    rescued -> reboot
       
    46 +    paused -> reboot
       
    47 +    suspended -> reboot
       
    48 +    error -> reboot
       
    49  
       
    50      live_migrate [shape="rectangle"]
       
    51      live_migrate -> active
       
    52 @@ -159,4 +162,4 @@
       
    53  power states when a new VM instance is created.
       
    54  
       
    55  
       
    56 -.. image:: /images/run_instance_walkthrough.png
       
    57 \ No newline at end of file
       
    58 +.. image:: /images/run_instance_walkthrough.png
       
    59 --- nova-2013.2.3/nova/compute/api.py	2014-04-03 11:49:46.000000000 -0700
       
    60 +++ nova-2013.2.3/nova/compute/api.py	2014-09-29 10:32:50.868945930 -0700
       
    61 @@ -1619,8 +1619,7 @@
       
    62      @check_instance_lock
       
    63      @check_instance_host
       
    64      @check_instance_cell
       
    65 -    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED,
       
    66 -                                    vm_states.ERROR],
       
    67 +    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED],
       
    68                            task_state=[None])
       
    69      def stop(self, context, instance, do_cast=True):
       
    70          """Stop an instance."""
       
    71 @@ -2429,7 +2428,7 @@
       
    72      @wrap_check_policy
       
    73      @check_instance_lock
       
    74      @check_instance_cell
       
    75 -    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED])
       
    76 +    @check_instance_state(vm_state=[vm_states.ACTIVE])
       
    77      def pause(self, context, instance):
       
    78          """Pause the given instance."""
       
    79          instance.task_state = task_states.PAUSING
       
    80 @@ -2456,7 +2455,7 @@
       
    81      @wrap_check_policy
       
    82      @check_instance_lock
       
    83      @check_instance_cell
       
    84 -    @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED])
       
    85 +    @check_instance_state(vm_state=[vm_states.ACTIVE])
       
    86      def suspend(self, context, instance):
       
    87          """Suspend the given instance."""
       
    88          instance.task_state = task_states.SUSPENDING
       
    89 --- nova-2013.2.3/nova/tests/compute/test_compute_api.py	2014-04-03 11:49:46.000000000 -0700
       
    90 +++ nova-2013.2.3/nova/tests/compute/test_compute_api.py	2014-09-29 10:32:35.926521781 -0700
       
    91 @@ -56,6 +56,16 @@
       
    92          self.context = context.RequestContext(self.user_id,
       
    93                                                self.project_id)
       
    94  
       
    95 +    def _get_vm_states(self, exclude_states=None):
       
    96 +        vm_state = set([vm_states.ACTIVE, vm_states.BUILDING, vm_states.PAUSED,
       
    97 +                    vm_states.SUSPENDED, vm_states.RESCUED, vm_states.STOPPED,
       
    98 +                    vm_states.RESIZED, vm_states.SOFT_DELETED,
       
    99 +                    vm_states.DELETED, vm_states.ERROR, vm_states.SHELVED,
       
   100 +                    vm_states.SHELVED_OFFLOADED])
       
   101 +        if not exclude_states:
       
   102 +            exclude_states = set()
       
   103 +        return vm_state - exclude_states
       
   104 +
       
   105      def _create_flavor(self, params=None):
       
   106          flavor = {'id': 1,
       
   107                    'flavorid': 1,
       
   108 @@ -193,6 +203,19 @@
       
   109          self.assertEqual(task_states.SUSPENDING,
       
   110                           instance.task_state)
       
   111  
       
   112 +    def _test_suspend_fails(self, vm_state):
       
   113 +        params = dict(vm_state=vm_state)
       
   114 +        instance = self._create_instance_obj(params=params)
       
   115 +        self.assertIsNone(instance.task_state)
       
   116 +        self.assertRaises(exception.InstanceInvalidState,
       
   117 +                          self.compute_api.suspend,
       
   118 +                          self.context, instance)
       
   119 +
       
   120 +    def test_suspend_fails_invalid_states(self):
       
   121 +        invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE]))
       
   122 +        for state in invalid_vm_states:
       
   123 +            self._test_suspend_fails(state)
       
   124 +
       
   125      def test_resume(self):
       
   126          # Ensure instance can be resumed (if suspended).
       
   127          instance = self._create_instance_obj(
       
   128 @@ -298,13 +321,19 @@
       
   129      def test_stop_stopped_instance_with_bypass(self):
       
   130          self._test_stop(vm_states.STOPPED, force=True)
       
   131  
       
   132 -    def test_stop_invalid_state(self):
       
   133 -        params = dict(vm_state=vm_states.PAUSED)
       
   134 +    def _test_stop_invalid_state(self, vm_state):
       
   135 +        params = dict(vm_state=vm_state)
       
   136          instance = self._create_instance_obj(params=params)
       
   137          self.assertRaises(exception.InstanceInvalidState,
       
   138                            self.compute_api.stop,
       
   139                            self.context, instance)
       
   140  
       
   141 +    def test_stop_fails_invalid_states(self):
       
   142 +        invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE,
       
   143 +                                                     vm_states.ERROR]))
       
   144 +        for state in invalid_vm_states:
       
   145 +            self._test_stop_invalid_state(state)
       
   146 +
       
   147      def test_stop_a_stopped_inst(self):
       
   148          params = {'vm_state': vm_states.STOPPED}
       
   149          instance = self._create_instance_obj(params=params)
       
   150 @@ -1075,6 +1104,19 @@
       
   151          self.assertEqual(task_states.PAUSING,
       
   152                           instance.task_state)
       
   153  
       
   154 +    def _test_pause_fails(self, vm_state):
       
   155 +        params = dict(vm_state=vm_state)
       
   156 +        instance = self._create_instance_obj(params=params)
       
   157 +        self.assertIsNone(instance.task_state)
       
   158 +        self.assertRaises(exception.InstanceInvalidState,
       
   159 +                          self.compute_api.pause,
       
   160 +                          self.context, instance)
       
   161 +
       
   162 +    def test_pause_fails_invalid_states(self):
       
   163 +        invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE]))
       
   164 +        for state in invalid_vm_states:
       
   165 +            self._test_pause_fails(state)
       
   166 +
       
   167      def test_unpause(self):
       
   168          # Ensure instance can be unpaused.
       
   169          params = dict(vm_state=vm_states.PAUSED)