Blame SOURCES/00352-resolve-hash-collisions-for-ipv4interface-and-ipv6interface.patch

d48edc
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
d48edc
From: Tapas Kundu <39723251+tapakund@users.noreply.github.com>
d48edc
Date: Wed, 1 Jul 2020 01:00:22 +0530
d48edc
Subject: [PATCH] 00352: Resolve hash collisions for IPv4Interface and
d48edc
 IPv6Interface
d48edc
d48edc
CVE-2020-14422
d48edc
The hash() methods of classes IPv4Interface and IPv6Interface had issue
d48edc
of generating constant hash values of 32 and 128 respectively causing hash collisions.
d48edc
The fix uses the hash() function to generate hash values for the objects
d48edc
instead of XOR operation.
d48edc
Fixed upstream: https://bugs.python.org/issue41004
d48edc
---
d48edc
 Lib/ipaddress.py                                      |  4 ++--
d48edc
 Lib/test/test_ipaddress.py                            | 11 +++++++++++
d48edc
 .../Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst |  1 +
d48edc
 3 files changed, 14 insertions(+), 2 deletions(-)
d48edc
 create mode 100644 Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
d48edc
d48edc
diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
d48edc
index 583f02ad54..98492136ca 100644
d48edc
--- a/Lib/ipaddress.py
d48edc
+++ b/Lib/ipaddress.py
d48edc
@@ -1418,7 +1418,7 @@ class IPv4Interface(IPv4Address):
d48edc
             return False
d48edc
 
d48edc
     def __hash__(self):
d48edc
-        return self._ip ^ self._prefixlen ^ int(self.network.network_address)
d48edc
+        return hash((self._ip, self._prefixlen, int(self.network.network_address)))
d48edc
 
d48edc
     __reduce__ = _IPAddressBase.__reduce__
d48edc
 
d48edc
@@ -2092,7 +2092,7 @@ class IPv6Interface(IPv6Address):
d48edc
             return False
d48edc
 
d48edc
     def __hash__(self):
d48edc
-        return self._ip ^ self._prefixlen ^ int(self.network.network_address)
d48edc
+        return hash((self._ip, self._prefixlen, int(self.network.network_address)))
d48edc
 
d48edc
     __reduce__ = _IPAddressBase.__reduce__
d48edc
 
d48edc
diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py
d48edc
index 1cef4217bc..7de444af4a 100644
d48edc
--- a/Lib/test/test_ipaddress.py
d48edc
+++ b/Lib/test/test_ipaddress.py
d48edc
@@ -1990,6 +1990,17 @@ class IpaddrUnitTest(unittest.TestCase):
d48edc
                          sixtofouraddr.sixtofour)
d48edc
         self.assertFalse(bad_addr.sixtofour)
d48edc
 
d48edc
+    # issue41004 Hash collisions in IPv4Interface and IPv6Interface
d48edc
+    def testV4HashIsNotConstant(self):
d48edc
+        ipv4_address1 = ipaddress.IPv4Interface("1.2.3.4")
d48edc
+        ipv4_address2 = ipaddress.IPv4Interface("2.3.4.5")
d48edc
+        self.assertNotEqual(ipv4_address1.__hash__(), ipv4_address2.__hash__())
d48edc
+
d48edc
+    # issue41004 Hash collisions in IPv4Interface and IPv6Interface
d48edc
+    def testV6HashIsNotConstant(self):
d48edc
+        ipv6_address1 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:1")
d48edc
+        ipv6_address2 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:2")
d48edc
+        self.assertNotEqual(ipv6_address1.__hash__(), ipv6_address2.__hash__())
d48edc
 
d48edc
 if __name__ == '__main__':
d48edc
     unittest.main()
d48edc
diff --git a/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst b/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
d48edc
new file mode 100644
d48edc
index 0000000000..f5a9db52ff
d48edc
--- /dev/null
d48edc
+++ b/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
d48edc
@@ -0,0 +1 @@
d48edc
+CVE-2020-14422: The __hash__() methods of  ipaddress.IPv4Interface and ipaddress.IPv6Interface incorrectly generated constant hash values of 32 and 128 respectively. This resulted in always causing hash collisions. The fix uses hash() to generate hash values for the tuple of (address, mask length, network address).