From 28b2615b3729ec8fe8697be6aeef7928dcb3f394 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 04:48:22 +0000 Subject: import python-2.7.5-76.el7 --- diff --git a/SOURCES/00285-fix-non-deterministic-read-in-test_pty.patch b/SOURCES/00285-fix-non-deterministic-read-in-test_pty.patch new file mode 100644 index 0000000..8605809 --- /dev/null +++ b/SOURCES/00285-fix-non-deterministic-read-in-test_pty.patch @@ -0,0 +1,59 @@ +diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py +index bec38c45456..f623aa09620 100644 +--- a/Lib/test/test_pty.py ++++ b/Lib/test/test_pty.py +@@ -11,6 +11,7 @@ + import select + import signal + import socket ++import io # readline + import unittest + + TEST_STRING_1 = "I wish to buy a fish license.\n" +@@ -24,6 +25,16 @@ def debug(msg): + pass + + ++# Note that os.read() is nondeterministic so we need to be very careful ++# to make the test suite deterministic. A normal call to os.read() may ++# give us less than expected. ++# ++# Beware, on my Linux system, if I put 'foo\n' into a terminal fd, I get ++# back 'foo\r\n' at the other end. The behavior depends on the termios ++# setting. The newline translation may be OS-specific. To make the ++# test suite deterministic and OS-independent, the functions _readline ++# and normalize_output can be used. ++ + def normalize_output(data): + # Some operating systems do conversions on newline. We could possibly + # fix that by doing the appropriate termios.tcsetattr()s. I couldn't +@@ -45,6 +56,12 @@ def normalize_output(data): + + return data + ++def _readline(fd): ++ """Read one line. May block forever if no newline is read.""" ++ reader = io.FileIO(fd, mode='rb', closefd=False) ++ return reader.readline() ++ ++ + + # Marginal testing of pty suite. Cannot do extensive 'do or fail' testing + # because pty code is not too portable. +@@ -97,14 +114,14 @@ def test_basic(self): + + debug("Writing to slave_fd") + os.write(slave_fd, TEST_STRING_1) +- s1 = os.read(master_fd, 1024) ++ s1 = _readline(master_fd) + self.assertEqual('I wish to buy a fish license.\n', + normalize_output(s1)) + + debug("Writing chunked output") + os.write(slave_fd, TEST_STRING_2[:5]) + os.write(slave_fd, TEST_STRING_2[5:]) +- s2 = os.read(master_fd, 1024) ++ s2 = _readline(master_fd) + self.assertEqual('For my pet fish, Eric.\n', normalize_output(s2)) + + os.close(slave_fd) diff --git a/SOURCES/00298-do-not-send-IP-in-SNI-TLS-extension.patch b/SOURCES/00298-do-not-send-IP-in-SNI-TLS-extension.patch new file mode 100644 index 0000000..99ed83c --- /dev/null +++ b/SOURCES/00298-do-not-send-IP-in-SNI-TLS-extension.patch @@ -0,0 +1,60 @@ +diff --git a/Modules/_ssl.c b/Modules/_ssl.c +index d0a3830..51b192c 100644 +--- a/Modules/_ssl.c ++++ b/Modules/_ssl.c +@@ -50,6 +50,11 @@ + #include + #endif + ++#ifndef MS_WINDOWS ++/* inet_pton */ ++#include ++#endif ++ + /* Include OpenSSL header files */ + #include "openssl/rsa.h" + #include "openssl/crypto.h" +@@ -493,8 +498,41 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, + SSL_set_mode(self->ssl, mode); + + #if HAVE_SNI +- if (server_hostname != NULL) +- SSL_set_tlsext_host_name(self->ssl, server_hostname); ++ if (server_hostname != NULL) { ++/* Don't send SNI for IP addresses. We cannot simply use inet_aton() and ++ * inet_pton() here. inet_aton() may be linked weakly and inet_pton() isn't ++ * available on all platforms. Use OpenSSL's IP address parser. It's ++ * available since 1.0.2 and LibreSSL since at least 2.3.0. */ ++ int send_sni = 1; ++#if OPENSSL_VERSION_NUMBER >= 0x10200000L ++ ASN1_OCTET_STRING *ip = a2i_IPADDRESS(server_hostname); ++ if (ip == NULL) { ++ send_sni = 1; ++ ERR_clear_error(); ++ } else { ++ send_sni = 0; ++ ASN1_OCTET_STRING_free(ip); ++ } ++#elif defined(HAVE_INET_PTON) ++#ifdef ENABLE_IPV6 ++ char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; ++#else ++ char packed[sizeof(struct in_addr)]; ++#endif /* ENABLE_IPV6 */ ++ if (inet_pton(AF_INET, server_hostname, packed)) { ++ send_sni = 0; ++#ifdef ENABLE_IPV6 ++ } else if(inet_pton(AF_INET6, server_hostname, packed)) { ++ send_sni = 0; ++#endif /* ENABLE_IPV6 */ ++ } else { ++ send_sni = 1; ++ } ++#endif /* HAVE_INET_PTON */ ++ if (send_sni) { ++ SSL_set_tlsext_host_name(self->ssl, server_hostname); ++ } ++ } + #endif + + /* If the socket is in non-blocking mode or timeout mode, set the BIO diff --git a/SOURCES/00299-fix-ssl-module-pymax.patch b/SOURCES/00299-fix-ssl-module-pymax.patch new file mode 100644 index 0000000..4f8c8da --- /dev/null +++ b/SOURCES/00299-fix-ssl-module-pymax.patch @@ -0,0 +1,24 @@ +From 439956a149f8a3eb44646498c63b2ef3337d5f3d Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Sun, 25 Feb 2018 13:08:05 +0100 +Subject: [PATCH] Fix ssl module, Python 2.7 doesn't have Py_MAX (#5878) + +Signed-off-by: Christian Heimes +--- + Modules/_ssl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/Modules/_ssl.c b/Modules/_ssl.c +index af66a581e15a..f9ed94dee1e1 100644 +--- a/Modules/_ssl.c ++++ b/Modules/_ssl.c +@@ -610,7 +610,8 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, + } + #elif defined(HAVE_INET_PTON) + #ifdef ENABLE_IPV6 +- char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; ++ #define PySSL_MAX(x, y) (((x) > (y)) ? (x) : (y)) ++ char packed[PySSL_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; + #else + char packed[sizeof(struct in_addr)]; + #endif /* ENABLE_IPV6 */ diff --git a/SOURCES/00303-CVE-2018-1060-1.patch b/SOURCES/00303-CVE-2018-1060-1.patch new file mode 100644 index 0000000..4d455a5 --- /dev/null +++ b/SOURCES/00303-CVE-2018-1060-1.patch @@ -0,0 +1,86 @@ +diff --git a/Lib/difflib.py b/Lib/difflib.py +index 1c6fbdbedcb7..788a92df3f89 100644 +--- a/Lib/difflib.py ++++ b/Lib/difflib.py +@@ -1103,7 +1103,7 @@ def _qformat(self, aline, bline, atags, btags): + + import re + +-def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match): ++def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): + r""" + Return 1 for ignorable line: iff `line` is blank or contains a single '#'. + +diff --git a/Lib/poplib.py b/Lib/poplib.py +index b91e5f72d2ca..a238510b38fc 100644 +--- a/Lib/poplib.py ++++ b/Lib/poplib.py +@@ -274,7 +274,7 @@ def rpop(self, user): + return self._shortcmd('RPOP %s' % user) + + +- timestamp = re.compile(r'\+OK.*(<[^>]+>)') ++ timestamp = re.compile(br'\+OK.[^<]*(<.*>)') + + def apop(self, user, secret): + """Authorisation +diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py +index 35f2c36ca70a..d8277b79b880 100644 +--- a/Lib/test/test_difflib.py ++++ b/Lib/test/test_difflib.py +@@ -269,13 +269,33 @@ def test_range_format_context(self): + self.assertEqual(fmt(3,6), '4,6') + self.assertEqual(fmt(0,0), '0') + ++class TestJunkAPIs(unittest.TestCase): ++ def test_is_line_junk_true(self): ++ for line in ['#', ' ', ' #', '# ', ' # ', '']: ++ self.assertTrue(difflib.IS_LINE_JUNK(line), repr(line)) ++ ++ def test_is_line_junk_false(self): ++ for line in ['##', ' ##', '## ', 'abc ', 'abc #', 'Mr. Moose is up!']: ++ self.assertFalse(difflib.IS_LINE_JUNK(line), repr(line)) ++ ++ def test_is_line_junk_REDOS(self): ++ evil_input = ('\t' * 1000000) + '##' ++ self.assertFalse(difflib.IS_LINE_JUNK(evil_input)) ++ ++ def test_is_character_junk_true(self): ++ for char in [' ', '\t']: ++ self.assertTrue(difflib.IS_CHARACTER_JUNK(char), repr(char)) ++ ++ def test_is_character_junk_false(self): ++ for char in ['a', '#', '\n', '\f', '\r', '\v']: ++ self.assertFalse(difflib.IS_CHARACTER_JUNK(char), repr(char)) + + def test_main(): + difflib.HtmlDiff._default_prefix = 0 + Doctests = doctest.DocTestSuite(difflib) + run_unittest( + TestWithAscii, TestAutojunk, TestSFpatches, TestSFbugs, +- TestOutputFormat, Doctests) ++ TestOutputFormat, TestJunkAPIs) + + if __name__ == '__main__': + test_main() +diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py +index 23d688724b95..d2143759ba66 100644 +--- a/Lib/test/test_poplib.py ++++ b/Lib/test/test_poplib.py +@@ -211,6 +211,16 @@ def test_noop(self): + def test_rpop(self): + self.assertOK(self.client.rpop('foo')) + ++ def test_apop_REDOS(self): ++ # Replace welcome with very long evil welcome. ++ # NB The upper bound on welcome length is currently 2048. ++ # At this length, evil input makes each apop call take ++ # on the order of milliseconds instead of microseconds. ++ evil_welcome = b'+OK' + (b'<' * 1000000) ++ with test_support.swap_attr(self.client, 'welcome', evil_welcome): ++ # The evil welcome is invalid, so apop should throw. ++ self.assertRaises(poplib.error_proto, self.client.apop, 'a', 'kb') ++ + def test_top(self): + expected = ('+OK 116 bytes', + ['From: postmaster@python.org', 'Content-Type: text/plain', diff --git a/SOURCES/00306-fix-oserror-17-upon-semaphores-creation.patch b/SOURCES/00306-fix-oserror-17-upon-semaphores-creation.patch new file mode 100644 index 0000000..b6070a4 --- /dev/null +++ b/SOURCES/00306-fix-oserror-17-upon-semaphores-creation.patch @@ -0,0 +1,44 @@ + +# HG changeset patch +# User Charles-François Natali +# Date 1455316761 0 +# Node ID d3662c088db8fb2c89f754031f18b1543419fed9 +# Parent 5715a6d9ff12053e81f7ad75268ac059b079b351 +Issue #24303: Fix random EEXIST upon multiprocessing semaphores creation with +Linux PID namespaces enabled. + +diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c +--- a/Modules/_multiprocessing/semaphore.c ++++ b/Modules/_multiprocessing/semaphore.c +@@ -429,7 +429,7 @@ semlock_new(PyTypeObject *type, PyObject + int kind, maxvalue, value; + PyObject *result; + static char *kwlist[] = {"kind", "value", "maxvalue", NULL}; +- static int counter = 0; ++ int try = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwlist, + &kind, &value, &maxvalue)) +@@ -440,10 +440,18 @@ semlock_new(PyTypeObject *type, PyObject + return NULL; + } + +- PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%d", (long)getpid(), counter++); ++ /* Create a semaphore with a unique name. The bytes returned by ++ * _PyOS_URandom() are treated as unsigned long to ensure that the filename ++ * is valid (no special characters). */ ++ do { ++ unsigned long suffix; ++ _PyOS_URandom((char *)&suffix, sizeof(suffix)); ++ PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%lu", (long)getpid(), ++ suffix); ++ SEM_CLEAR_ERROR(); ++ handle = SEM_CREATE(buffer, value, maxvalue); ++ } while ((handle == SEM_FAILED) && (errno == EEXIST) && (++try < 100)); + +- SEM_CLEAR_ERROR(); +- handle = SEM_CREATE(buffer, value, maxvalue); + /* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */ + if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0) + goto failure; + diff --git a/SPECS/python.spec b/SPECS/python.spec index 2af363e..5277f37 100644 --- a/SPECS/python.spec +++ b/SPECS/python.spec @@ -1,3 +1,4 @@ + # ====================================================== # Conditionals and other variables controlling the build # ====================================================== @@ -51,6 +52,13 @@ %global with_valgrind 0 %endif +# Having more than 28 cores on a PPC machine will lead to race conditions +# during build so we have to set a limit. +# See: https://bugzilla.redhat.com/show_bug.cgi?id=1568974 +%ifarch ppc %{power64} && %_smp_ncpus_max > 28 +%global _smp_ncpus_max 28 +%endif + %global with_gdbm 1 # Turn this to 0 to turn off the "check" phase: @@ -106,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: 69%{?dist} +Release: 76%{?dist} License: Python Group: Development/Languages Requires: %{python}-libs%{?_isa} = %{version}-%{release} @@ -1204,6 +1212,12 @@ Patch281: 00281-add-context-parameter-to-xmlrpclib.ServerProxy.patch # Resolves: rhbz#1468410 Patch282: 00282-obmalloc-mmap-threshold.patch +# 00285 # +# Fix nondeterministic read in test_pty which fails randomly in brew. +# FIXED UPSTREAM: https://bugs.python.org/issue31158 +# Resolves: rhbz#1512160 +Patch285: 00285-fix-non-deterministic-read-in-test_pty.patch + # 00287 # # On the creation of io.FileIO() and builtin file() objects the GIL is now released # when checking the file descriptor. io.FileIO.readall(), io.FileIO.read(), and @@ -1228,12 +1242,40 @@ Patch295: 00295-fix-https-behind-proxy.patch # Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1546351 Patch296: 00296-Readd-the-private-_set_hostport-api-to-httplib.patch +# 00298 # +# The SSL module no longer sends IP addresses in SNI TLS extension on +# platforms with OpenSSL 1.0.2+ or inet_pton. +# FIXED UPSTREAM: https://bugs.python.org/issue32185 +# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1555314 +Patch298: 00298-do-not-send-IP-in-SNI-TLS-extension.patch + +# 00299 # +# Fix ssl module, Python 2.7 doesn't have Py_MAX +# The previous patch 298 broke python2. This is a fixup. +# FIXED UPSTREAM: https://github.com/python/cpython/pull/5878 +# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1555314 +Patch299: 00299-fix-ssl-module-pymax.patch + +# 00303 # +# Fix CVE-2018-1060 and CVE-2018-1061 +# FIXED UPSTREAM: https://bugs.python.org/issue32981 +# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1563454 +# and https://bugzilla.redhat.com/show_bug.cgi?id=1549192 +Patch303: 00303-CVE-2018-1060-1.patch + # 00305 # # Remove 3DES from the cipher list to mitigate CVE-2016-2183 (sweet32). # FIXED UPSTREAM: https://bugs.python.org/issue27850 -# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1584545 +# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1581901 Patch305: 00305-CVE-2016-2183.patch +# 00306 # +# Fix OSERROR 17 due to _multiprocessing/semaphore.c +# assuming a one-to-one Pid -> process mapping +# FIXED UPSTREAM: https://bugs.python.org/issue24303 +# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1579432 +Patch306: 00306-fix-oserror-17-upon-semaphores-creation.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora 17 onwards, @@ -1266,7 +1308,6 @@ Patch5000: 05000-autotool-intermediates.patch %if %{main_python} Obsoletes: Distutils Provides: Distutils -Obsoletes: python2 Provides: python2 = %{version} Obsoletes: python-elementtree <= 1.2.6 Obsoletes: python-sqlite < 2.3.2 @@ -1331,6 +1372,9 @@ Conflicts: python-virtualenv < 15.1.0-1 # yet upgraded expat: Requires: expat >= 2.1.0 +Provides: python2-libs = %{version}-%{release} +Provides: python2-libs%{?_isa} = %{version}-%{release} + %description libs This package contains runtime libraries for use by Python: - the libpython dynamic library, for use by applications that embed Python as @@ -1655,10 +1699,15 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c %patch276 -p1 %patch281 -p1 %patch282 -p1 +%patch285 -p1 %patch287 -p1 %patch295 -p1 %patch296 -p1 +%patch298 -p1 +%patch299 -p1 +%patch303 -p1 %patch305 -p1 +%patch306 -p1 # This shouldn't be necesarry, but is right now (2.2a3) @@ -2107,6 +2156,10 @@ sed -i "s|^#\!.\?/usr/bin.*$|#\! %{__python}|" \ mkdir %{buildroot}%{_tmpfilesdir} cp %{SOURCE9} %{buildroot}%{_tmpfilesdir}/python.conf +# Create the platform-python symlink pointing to usr/bin/python2.7 +mkdir -p %{buildroot}%{_libexecdir} +ln -s %{_bindir}/python%{pybasever} %{buildroot}%{_libexecdir}/platform-python + # ====================================================== # Running the upstream test suite # ====================================================== @@ -2194,6 +2247,9 @@ rm -fr %{buildroot} %{_bindir}/python2 %endif %{_bindir}/python%{pybasever} + +%{_libexecdir}/platform-python + %{_mandir}/*/* %files libs @@ -2532,9 +2588,40 @@ rm -fr %{buildroot} # ====================================================== %changelog -* Wed May 30 2018 Charalampos Stratakis - 2.7.5-70 +* Mon Sep 10 2018 Charalampos Stratakis - 2.7.5-76 +- Remove an unversioned obsoletes tag +Resolves: rhbz#1627059 + +* Mon Jul 16 2018 Charalampos Stratakis - 2.7.5-75 +- Provide the /usr/libexec/platform-python symlink to the main binary +Resolves: rhbz#1599159 + +* Tue Jun 12 2018 Charalampos Stratakis - 2.7.5-74 +- Fix OSERROR 17 due to _multiprocessing/semaphore.c assuming + a one-to-one Pid -> process mapping +Resolves: rhbz#1579432 + +* Wed May 30 2018 Charalampos Stratakis - 2.7.5-73 - Remove 3DS cipher to mitigate CVE-2016-2183 (sweet32). -Resolves: rhbz#1584545 +Resolves: rhbz#1581901 + +* Thu May 03 2018 Charalampos Stratakis - 2.7.5-72 +- Fix CVE-2018-1060 and CVE-2018-1061 +Resolves: rhbz#1563454 and rhbz#1549192 +- Provide python2-libs from the python-libs subpackage +Resolves: rhbz#1557460 + +* Wed Apr 18 2018 Charalampos Stratakis - 2.7.5-71 +- Limit the number of CPU cores when building the package on power architectures +Resolves: rhbz#1568974 + +* Tue Apr 17 2018 Charalampos Stratakis - 2.7.5-70 +- Do not send IP addresses in SNI TLS extension +Resolves: rhbz#1555314 + +* Tue Apr 17 2018 Charalampos Stratakis - 2.7.5-69 +- Fix nondeterministic read in test_pty +Resolves: rhbz#1512160 * Mon Feb 19 2018 Tomas Orsava - 2.7.5-68 - Add Conflicts tag with old virtualenv versions due to new behaviour of