diff --git a/SOURCES/00351-avoid-infinite-loop-in-the-tarfile-module.patch b/SOURCES/00351-avoid-infinite-loop-in-the-tarfile-module.patch new file mode 100644 index 0000000..c9c431c --- /dev/null +++ b/SOURCES/00351-avoid-infinite-loop-in-the-tarfile-module.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Wed, 15 Jul 2020 05:36:36 -0700 +Subject: [PATCH] 00351: Avoid infinite loop in the tarfile module + +Avoid infinite loop when reading specially crafted TAR files using the tarfile module +(CVE-2019-20907). +Fixed upstream: https://bugs.python.org/issue39017 +--- + Lib/tarfile.py | 2 ++ + Lib/test/recursion.tar | Bin 0 -> 516 bytes + Lib/test/test_tarfile.py | 7 +++++++ + .../2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst | 1 + + 4 files changed, 10 insertions(+) + create mode 100644 Lib/test/recursion.tar + create mode 100644 Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst + +diff --git a/Lib/tarfile.py b/Lib/tarfile.py +index 62d22150f5..2ea47978ff 100755 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -1231,6 +1231,8 @@ class TarInfo(object): + + length, keyword = match.groups() + length = int(length) ++ if length == 0: ++ raise InvalidHeaderError("invalid header") + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + # Normally, we could just use "utf-8" as the encoding and "strict" +diff --git a/Lib/test/recursion.tar b/Lib/test/recursion.tar +new file mode 100644 +index 0000000000000000000000000000000000000000..b8237251964983f54ed1966297e887636cd0c5f4 +GIT binary patch +literal 516 +zcmYdFPRz+kEn=W0Fn}74P8%Xw3X=l~85kIuo0>8xq$A1Gm}!7)KUsFc41m#O8A5+e +I1_}|j06>QaCIA2c + +literal 0 +HcmV?d00001 + +diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py +index 4cd7d5370f..573be812ea 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -395,6 +395,13 @@ class CommonReadTest(ReadTest): + with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"): + tar.extractfile(t).read() + ++ def test_length_zero_header(self): ++ # bpo-39017 (CVE-2019-20907): reading a zero-length header should fail ++ # with an exception ++ with self.assertRaisesRegex(tarfile.ReadError, "file could not be opened successfully"): ++ with tarfile.open(support.findfile('recursion.tar')) as tar: ++ pass ++ + class MiscReadTestBase(CommonReadTest): + def requires_name_attribute(self): + pass +diff --git a/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst +new file mode 100644 +index 0000000000..ad26676f8b +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst +@@ -0,0 +1 @@ ++Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907). diff --git a/SOURCES/00352-resolve-hash-collisions-for-ipv4interface-and-ipv6interface.patch b/SOURCES/00352-resolve-hash-collisions-for-ipv4interface-and-ipv6interface.patch new file mode 100644 index 0000000..c01a42e --- /dev/null +++ b/SOURCES/00352-resolve-hash-collisions-for-ipv4interface-and-ipv6interface.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tapas Kundu <39723251+tapakund@users.noreply.github.com> +Date: Wed, 1 Jul 2020 01:00:22 +0530 +Subject: [PATCH] 00352: Resolve hash collisions for IPv4Interface and + IPv6Interface + +CVE-2020-14422 +The hash() methods of classes IPv4Interface and IPv6Interface had issue +of generating constant hash values of 32 and 128 respectively causing hash collisions. +The fix uses the hash() function to generate hash values for the objects +instead of XOR operation. +Fixed upstream: https://bugs.python.org/issue41004 +--- + Lib/ipaddress.py | 4 ++-- + Lib/test/test_ipaddress.py | 11 +++++++++++ + .../Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst | 1 + + 3 files changed, 14 insertions(+), 2 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst + +diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py +index 583f02ad54..98492136ca 100644 +--- a/Lib/ipaddress.py ++++ b/Lib/ipaddress.py +@@ -1418,7 +1418,7 @@ class IPv4Interface(IPv4Address): + return False + + def __hash__(self): +- return self._ip ^ self._prefixlen ^ int(self.network.network_address) ++ return hash((self._ip, self._prefixlen, int(self.network.network_address))) + + __reduce__ = _IPAddressBase.__reduce__ + +@@ -2092,7 +2092,7 @@ class IPv6Interface(IPv6Address): + return False + + def __hash__(self): +- return self._ip ^ self._prefixlen ^ int(self.network.network_address) ++ return hash((self._ip, self._prefixlen, int(self.network.network_address))) + + __reduce__ = _IPAddressBase.__reduce__ + +diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py +index 1cef4217bc..7de444af4a 100644 +--- a/Lib/test/test_ipaddress.py ++++ b/Lib/test/test_ipaddress.py +@@ -1990,6 +1990,17 @@ class IpaddrUnitTest(unittest.TestCase): + sixtofouraddr.sixtofour) + self.assertFalse(bad_addr.sixtofour) + ++ # issue41004 Hash collisions in IPv4Interface and IPv6Interface ++ def testV4HashIsNotConstant(self): ++ ipv4_address1 = ipaddress.IPv4Interface("1.2.3.4") ++ ipv4_address2 = ipaddress.IPv4Interface("2.3.4.5") ++ self.assertNotEqual(ipv4_address1.__hash__(), ipv4_address2.__hash__()) ++ ++ # issue41004 Hash collisions in IPv4Interface and IPv6Interface ++ def testV6HashIsNotConstant(self): ++ ipv6_address1 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:1") ++ ipv6_address2 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:2") ++ self.assertNotEqual(ipv6_address1.__hash__(), ipv6_address2.__hash__()) + + if __name__ == '__main__': + unittest.main() +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 +new file mode 100644 +index 0000000000..f5a9db52ff +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst +@@ -0,0 +1 @@ ++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). diff --git a/SPECS/python3.spec b/SPECS/python3.spec index 8ad452e..db550a8 100644 --- a/SPECS/python3.spec +++ b/SPECS/python3.spec @@ -14,7 +14,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well Version: %{pybasever}.8 -Release: 17%{?dist} +Release: 18%{?dist} License: Python @@ -190,6 +190,7 @@ BuildRequires: gcc-c++ # Removed version limit (gdbm-devel >= 1:1.13), because RHEL7 has only version 1.10 BuildRequires: gdbm-devel %endif +BuildRequires: git-core BuildRequires: glibc-devel BuildRequires: gmp-devel BuildRequires: libappstream-glib @@ -451,6 +452,23 @@ Patch344: 00344-CVE-2019-16935.patch # Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1810616 Patch346: 00346-CVE-2020-8492.patch +# 00351 # +# Avoid infinite loop when reading specially crafted TAR files using the tarfile module +# (CVE-2019-20907). +# See: https://bugs.python.org/issue39017 +Patch351: 00351-avoid-infinite-loop-in-the-tarfile-module.patch + +# 00352 # 5253c417a23b3658fa115d2c72fa54b20293a31c +# Resolve hash collisions for IPv4Interface and IPv6Interface +# +# CVE-2020-14422 +# The hash() methods of classes IPv4Interface and IPv6Interface had issue +# of generating constant hash values of 32 and 128 respectively causing hash collisions. +# The fix uses the hash() function to generate hash values for the objects +# instead of XOR operation. +# Fixed upstream: https://bugs.python.org/issue41004 +Patch352: 00352-resolve-hash-collisions-for-ipv4interface-and-ipv6interface.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -776,6 +794,10 @@ sed -r -i s/'_PIP_VERSION = "[0-9.]+"'/'_PIP_VERSION = "%{pip_version}"'/ Lib/en %patch344 -p1 %patch346 -p1 +# Patch 351 adds binary file for testing. We need to apply it using Git. +git apply %{PATCH351} + +%patch352 -p1 # Remove files that should be generated by the build # (This is after patching, so that we can use patches directly from upstream) @@ -1164,9 +1186,6 @@ CheckPython() { -wW --slowest --findleaks \ -x test_distutils \ -x test_bdist_rpm \ - %ifarch %{arm} - -x test_gdb \ - %endif %ifarch %{mips64} -x test_ctypes \ %endif @@ -1652,6 +1671,12 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 31 2020 Charalampos Stratakis - 3.6.8-18 +- Avoid infinite loop when reading specially crafted TAR files (CVE-2019-20907) +Resolves: rhbz#1856481 +- Resolve hash collisions for Pv4Interface and IPv6Interface (CVE-2020-14422) +Resolves: rhbz#1854926 + * Wed May 06 2020 Charalampos Stratakis - 3.6.8-17 - Overhaul python's FIPS mode support Resolves: rhbz#1788459