diff --git a/SOURCES/00351-cve-2019-20907-fix-infinite-loop-in-tarfile.patch b/SOURCES/00351-cve-2019-20907-fix-infinite-loop-in-tarfile.patch new file mode 100644 index 0000000..f832265 --- /dev/null +++ b/SOURCES/00351-cve-2019-20907-fix-infinite-loop-in-tarfile.patch @@ -0,0 +1,78 @@ +From cb33ceb1b0ec5ec1cf8cb8239ea2705508501afc Mon Sep 17 00:00:00 2001 +From: Rishi +Date: Wed, 15 Jul 2020 13:51:00 +0200 +Subject: [PATCH] 00351-cve-2019-20907-fix-infinite-loop-in-tarfile.patch + +00351 # +Avoid infinite loop when reading specially crafted TAR files using the tarfile module +(CVE-2019-20907). +See: https://bugs.python.org/issue39017 +--- + Lib/tarfile.py | 2 ++ + Lib/test/recursion.tar | Bin 0 -> 516 bytes + Lib/test/test_tarfile.py | 8 ++++++++ + .../2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst | 1 + + 4 files changed, 11 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 16a6e86..ddddc1b 100644 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -1388,6 +1388,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] + + keyword = keyword.decode("utf8") +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 69d342a..9aa6ea6 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -11,6 +11,7 @@ import unittest + import tarfile + + from test import test_support ++from test import test_support as support + + # Check for our compression modules. + try: +@@ -206,6 +207,13 @@ class CommonReadTest(ReadTest): + + class MiscReadTest(CommonReadTest): + ++ def test_length_zero_header(self): ++ # bpo-39017 (CVE-2019-20907): reading a zero-length header should fail ++ # with an exception ++ with self.assertRaisesRegexp(tarfile.ReadError, "file could not be opened successfully"): ++ with tarfile.open(support.findfile('recursion.tar')) as tar: ++ pass ++ + def test_no_name_argument(self): + fobj = open(self.tarname, "rb") + tar = tarfile.open(fileobj=fobj, mode=self.mode) +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 0000000..ad26676 +--- /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). +-- +2.26.2 + diff --git a/SOURCES/99999-python-2.7.5-issues-17979-17998.patch b/SOURCES/99999-python-2.7.5-issues-17979-17998.patch deleted file mode 100644 index fbf2388..0000000 --- a/SOURCES/99999-python-2.7.5-issues-17979-17998.patch +++ /dev/null @@ -1,129 +0,0 @@ - -# HG changeset patch -# User Serhiy Storchaka -# Date 1369166013 -10800 -# Node ID 8408eed151ebee1c546414f1f40be46c1ad76077 -# Parent 7fce9186accb10122e45d975f4b380c2ed0fae35 -Issue #17979: Fixed the re module in build with --disable-unicode. - -diff --git a/Modules/sre.h b/Modules/sre.h ---- a/Modules/sre.h -+++ b/Modules/sre.h -@@ -23,8 +23,8 @@ - # define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX + 1u) - # endif - #else --# define SRE_CODE unsigned long --# if SIZEOF_SIZE_T > SIZEOF_LONG -+# define SRE_CODE unsigned int -+# if SIZEOF_SIZE_T > SIZEOF_INT - # define SRE_MAXREPEAT (~(SRE_CODE)0) - # else - # define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX + 1u) - - -# HG changeset patch -# User Serhiy Storchaka -# Date 1375547193 -10800 -# Node ID e5e425fd1e4f7e859abdced43621203cdfa87a16 -# Parent 8205e72b5cfcdb7a3450c80f3368eff610bc650c -Issue #17998: Fix an internal error in regular expression engine. - -diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py ---- a/Lib/test/test_re.py -+++ b/Lib/test/test_re.py -@@ -907,6 +907,16 @@ class ReTests(unittest.TestCase): - self.assertEqual(m.group(1), "") - self.assertEqual(m.group(2), "y") - -+ def test_issue17998(self): -+ for reps in '*', '+', '?', '{1}': -+ for mod in '', '?': -+ pattern = '.' + reps + mod + 'yz' -+ self.assertEqual(re.compile(pattern, re.S).findall('xyz'), -+ ['xyz'], msg=pattern) -+ pattern = pattern.encode() -+ self.assertEqual(re.compile(pattern, re.S).findall(b'xyz'), -+ [b'xyz'], msg=pattern) -+ - - - def run_re_tests(): -diff --git a/Modules/_sre.c b/Modules/_sre.c ---- a/Modules/_sre.c -+++ b/Modules/_sre.c -@@ -1028,7 +1028,7 @@ entrance: - TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); - -- if (ctx->pattern[1] > end - ctx->ptr) -+ if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) - RETURN_FAILURE; /* cannot match */ - - state->ptr = ctx->ptr; -@@ -1111,7 +1111,7 @@ entrance: - TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); - -- if (ctx->pattern[1] > end - ctx->ptr) -+ if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) - RETURN_FAILURE; /* cannot match */ - - state->ptr = ctx->ptr; -@@ -1210,7 +1210,7 @@ entrance: - TRACE(("|%p|%p|MAX_UNTIL %d\n", ctx->pattern, - ctx->ptr, ctx->count)); - -- if (ctx->count < ctx->u.rep->pattern[1]) { -+ if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { - /* not enough matches */ - ctx->u.rep->count = ctx->count; - DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1, -@@ -1224,7 +1224,7 @@ entrance: - RETURN_FAILURE; - } - -- if ((ctx->count < ctx->u.rep->pattern[2] || -+ if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] || - ctx->u.rep->pattern[2] == SRE_MAXREPEAT) && - state->ptr != ctx->u.rep->last_ptr) { - /* we may have enough matches, but if we can -@@ -1273,7 +1273,7 @@ entrance: - TRACE(("|%p|%p|MIN_UNTIL %d %p\n", ctx->pattern, - ctx->ptr, ctx->count, ctx->u.rep->pattern)); - -- if (ctx->count < ctx->u.rep->pattern[1]) { -+ if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { - /* not enough matches */ - ctx->u.rep->count = ctx->count; - DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1, -@@ -1302,7 +1302,7 @@ entrance: - - LASTMARK_RESTORE(); - -- if ((ctx->count >= ctx->u.rep->pattern[2] -+ if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2] - && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) || - state->ptr == ctx->u.rep->last_ptr) - RETURN_FAILURE; -diff --git a/Modules/sre.h b/Modules/sre.h ---- a/Modules/sre.h -+++ b/Modules/sre.h -@@ -20,14 +20,14 @@ - # if SIZEOF_SIZE_T > 4 - # define SRE_MAXREPEAT (~(SRE_CODE)0) - # else --# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX + 1u) -+# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX) - # endif - #else - # define SRE_CODE unsigned int - # if SIZEOF_SIZE_T > SIZEOF_INT - # define SRE_MAXREPEAT (~(SRE_CODE)0) - # else --# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX + 1u) -+# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX) - # endif - #endif - - diff --git a/SPECS/python.spec b/SPECS/python.spec index eaac3d3..4a08d65 100644 --- a/SPECS/python.spec +++ b/SPECS/python.spec @@ -114,7 +114,7 @@ Summary: An interpreted, interactive, object-oriented programming language Name: %{python} # Remember to also rebase python-docs when changing this: Version: 2.7.5 -Release: 89%{?dist} +Release: 90%{?dist} License: Python Group: Development/Languages Requires: %{python}-libs%{?_isa} = %{version}-%{release} @@ -142,6 +142,7 @@ BuildRequires: gcc-c++ %if %{with_gdbm} BuildRequires: gdbm-devel %endif +BuildRequires: git-core BuildRequires: glibc-devel BuildRequires: gmp-devel BuildRequires: libdb-devel @@ -1327,6 +1328,12 @@ Patch332: 00332-CVE-2019-16056.patch # Fixed upstream: https://bugs.python.org/issue27614 Patch344: 00344-CVE-2019-16935.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-cve-2019-20907-fix-infinite-loop-in-tarfile.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora 17 onwards, @@ -1352,8 +1359,6 @@ Patch344: 00344-CVE-2019-16935.patch # above: Patch5000: 05000-autotool-intermediates.patch -Patch99999: 99999-python-2.7.5-issues-17979-17998.patch - # ====================================================== # Additional metadata, and subpackages # ====================================================== @@ -1777,9 +1782,9 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c %patch332 -p1 %patch344 -p1 -%ifarch %{arm} %{ix86} ppc -%patch99999 -p1 -%endif + +# Patch 351 adds binary file for testing. We need to apply it using Git. +git apply %{PATCH351} # This shouldn't be necesarry, but is right now (2.2a3) find -name "*~" |xargs rm -f @@ -2652,6 +2657,10 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Fri Jul 31 2020 Charalampos Stratakis - 2.7.5-90 +- Avoid infinite loop when reading specially crafted TAR files (CVE-2019-20907) +Resolves: rhbz#1856481 + * Fri Mar 20 2020 Charalampos Stratakis - 2.7.5-89 - Security fix for CVE-2019-16935 Resolves: rhbz#1797998