--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openstack/nova/patches/07-CVE-2014-3517.patch Tue Sep 23 17:12:33 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 <[email protected]>
+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