diff -r b4b74d363c31 -r a725bbd5dea1 components/openstack/nova/patches/07-CVE-2014-3517.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/openstack/nova/patches/07-CVE-2014-3517.patch Tue Sep 23 11:18:31 2014 -0700 @@ -0,0 +1,91 @@ +This upstream patch addresses CVE-2014-3517 and is tracked under +Launchpad bug 1325128. It is addressed in the Juno trunk, Icehouse +2014.1.2, and Havana 2013.2.4. It has been modified to apply cleanly +into our current Havana implementation + +commit 1dd97d1335f6ec028d0e4440250f80802a2f1d18 +Author: Grant Murphy +Date: Tue Jul 8 03:35:40 2014 +0000 + + Avoid possible timing attack in metadata api + + Introduce a constant time comparison function to + nova utils for comparing authentication tokens. + + Conflicts: + nova/tests/test_utils.py + nova/utils.py + + Closes-bug: #1325128 + Change-Id: I7374f2edc6f03c7da59cf73ae91a87147e53d0de + (cherry picked from commit 9f59ca751f1a392ef24d8ab73a7bf5ce9655017e) + +diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py +index 50387ab..74bb4f7 100644 +--- a/nova/api/metadata/handler.py ++++ b/nova/api/metadata/handler.py +@@ -31,6 +31,7 @@ from nova import exception + from nova.openstack.common.gettextutils import _ + from nova.openstack.common import log as logging + from nova.openstack.common import memorycache ++from nova import utils + from nova import wsgi + + CACHE_EXPIRATION = 15 # in seconds +@@ -172,7 +173,7 @@ class MetadataRequestHandler(wsgi.Application): + instance_id, + hashlib.sha256).hexdigest() + +- if expected_signature != signature: ++ if not utils.constant_time_compare(expected_signature, signature): + if instance_id: + LOG.warn(_('X-Instance-ID-Signature: %(signature)s does not ' + 'match the expected value: %(expected_signature)s ' +diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py +index b38ea50..820fe09 100644 +--- a/nova/tests/test_utils.py ++++ b/nova/tests/test_utils.py +@@ -1083,3 +1083,10 @@ class GetImageFromSystemMetadataTestCase(test.NoDBTestCase): + + # Verify that the foo1 key has not been inherited + self.assertTrue("foo1" not in image) ++ ++ ++class ConstantTimeCompareTestCase(test.NoDBTestCase): ++ def test_constant_time_compare(self): ++ self.assertTrue(utils.constant_time_compare("abcd1234", "abcd1234")) ++ self.assertFalse(utils.constant_time_compare("abcd1234", "a")) ++ self.assertFalse(utils.constant_time_compare("abcd1234", "ABCD234")) +diff --git a/nova/utils.py b/nova/utils.py +index 4757f3a..5f10a8a 100755 +--- nova-2013.2.3/nova/utils.py.~2~ 2014-09-02 13:57:46.030039835 -0700 ++++ nova-2013.2.3/nova/utils.py 2014-09-02 13:57:49.391998275 -0700 +@@ -23,6 +23,7 @@ import contextlib + import datetime + import functools + import hashlib ++import hmac + import inspect + import os + import pyclbr +@@ -1288,3 +1289,20 @@ def get_boolean(value): + return value + else: + return strutils.bool_from_string(value) ++ ++if hasattr(hmac, 'compare_digest'): ++ constant_time_compare = hmac.compare_digest ++else: ++ def constant_time_compare(first, second): ++ """Returns True if both string inputs are equal, otherwise False. ++ ++ This function should take a constant amount of time regardless of ++ how many characters in the strings match. ++ ++ """ ++ if len(first) != len(second): ++ return False ++ result = 0 ++ for x, y in zip(first, second): ++ result |= ord(x) ^ ord(y) ++ return result == 0