components/openstack/nova/patches/07-CVE-2014-3517.patch
branchs11u2-sru
changeset 3326 030508e3f1bd
equal deleted inserted replaced
3325:a7caf8e15ab7 3326:030508e3f1bd
       
     1 This upstream patch addresses CVE-2014-3517 and is tracked under
       
     2 Launchpad bug 1325128. It is addressed in the Juno trunk, Icehouse
       
     3 2014.1.2, and Havana 2013.2.4. It has been modified to apply cleanly
       
     4 into our current Havana implementation
       
     5 
       
     6 commit 1dd97d1335f6ec028d0e4440250f80802a2f1d18
       
     7 Author: Grant Murphy <[email protected]>
       
     8 Date:   Tue Jul 8 03:35:40 2014 +0000
       
     9 
       
    10     Avoid possible timing attack in metadata api
       
    11     
       
    12     Introduce a constant time comparison function to
       
    13     nova utils for comparing authentication tokens.
       
    14     
       
    15     Conflicts:
       
    16     	nova/tests/test_utils.py
       
    17     	nova/utils.py
       
    18     
       
    19     Closes-bug: #1325128
       
    20     Change-Id: I7374f2edc6f03c7da59cf73ae91a87147e53d0de
       
    21     (cherry picked from commit 9f59ca751f1a392ef24d8ab73a7bf5ce9655017e)
       
    22 
       
    23 diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py
       
    24 index 50387ab..74bb4f7 100644
       
    25 --- a/nova/api/metadata/handler.py
       
    26 +++ b/nova/api/metadata/handler.py
       
    27 @@ -31,6 +31,7 @@ from nova import exception
       
    28  from nova.openstack.common.gettextutils import _
       
    29  from nova.openstack.common import log as logging
       
    30  from nova.openstack.common import memorycache
       
    31 +from nova import utils
       
    32  from nova import wsgi
       
    33  
       
    34  CACHE_EXPIRATION = 15  # in seconds
       
    35 @@ -172,7 +173,7 @@ class MetadataRequestHandler(wsgi.Application):
       
    36              instance_id,
       
    37              hashlib.sha256).hexdigest()
       
    38  
       
    39 -        if expected_signature != signature:
       
    40 +        if not utils.constant_time_compare(expected_signature, signature):
       
    41              if instance_id:
       
    42                  LOG.warn(_('X-Instance-ID-Signature: %(signature)s does not '
       
    43                             'match the expected value: %(expected_signature)s '
       
    44 diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py
       
    45 index b38ea50..820fe09 100644
       
    46 --- a/nova/tests/test_utils.py
       
    47 +++ b/nova/tests/test_utils.py
       
    48 @@ -1083,3 +1083,10 @@ class GetImageFromSystemMetadataTestCase(test.NoDBTestCase):
       
    49  
       
    50          # Verify that the foo1 key has not been inherited
       
    51          self.assertTrue("foo1" not in image)
       
    52 +
       
    53 +
       
    54 +class ConstantTimeCompareTestCase(test.NoDBTestCase):
       
    55 +    def test_constant_time_compare(self):
       
    56 +        self.assertTrue(utils.constant_time_compare("abcd1234", "abcd1234"))
       
    57 +        self.assertFalse(utils.constant_time_compare("abcd1234", "a"))
       
    58 +        self.assertFalse(utils.constant_time_compare("abcd1234", "ABCD234"))
       
    59 diff --git a/nova/utils.py b/nova/utils.py
       
    60 index 4757f3a..5f10a8a 100755
       
    61 --- nova-2013.2.3/nova/utils.py.~2~	2014-09-02 13:57:46.030039835 -0700
       
    62 +++ nova-2013.2.3/nova/utils.py	2014-09-02 13:57:49.391998275 -0700
       
    63 @@ -23,6 +23,7 @@ import contextlib
       
    64  import datetime
       
    65  import functools
       
    66  import hashlib
       
    67 +import hmac
       
    68  import inspect
       
    69  import os
       
    70  import pyclbr
       
    71 @@ -1288,3 +1289,20 @@ def get_boolean(value):
       
    72          return value
       
    73      else:
       
    74          return strutils.bool_from_string(value)
       
    75 +
       
    76 +if hasattr(hmac, 'compare_digest'):
       
    77 +    constant_time_compare = hmac.compare_digest
       
    78 +else:
       
    79 +    def constant_time_compare(first, second):
       
    80 +        """Returns True if both string inputs are equal, otherwise False.
       
    81 +
       
    82 +        This function should take a constant amount of time regardless of
       
    83 +        how many characters in the strings match.
       
    84 +
       
    85 +        """
       
    86 +        if len(first) != len(second):
       
    87 +            return False
       
    88 +        result = 0
       
    89 +        for x, y in zip(first, second):
       
    90 +            result |= ord(x) ^ ord(y)
       
    91 +        return result == 0