1 From b98e7790c77a4378ec4b1c71b84138cb930b69b7 Mon Sep 17 00:00:00 2001
2 From: Tapas Kundu <39723251+tapakund@users.noreply.github.com>
3 Date: Wed, 1 Jul 2020 00:50:21 +0530
4 Subject: [PATCH] [3.7] bpo-41004: Resolve hash collisions for IPv4Interface
5 and IPv6Interface (GH-21033) (GH-21231)
8 The __hash__() methods of classes IPv4Interface and IPv6Interface had issue
9 of generating constant hash values of 32 and 128 respectively causing hash collisions.
10 The fix uses the hash() function to generate hash values for the objects
11 instead of XOR operation
12 (cherry picked from commit b30ee26e366bf509b7538d79bfec6c6d38d53f28)
14 Co-authored-by: Ravi Teja P <rvteja92@gmail.com>
16 Signed-off-by: Tapas Kundu <tkundu@vmware.com>
18 Lib/ipaddress.py | 4 ++--
19 Lib/test/test_ipaddress.py | 11 +++++++++++
20 .../Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst | 1 +
21 3 files changed, 14 insertions(+), 2 deletions(-)
22 create mode 100644 Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
24 diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
25 index 80249288d73ab..54882934c3dc1 100644
26 --- a/Lib/ipaddress.py
27 +++ b/Lib/ipaddress.py
28 @@ -1442,7 +1442,7 @@ def __lt__(self, other):
32 - return self._ip ^ self._prefixlen ^ int(self.network.network_address)
33 + return hash((self._ip, self._prefixlen, int(self.network.network_address)))
35 __reduce__ = _IPAddressBase.__reduce__
37 @@ -2088,7 +2088,7 @@ def __lt__(self, other):
41 - return self._ip ^ self._prefixlen ^ int(self.network.network_address)
42 + return hash((self._ip, self._prefixlen, int(self.network.network_address)))
44 __reduce__ = _IPAddressBase.__reduce__
46 diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py
47 index 455b893fb126f..1fb6a929dc2d9 100644
48 --- a/Lib/test/test_ipaddress.py
49 +++ b/Lib/test/test_ipaddress.py
50 @@ -2091,6 +2091,17 @@ def testsixtofour(self):
51 sixtofouraddr.sixtofour)
52 self.assertFalse(bad_addr.sixtofour)
54 + # issue41004 Hash collisions in IPv4Interface and IPv6Interface
55 + def testV4HashIsNotConstant(self):
56 + ipv4_address1 = ipaddress.IPv4Interface("1.2.3.4")
57 + ipv4_address2 = ipaddress.IPv4Interface("2.3.4.5")
58 + self.assertNotEqual(ipv4_address1.__hash__(), ipv4_address2.__hash__())
60 + # issue41004 Hash collisions in IPv4Interface and IPv6Interface
61 + def testV6HashIsNotConstant(self):
62 + ipv6_address1 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:1")
63 + ipv6_address2 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:2")
64 + self.assertNotEqual(ipv6_address1.__hash__(), ipv6_address2.__hash__())
66 if __name__ == '__main__':
68 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
70 index 0000000000000..f5a9db52fff52
72 +++ b/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
74 +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).