From 2a4aa9ca85e851ffd1f8a0b9ca2f0df01001072b Mon Sep 17 00:00:00 2001 From: Slavek Kabrda Date: Dec 04 2014 12:39:59 +0000 Subject: Fix CVE-2013-7338 and CVE-2014-2667. Resolves: rhbz#1078015 Resolves: rhbz#1083594 --- diff --git a/00198-fix-CVE-2013-7338.patch b/00198-fix-CVE-2013-7338.patch new file mode 100644 index 0000000..c330a56 --- /dev/null +++ b/00198-fix-CVE-2013-7338.patch @@ -0,0 +1,21 @@ +# This is a backport of following upstream patch: +# HG changeset patch +# User Serhiy Storchaka +# Date 1389272021 -7200 +# Node ID 79ea4ce431b1b10c79f51dcb2aaa0ccb2a8b1d48 +# Parent 9e3f5b5bcf7e4c62475bb1126fd0aecbbb9b64ac# Parent 0cf1defd5ac4433b8e36f950ba452103eb417f9f +Issue #20078: Reading malformed zipfiles no longer hangs with 100% CPU +consumption. + +diff --git a/Lib/zipfile.py b/Lib/zipfile.py +--- a/Lib/zipfile.py ++++ b/Lib/zipfile.py +@@ -862,6 +862,8 @@ class ZipExtFile(io.BufferedIOBase): + + data = self._fileobj.read(n) + self._compress_left -= len(data) ++ if not data: ++ raise EOFError + + if self._decrypter is not None: + data = bytes(map(self._decrypter, data)) diff --git a/00199-fix-CVE-2014-2667.patch b/00199-fix-CVE-2014-2667.patch new file mode 100644 index 0000000..dbcc786 --- /dev/null +++ b/00199-fix-CVE-2014-2667.patch @@ -0,0 +1,102 @@ +# This is a backport of following upstream patch: +# HG changeset patch +# User Benjamin Peterson +# Date 1396394277 14400 +# Node ID 6370d44013f7e7e0892dd7f78b91d3a929e2d343 +# Parent cb3a8abc0870d8d81a3521b3c8f397c5ccc73d7d# Parent 9186f4a18584f5038a9f875f2a7a3194ee46a571 +merge 3.2 (#21082) + +diff --git a/Doc/library/os.rst b/Doc/library/os.rst +--- a/Doc/library/os.rst ++++ b/Doc/library/os.rst +@@ -1563,11 +1563,8 @@ features: + The default *mode* is ``0o777`` (octal). On some systems, *mode* is + ignored. Where it is used, the current umask value is first masked out. + +- If *exists_ok* is ``False`` (the default), an :exc:`OSError` is raised if +- the target directory already exists. If *exists_ok* is ``True`` an +- :exc:`OSError` is still raised if the umask-masked *mode* is different from +- the existing mode, on systems where the mode is used. :exc:`OSError` will +- also be raised if the directory creation fails. ++ If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if the ++ target directory already exists. + + .. note:: + +diff --git a/Lib/os.py b/Lib/os.py +--- a/Lib/os.py ++++ b/Lib/os.py +@@ -230,23 +230,16 @@ SEEK_SET = 0 + SEEK_CUR = 1 + SEEK_END = 2 + +- +-def _get_masked_mode(mode): +- mask = umask(0) +- umask(mask) +- return mode & ~mask +- + # Super directory utilities. + # (Inspired by Eric Raymond; the doc strings are mostly his) + + def makedirs(name, mode=0o777, exist_ok=False): + """makedirs(path [, mode=0o777][, exist_ok=False]) + +- Super-mkdir; create a leaf directory and all intermediate ones. +- Works like mkdir, except that any intermediate path segment (not +- just the rightmost) will be created if it does not exist. If the +- target directory with the same mode as we specified already exists, +- raises an OSError if exist_ok is False, otherwise no exception is ++ Super-mkdir; create a leaf directory and all intermediate ones. Works like ++ mkdir, except that any intermediate path segment (not just the rightmost) ++ will be created if it does not exist. If the target directory already ++ exists, raise an OSError if exist_ok is False. Otherwise no exception is + raised. This is recursive. + + """ +@@ -268,20 +261,7 @@ def makedirs(name, mode=0o777, exist_ok= + try: + mkdir(name, mode) + except OSError as e: +- dir_exists = path.isdir(name) +- expected_mode = _get_masked_mode(mode) +- if dir_exists: +- # S_ISGID is automatically copied by the OS from parent to child +- # directories on mkdir. Don't consider it being set to be a mode +- # mismatch as mkdir does not unset it when not specified in mode. +- actual_mode = st.S_IMODE(lstat(name).st_mode) & ~st.S_ISGID +- else: +- actual_mode = -1 +- if not (e.errno == errno.EEXIST and exist_ok and dir_exists and +- actual_mode == expected_mode): +- if dir_exists and actual_mode != expected_mode: +- e.strerror += ' (mode %o != expected mode %o)' % ( +- actual_mode, expected_mode) ++ if not exist_ok or e.errno != errno.EEXIST or not path.isdir(name): + raise + + def removedirs(name): +diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py +--- a/Lib/test/test_os.py ++++ b/Lib/test/test_os.py +@@ -872,7 +872,7 @@ class MakedirTests(unittest.TestCase): + os.makedirs(path, mode) + self.assertRaises(OSError, os.makedirs, path, mode) + self.assertRaises(OSError, os.makedirs, path, mode, exist_ok=False) +- self.assertRaises(OSError, os.makedirs, path, 0o776, exist_ok=True) ++ os.makedirs(path, 0o776, exist_ok=True) + os.makedirs(path, mode=mode, exist_ok=True) + os.umask(old_mask) + +@@ -898,9 +898,8 @@ class MakedirTests(unittest.TestCase): + os.makedirs(path, mode, exist_ok=True) + # remove the bit. + os.chmod(path, stat.S_IMODE(os.lstat(path).st_mode) & ~S_ISGID) +- with self.assertRaises(OSError): +- # Should fail when the bit is not already set when demanded. +- os.makedirs(path, mode | S_ISGID, exist_ok=True) ++ # May work even when the bit is not already set when demanded. ++ os.makedirs(path, mode | S_ISGID, exist_ok=True) + finally: + os.umask(old_mask) + diff --git a/python3.spec b/python3.spec index b726582..958940b 100644 --- a/python3.spec +++ b/python3.spec @@ -126,7 +126,7 @@ Summary: Version 3 of the Python programming language aka Python 3000 Name: python3 Version: %{pybasever}.2 -Release: 18%{?dist} +Release: 19%{?dist} License: Python Group: Development/Languages @@ -666,6 +666,18 @@ Patch194: 00194-json-add-boundary-check.patch # document root. Patch197: 00197-fix-CVE-2014-4650.patch +# 00198 +# +# Fix CVE-2013-7338: malformed ZIP files could cause 100% CPU usage +# https://hg.python.org/cpython/rev/79ea4ce431b1 +Patch198: 00198-fix-CVE-2013-7338.patch + +# 00199 +# +# Fix CVE-2014-2667: os.makedirs(exist_ok=True) is not thread-safe in Python 3.x +# https://hg.python.org/cpython/rev/c24dd53ab4b9 +Patch199: 00199-fix-CVE-2014-2667.patch + # (New patches go here ^^^) # @@ -934,6 +946,8 @@ done %patch193 -p1 %patch194 -p1 %patch197 -p1 +%patch198 -p1 +%patch199 -p1 # Currently (2010-01-15), http://docs.python.org/library is for 2.6, and there # are many differences between 2.6 and the Python 3 library. @@ -1789,6 +1803,11 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Thu Dec 04 2014 Slavek Kabrda - 3.3.2-19 +- Fix CVE-2013-7338 and CVE-2014-2667. +Resolves: rhbz#1078015 +Resolves: rhbz#1083594 + * Mon Nov 03 2014 Slavek Kabrda - 3.3.2-18 - Fix CVE-2014-4650 - CGIHTTPServer URL handling Resolves: rhbz#1113529