diff --git a/.gitignore b/.gitignore index 627a8a1..5dc28db 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/Python-2.7.16.tar.xz +SOURCES/Python-2.7.17.tar.xz diff --git a/.python27-python.metadata b/.python27-python.metadata index 9cde9f3..91447a6 100644 --- a/.python27-python.metadata +++ b/.python27-python.metadata @@ -1 +1 @@ -e9543af127d958b12b0edfb9340d4f0af3d0d90e SOURCES/Python-2.7.16.tar.xz +dc5784d11d09c29fbf3fc155e2f242b3d3309454 SOURCES/Python-2.7.17.tar.xz diff --git a/SOURCES/00146-hashlib-fips.patch b/SOURCES/00146-hashlib-fips.patch index 088ce1d..ef7bec5 100644 --- a/SOURCES/00146-hashlib-fips.patch +++ b/SOURCES/00146-hashlib-fips.patch @@ -343,7 +343,7 @@ index b8d6388..e0520ed 100644 pbkdf2_test_vectors = [ (b'password', b'salt', 1, None), diff --git a/Modules/Setup.dist b/Modules/Setup.dist -index c9c2226..38758c5 100644 +index b8f9702..00e5f18 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -252,14 +252,14 @@ imageop imageop.c # Operations on images @@ -366,7 +366,7 @@ index c9c2226..38758c5 100644 # SGI IRIX specific modules -- off by default. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c -index de69f6f..b2c2956 100644 +index 5df08e5..382ab9a 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -36,6 +36,7 @@ @@ -400,7 +400,7 @@ index de69f6f..b2c2956 100644 DEFINE_CONSTS_FOR_NEW(md5) DEFINE_CONSTS_FOR_NEW(sha1) -@@ -166,6 +177,48 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) +@@ -167,6 +178,48 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) } } @@ -449,7 +449,7 @@ index de69f6f..b2c2956 100644 /* Internal methods for a hash object */ static void -@@ -386,14 +439,15 @@ EVP_repr(PyObject *self) +@@ -388,14 +441,15 @@ EVP_repr(PyObject *self) static int EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) { @@ -468,7 +468,7 @@ index de69f6f..b2c2956 100644 return -1; } -@@ -409,7 +463,12 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) +@@ -411,7 +465,12 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) PyBuffer_Release(&view); return -1; } @@ -482,7 +482,7 @@ index de69f6f..b2c2956 100644 self->name = name_obj; Py_INCREF(self->name); -@@ -493,7 +552,8 @@ static PyTypeObject EVPtype = { +@@ -495,7 +554,8 @@ static PyTypeObject EVPtype = { static PyObject * EVPnew(PyObject *name_obj, const EVP_MD *digest, const EVP_MD_CTX *initial_ctx, @@ -492,7 +492,7 @@ index de69f6f..b2c2956 100644 { EVPobject *self; -@@ -508,7 +568,12 @@ EVPnew(PyObject *name_obj, +@@ -510,7 +570,12 @@ EVPnew(PyObject *name_obj, if (initial_ctx) { EVP_MD_CTX_copy(self->ctx, initial_ctx); } else { @@ -506,7 +506,7 @@ index de69f6f..b2c2956 100644 } if (cp && len) { -@@ -532,20 +597,28 @@ PyDoc_STRVAR(EVP_new__doc__, +@@ -534,20 +599,28 @@ PyDoc_STRVAR(EVP_new__doc__, An optional string argument may be provided and will be\n\ automatically hashed.\n\ \n\ @@ -539,7 +539,7 @@ index de69f6f..b2c2956 100644 return NULL; } -@@ -558,7 +631,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict) +@@ -560,7 +633,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict) digest = EVP_get_digestbyname(name); ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, @@ -548,7 +548,7 @@ index de69f6f..b2c2956 100644 PyBuffer_Release(&view); return ret_obj; -@@ -818,51 +891,111 @@ generate_hash_name_list(void) +@@ -820,51 +893,111 @@ generate_hash_name_list(void) /* @@ -690,9 +690,9 @@ index de69f6f..b2c2956 100644 GEN_CONSTRUCTOR(md5) GEN_CONSTRUCTOR(sha1) #ifdef _OPENSSL_SUPPORTS_SHA2 -@@ -901,6 +1034,8 @@ init_hashlib(void) +@@ -903,6 +1036,8 @@ init_hashlib(void) - #ifndef OPENSSL_VERSION_1_1 + #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) /* Load all digest algorithms and initialize cpuid */ + SSL_load_error_strings(); + SSL_library_init(); @@ -700,10 +700,10 @@ index de69f6f..b2c2956 100644 ERR_load_crypto_strings(); #endif diff --git a/setup.py b/setup.py -index e728e17..b210cd7 100644 +index 77e3a40..b401ab8 100644 --- a/setup.py +++ b/setup.py -@@ -874,21 +874,6 @@ class PyBuildExt(build_ext): +@@ -920,21 +920,6 @@ class PyBuildExt(build_ext): print ("warning: openssl 0x%08x is too old for _hashlib" % openssl_ver) missing.append('_hashlib') diff --git a/SOURCES/00153-fix-test_gdb-noise.patch b/SOURCES/00153-fix-test_gdb-noise.patch deleted file mode 100644 index b32f47a..0000000 --- a/SOURCES/00153-fix-test_gdb-noise.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py -index dec290b..b3541f0 100644 ---- a/Lib/test/test_gdb.py -+++ b/Lib/test/test_gdb.py -@@ -260,6 +260,10 @@ class DebuggerTests(unittest.TestCase): - # ignore all warnings - 'warning: ', - ) -+ ignore_patterns += ('warning: Unable to open', -+ 'Missing separate debuginfo for', -+ 'Try: yum --disablerepo=', -+ 'Undefined set print command') - for line in errlines: - if not line: - continue diff --git a/SOURCES/00157-uid-gid-overflows.patch b/SOURCES/00157-uid-gid-overflows.patch deleted file mode 100644 index a31c98a..0000000 --- a/SOURCES/00157-uid-gid-overflows.patch +++ /dev/null @@ -1,49 +0,0 @@ -diff -up Python-2.7.3/Lib/test/test_os.py.uid-gid-overflows Python-2.7.3/Lib/test/test_os.py ---- Python-2.7.3/Lib/test/test_os.py.uid-gid-overflows 2012-04-09 19:07:32.000000000 -0400 -+++ Python-2.7.3/Lib/test/test_os.py 2012-06-26 14:51:36.000817929 -0400 -@@ -677,30 +677,36 @@ if sys.platform != 'win32': - def test_setuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setuid, 0) -+ self.assertRaises(TypeError, os.setuid, 'not an int') - self.assertRaises(OverflowError, os.setuid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()') - def test_setgid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setgid, 0) -+ self.assertRaises(TypeError, os.setgid, 'not an int') - self.assertRaises(OverflowError, os.setgid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()') - def test_seteuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.seteuid, 0) -+ self.assertRaises(TypeError, os.seteuid, 'not an int') - self.assertRaises(OverflowError, os.seteuid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()') - def test_setegid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setegid, 0) -+ self.assertRaises(TypeError, os.setegid, 'not an int') - self.assertRaises(OverflowError, os.setegid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()') - def test_setreuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setreuid, 0, 0) -+ self.assertRaises(TypeError, os.setreuid, 'not an int', 0) -+ self.assertRaises(TypeError, os.setreuid, 0, 'not an int') - self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) - self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) - -@@ -715,6 +721,8 @@ if sys.platform != 'win32': - def test_setregid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setregid, 0, 0) -+ self.assertRaises(TypeError, os.setregid, 'not an int', 0) -+ self.assertRaises(TypeError, os.setregid, 0, 'not an int') - self.assertRaises(OverflowError, os.setregid, 1<<32, 0) - self.assertRaises(OverflowError, os.setregid, 0, 1<<32) - diff --git a/SOURCES/00168-distutils-cflags.patch b/SOURCES/00168-distutils-cflags.patch deleted file mode 100644 index 0c4a8df..0000000 --- a/SOURCES/00168-distutils-cflags.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up Python-2.6.6/Lib/distutils/sysconfig.py.distutils-cflags Python-2.6.6/Lib/distutils/sysconfig.py ---- Python-2.6.6/Lib/distutils/sysconfig.py.distutils-cflags 2011-08-12 17:18:17.833091153 -0400 -+++ Python-2.6.6/Lib/distutils/sysconfig.py 2011-08-12 17:18:27.449106938 -0400 -@@ -187,7 +187,7 @@ def customize_compiler(compiler): - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: -- cflags = opt + ' ' + os.environ['CFLAGS'] -+ cflags = cflags + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] diff --git a/SOURCES/00189-gdb-py-bt-dont-raise-exception-from-eval.patch b/SOURCES/00189-gdb-py-bt-dont-raise-exception-from-eval.patch deleted file mode 100644 index 45f9eb3..0000000 --- a/SOURCES/00189-gdb-py-bt-dont-raise-exception-from-eval.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py -index 9def56e..d98cb2d 100755 ---- a/Tools/gdb/libpython.py -+++ b/Tools/gdb/libpython.py -@@ -938,6 +938,8 @@ class PyFrameObjectPtr(PyObjectPtr): - newline character''' - if self.is_optimized_out(): - return '(frame information optimized out)' -+ if self.filename() == '': -+ return '(in an eval block)' - - lineno = self.current_line_num() - if lineno is None: diff --git a/SOURCES/00320-CVE-2019-9636-and-CVE-2019-10160.patch b/SOURCES/00320-CVE-2019-9636-and-CVE-2019-10160.patch deleted file mode 100644 index 670f3e4..0000000 --- a/SOURCES/00320-CVE-2019-9636-and-CVE-2019-10160.patch +++ /dev/null @@ -1,152 +0,0 @@ -diff --git a/Doc/library/urlparse.rst b/Doc/library/urlparse.rst -index 22249da..0989c88 100644 ---- a/Doc/library/urlparse.rst -+++ b/Doc/library/urlparse.rst -@@ -119,12 +119,22 @@ The :mod:`urlparse` module defines the following functions: - See section :ref:`urlparse-result-object` for more information on the result - object. - -+ Characters in the :attr:`netloc` attribute that decompose under NFKC -+ normalization (as used by the IDNA encoding) into any of ``/``, ``?``, -+ ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is -+ decomposed before parsing, or is not a Unicode string, no error will be -+ raised. -+ - .. versionchanged:: 2.5 - Added attributes to return value. - - .. versionchanged:: 2.7 - Added IPv6 URL parsing capabilities. - -+ .. versionchanged:: 2.7.17 -+ Characters that affect netloc parsing under NFKC normalization will -+ now raise :exc:`ValueError`. -+ - - .. function:: parse_qs(qs[, keep_blank_values[, strict_parsing[, max_num_fields]]]) - -@@ -232,11 +242,21 @@ The :mod:`urlparse` module defines the following functions: - See section :ref:`urlparse-result-object` for more information on the result - object. - -+ Characters in the :attr:`netloc` attribute that decompose under NFKC -+ normalization (as used by the IDNA encoding) into any of ``/``, ``?``, -+ ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is -+ decomposed before parsing, or is not a Unicode string, no error will be -+ raised. -+ - .. versionadded:: 2.2 - - .. versionchanged:: 2.5 - Added attributes to return value. - -+ .. versionchanged:: 2.7.17 -+ Characters that affect netloc parsing under NFKC normalization will -+ now raise :exc:`ValueError`. -+ - - .. function:: urlunsplit(parts) - -diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py -index 4e1ded7..86c4a05 100644 ---- a/Lib/test/test_urlparse.py -+++ b/Lib/test/test_urlparse.py -@@ -1,4 +1,6 @@ - from test import test_support -+import sys -+import unicodedata - import unittest - import urlparse - -@@ -624,6 +626,45 @@ class UrlParseTestCase(unittest.TestCase): - self.assertEqual(urlparse.urlparse("http://www.python.org:80"), - ('http','www.python.org:80','','','','')) - -+ def test_urlsplit_normalization(self): -+ # Certain characters should never occur in the netloc, -+ # including under normalization. -+ # Ensure that ALL of them are detected and cause an error -+ illegal_chars = u'/:#?@' -+ hex_chars = {'{:04X}'.format(ord(c)) for c in illegal_chars} -+ denorm_chars = [ -+ c for c in map(unichr, range(128, sys.maxunicode)) -+ if (hex_chars & set(unicodedata.decomposition(c).split())) -+ and c not in illegal_chars -+ ] -+ # Sanity check that we found at least one such character -+ self.assertIn(u'\u2100', denorm_chars) -+ self.assertIn(u'\uFF03', denorm_chars) -+ -+ # bpo-36742: Verify port separators are ignored when they -+ # existed prior to decomposition -+ urlparse.urlsplit(u'http://\u30d5\u309a:80') -+ with self.assertRaises(ValueError): -+ urlparse.urlsplit(u'http://\u30d5\u309a\ufe1380') -+ -+ for scheme in [u"http", u"https", u"ftp"]: -+ for netloc in [u"netloc{}false.netloc", u"n{}user@netloc"]: -+ for c in denorm_chars: -+ url = u"{}://{}/path".format(scheme, netloc.format(c)) -+ if test_support.verbose: -+ print "Checking %r" % url -+ with self.assertRaises(ValueError): -+ urlparse.urlsplit(url) -+ -+ # check error message: invalid netloc must be formated with repr() -+ # to get an ASCII error message -+ with self.assertRaises(ValueError) as cm: -+ urlparse.urlsplit(u'http://example.com\uFF03@bing.com') -+ self.assertEqual(str(cm.exception), -+ "netloc u'example.com\\uff03@bing.com' contains invalid characters " -+ "under NFKC normalization") -+ self.assertIsInstance(cm.exception.args[0], str) -+ - def test_main(): - test_support.run_unittest(UrlParseTestCase) - -diff --git a/Lib/urlparse.py b/Lib/urlparse.py -index f7c2b03..798b467 100644 ---- a/Lib/urlparse.py -+++ b/Lib/urlparse.py -@@ -165,6 +165,25 @@ def _splitnetloc(url, start=0): - delim = min(delim, wdelim) # use earliest delim position - return url[start:delim], url[delim:] # return (domain, rest) - -+def _checknetloc(netloc): -+ if not netloc or not isinstance(netloc, unicode): -+ return -+ # looking for characters like \u2100 that expand to 'a/c' -+ # IDNA uses NFKC equivalence, so normalize for this check -+ import unicodedata -+ n = netloc.replace(u'@', u'') # ignore characters already included -+ n = n.replace(u':', u'') # but not the surrounding text -+ n = n.replace(u'#', u'') -+ n = n.replace(u'?', u'') -+ netloc2 = unicodedata.normalize('NFKC', n) -+ if n == netloc2: -+ return -+ for c in '/?#@:': -+ if c in netloc2: -+ raise ValueError("netloc %r contains invalid characters " -+ "under NFKC normalization" -+ % netloc) -+ - def urlsplit(url, scheme='', allow_fragments=True): - """Parse a URL into 5 components: - :///?# -@@ -193,6 +212,7 @@ def urlsplit(url, scheme='', allow_fragments=True): - url, fragment = url.split('#', 1) - if '?' in url: - url, query = url.split('?', 1) -+ _checknetloc(netloc) - v = SplitResult(scheme, netloc, url, query, fragment) - _parse_cache[key] = v - return v -@@ -216,6 +236,7 @@ def urlsplit(url, scheme='', allow_fragments=True): - url, fragment = url.split('#', 1) - if '?' in url: - url, query = url.split('?', 1) -+ _checknetloc(netloc) - v = SplitResult(scheme, netloc, url, query, fragment) - _parse_cache[key] = v - return v diff --git a/SOURCES/00324-disallow-control-chars-in-http-urls.patch b/SOURCES/00324-disallow-control-chars-in-http-urls.patch deleted file mode 100644 index 7d52fa6..0000000 --- a/SOURCES/00324-disallow-control-chars-in-http-urls.patch +++ /dev/null @@ -1,165 +0,0 @@ -diff --git a/Lib/httplib.py b/Lib/httplib.py -index 60a8fb4..1b41c34 100644 ---- a/Lib/httplib.py -+++ b/Lib/httplib.py -@@ -247,6 +247,16 @@ _MAXHEADERS = 100 - _is_legal_header_name = re.compile(r'\A[^:\s][^:\r\n]*\Z').match - _is_illegal_header_value = re.compile(r'\n(?![ \t])|\r(?![ \t\n])').search - -+# These characters are not allowed within HTTP URL paths. -+# See https://tools.ietf.org/html/rfc3986#section-3.3 and the -+# https://tools.ietf.org/html/rfc3986#appendix-A pchar definition. -+# Prevents CVE-2019-9740. Includes control characters such as \r\n. -+# Restrict non-ASCII characters above \x7f (0x80-0xff). -+_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f-\xff]') -+# Arguably only these _should_ allowed: -+# _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$") -+# We are more lenient for assumed real world compatibility purposes. -+ - # We always set the Content-Length header for these methods because some - # servers will otherwise respond with a 411 - _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'} -@@ -927,6 +937,12 @@ class HTTPConnection: - self._method = method - if not url: - url = '/' -+ # Prevent CVE-2019-9740. -+ match = _contains_disallowed_url_pchar_re.search(url) -+ if match: -+ raise InvalidURL("URL can't contain control characters. %r " -+ "(found at least %r)" -+ % (url, match.group())) - hdr = '%s %s %s' % (method, url, self._http_vsn_str) - - self._output(hdr) -diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py -index 1ce9201..d7778d4 100644 ---- a/Lib/test/test_urllib.py -+++ b/Lib/test/test_urllib.py -@@ -257,6 +257,31 @@ class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin): - finally: - self.unfakehttp() - -+ def test_url_with_control_char_rejected(self): -+ for char_no in range(0, 0x21) + range(0x7f, 0x100): -+ char = chr(char_no) -+ schemeless_url = "//localhost:7777/test%s/" % char -+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") -+ try: -+ # urllib quotes the URL so there is no injection. -+ resp = urllib.urlopen("http:" + schemeless_url) -+ self.assertNotIn(char, resp.geturl()) -+ finally: -+ self.unfakehttp() -+ -+ def test_url_with_newline_header_injection_rejected(self): -+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") -+ host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123" -+ schemeless_url = "//" + host + ":8080/test/?test=a" -+ try: -+ # urllib quotes the URL so there is no injection. -+ resp = urllib.urlopen("http:" + schemeless_url) -+ self.assertNotIn(' ', resp.geturl()) -+ self.assertNotIn('\r', resp.geturl()) -+ self.assertNotIn('\n', resp.geturl()) -+ finally: -+ self.unfakehttp() -+ - def test_read_bogus(self): - # urlopen() should raise IOError for many error codes. - self.fakehttp('''HTTP/1.1 401 Authentication Required -diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py -index 6d24d5d..9531818 100644 ---- a/Lib/test/test_urllib2.py -+++ b/Lib/test/test_urllib2.py -@@ -15,6 +15,9 @@ try: - except ImportError: - ssl = None - -+from test.test_urllib import FakeHTTPMixin -+ -+ - # XXX - # Request - # CacheFTPHandler (hard to write) -@@ -1262,7 +1265,7 @@ class HandlerTests(unittest.TestCase): - self.assertEqual(len(http_handler.requests), 1) - self.assertFalse(http_handler.requests[0].has_header(auth_header)) - --class MiscTests(unittest.TestCase): -+class MiscTests(unittest.TestCase, FakeHTTPMixin): - - def test_build_opener(self): - class MyHTTPHandler(urllib2.HTTPHandler): pass -@@ -1317,6 +1320,52 @@ class MiscTests(unittest.TestCase): - "Unsupported digest authentication algorithm 'invalid'" - ) - -+ @unittest.skipUnless(ssl, "ssl module required") -+ def test_url_with_control_char_rejected(self): -+ for char_no in range(0, 0x21) + range(0x7f, 0x100): -+ char = chr(char_no) -+ schemeless_url = "//localhost:7777/test%s/" % char -+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") -+ try: -+ # We explicitly test urllib.request.urlopen() instead of the top -+ # level 'def urlopen()' function defined in this... (quite ugly) -+ # test suite. They use different url opening codepaths. Plain -+ # urlopen uses FancyURLOpener which goes via a codepath that -+ # calls urllib.parse.quote() on the URL which makes all of the -+ # above attempts at injection within the url _path_ safe. -+ escaped_char_repr = repr(char).replace('\\', r'\\') -+ InvalidURL = httplib.InvalidURL -+ with self.assertRaisesRegexp( -+ InvalidURL, "contain control.*" + escaped_char_repr): -+ urllib2.urlopen("http:" + schemeless_url) -+ with self.assertRaisesRegexp( -+ InvalidURL, "contain control.*" + escaped_char_repr): -+ urllib2.urlopen("https:" + schemeless_url) -+ finally: -+ self.unfakehttp() -+ -+ @unittest.skipUnless(ssl, "ssl module required") -+ def test_url_with_newline_header_injection_rejected(self): -+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") -+ host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123" -+ schemeless_url = "//" + host + ":8080/test/?test=a" -+ try: -+ # We explicitly test urllib2.urlopen() instead of the top -+ # level 'def urlopen()' function defined in this... (quite ugly) -+ # test suite. They use different url opening codepaths. Plain -+ # urlopen uses FancyURLOpener which goes via a codepath that -+ # calls urllib.parse.quote() on the URL which makes all of the -+ # above attempts at injection within the url _path_ safe. -+ InvalidURL = httplib.InvalidURL -+ with self.assertRaisesRegexp( -+ InvalidURL, r"contain control.*\\r.*(found at least . .)"): -+ urllib2.urlopen("http:" + schemeless_url) -+ with self.assertRaisesRegexp(InvalidURL, r"contain control.*\\n"): -+ urllib2.urlopen("https:" + schemeless_url) -+ finally: -+ self.unfakehttp() -+ -+ - - class RequestTests(unittest.TestCase): - -diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py -index 36b3be6..90ccb30 100644 ---- a/Lib/test/test_xmlrpc.py -+++ b/Lib/test/test_xmlrpc.py -@@ -659,7 +659,13 @@ class SimpleServerTestCase(BaseServerTestCase): - def test_partial_post(self): - # Check that a partial POST doesn't make the server loop: issue #14001. - conn = httplib.HTTPConnection(ADDR, PORT) -- conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye') -+ conn.send('POST /RPC2 HTTP/1.0\r\n' -+ 'Content-Length: 100\r\n\r\n' -+ 'bye HTTP/1.1\r\n' -+ 'Host: %s:%s\r\n' -+ 'Accept-Encoding: identity\r\n' -+ 'Content-Length: 0\r\n\r\n' -+ % (ADDR, PORT)) - conn.close() - - class SimpleServerEncodingTestCase(BaseServerTestCase): diff --git a/SOURCES/00325-CVE-2019-9948.patch b/SOURCES/00325-CVE-2019-9948.patch deleted file mode 100644 index 890bf71..0000000 --- a/SOURCES/00325-CVE-2019-9948.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py -index d2da0f8..7813b9f 100644 ---- a/Lib/test/test_urllib.py -+++ b/Lib/test/test_urllib.py -@@ -872,6 +872,17 @@ class URLopener_Tests(unittest.TestCase): - "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"), - "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/") - -+ def test_local_file_open(self): -+ # bpo-35907, CVE-2019-9948: urllib must reject local_file:// scheme -+ class DummyURLopener(urllib.URLopener): -+ def open_local_file(self, url): -+ return url -+ for url in ('local_file://example', 'local-file://example'): -+ self.assertRaises(IOError, urllib.urlopen, url) -+ self.assertRaises(IOError, urllib.URLopener().open, url) -+ self.assertRaises(IOError, urllib.URLopener().retrieve, url) -+ self.assertRaises(IOError, DummyURLopener().open, url) -+ self.assertRaises(IOError, DummyURLopener().retrieve, url) - - # Just commented them out. - # Can't really tell why keep failing in windows and sparc. -diff --git a/Lib/urllib.py b/Lib/urllib.py -index 2201e3e..71e3637 100644 ---- a/Lib/urllib.py -+++ b/Lib/urllib.py -@@ -198,7 +198,9 @@ class URLopener: - name = 'open_' + urltype - self.type = urltype - name = name.replace('-', '_') -- if not hasattr(self, name): -+ -+ # bpo-35907: disallow the file reading with the type not allowed -+ if not hasattr(self, name) or name == 'open_local_file': - if proxy: - return self.open_unknown_proxy(proxy, fullurl, data) - else: diff --git a/SPECS/python.spec b/SPECS/python.spec index f52f4b0..dca64b9 100644 --- a/SPECS/python.spec +++ b/SPECS/python.spec @@ -121,8 +121,8 @@ Summary: An interpreted, interactive, object-oriented programming language Name: %{?scl_prefix}%{python} # Remember to also rebase python-docs when changing this: -Version: 2.7.16 -Release: 6%{?dist} +Version: 2.7.17 +Release: 2%{?dist} License: Python Group: Development/Languages %{?scl:Requires: %{scl}-runtime} @@ -593,13 +593,6 @@ Patch146: 00146-hashlib-fips.patch # Sent upstream as http://bugs.python.org/issue14785 Patch147: 00147-add-debug-malloc-stats.patch -# 00153 # -# Strip out lines of the form "warning: Unable to open ..." from gdb's stderr -# when running test_gdb.py; also cope with change to gdb in F17 onwards in -# which values are printed as "v@entry" rather than just "v": -# Not yet sent upstream -Patch153: 00153-fix-test_gdb-noise.patch - # 00155 # # Avoid allocating thunks in ctypes unless absolutely necessary, to avoid # generating SELinux denials on "import ctypes" and "import uuid" when @@ -613,22 +606,6 @@ Patch155: 00155-avoid-ctypes-thunks.patch # Not yet sent upstream Patch156: 00156-gdb-autoload-safepath.patch -# 00157 # -# Update uid/gid handling throughout the standard library: uid_t and gid_t are -# unsigned 32-bit values, but existing code often passed them through C long -# values, which are signed 32-bit values on 32-bit architectures, leading to -# negative int objects for uid/gid values >= 2^31 on 32-bit architectures. -# -# Introduce _PyObject_FromUid/Gid to convert uid_t/gid_t values to python -# objects, using int objects where the value will fit (long objects otherwise), -# and _PyArg_ParseUid/Gid to convert int/long to uid_t/gid_t, with -1 allowed -# as a special case (since this is given special meaning by the chown syscall) -# -# Update standard library to use this throughout for uid/gid values, so that -# very large uid/gid values are round-trippable, and -1 remains usable. -# (rhbz#697470) -Patch157: 00157-uid-gid-overflows.patch - # 00165 # # Backport to Python 2 from Python 3.3 of improvements to the "crypt" module # adding precanned ways of salting a password (rhbz#835021) @@ -647,18 +624,6 @@ Patch165: 00165-crypt-module-salt-backport.patch # Not yet sent upstream Patch167: 00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch -# 00168 # -# Update distutils.sysconfig so that if CFLAGS is defined in the environment, -# when building extension modules, it is appended to the full compilation -# flags from Python's Makefile, rather than instead reducing the compilation -# flags to the subset within OPT and adding it to those. -# -# In particular, this should ensure that "-fno-strict-aliasing" is used by -# "python setup.py build" even when CFLAGS is defined in the environment. -# -# (rhbz#849994) -Patch168: 00168-distutils-cflags.patch - # 00169 # # Use SHA-256 rather than implicitly using MD5 within the challenge handling # in multiprocessing.connection @@ -719,12 +684,6 @@ Patch185: 00185-urllib2-honors-noproxy-for-ftp.patch # symbol) Patch187: 00187-add-RPATH-to-pyexpat.patch -# 00189 # -# Fixes gdb py-bt command not to raise exception while processing -# statements from eval -# rhbz#1008154 (patch by Attila Fazekas) -Patch189: 00189-gdb-py-bt-dont-raise-exception-from-eval.patch - # 00191 # # # Disabling NOOP test as it fails without internet connection @@ -740,28 +699,6 @@ Patch198: 00198-add-rewheel-module.patch # Resolves: rhbz#1417838 and previously rhbz#1219108 Patch224: 00224-PEP-493-Re-add-file-based-configuration-of-HTTPS-ver.patch -# 00320 # -# Security fix for CVE-2019-9636 and CVE-2019-10160: Information Disclosure due to urlsplit improper NFKC normalization -# FIXED UPSTREAM: https://bugs.python.org/issue36216 and https://bugs.python.org/issue36742 -# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689326 -# and https://bugzilla.redhat.com/show_bug.cgi?id=1718924 -Patch320: 00320-CVE-2019-9636-and-CVE-2019-10160.patch - -# 00324 # -# Disallow control chars in http URLs -# Security fix for CVE-2019-9740 and CVE-2019-9947 -# Fixed upstream: https://bugs.python.org/issue30458 -# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1703534 -# and https://bugzilla.redhat.com/show_bug.cgi?id=1704372 -Patch324: 00324-disallow-control-chars-in-http-urls.patch - -# 00325 # -# Unnecessary URL scheme exists to allow local_file:// reading file in urllib -# Security fix for CVE-2019-9948 -# Fixed upstream: https://bugs.python.org/issue35907 -# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1709404 -Patch325: 00325-CVE-2019-9948.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora 17 onwards, @@ -1077,14 +1014,11 @@ done %endif %patch146 -p1 %patch147 -p1 -%patch153 -p1 %patch155 -p1 %patch156 -p1 -%patch157 -p1 %patch165 -p1 mv Modules/cryptmodule.c Modules/_cryptmodule.c %patch167 -p1 -%patch168 -p1 %patch169 -p1 %patch170 -p1 %patch173 -p1 @@ -1093,15 +1027,11 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c %patch181 -p1 %patch185 -p1 %patch187 -p1 -%patch189 -p1 %patch191 -p1 %if 0%{with_rewheel} %patch198 -p1 %endif %patch224 -p1 -%patch320 -p1 -%patch324 -p1 -%patch325 -p1 # This shouldn't be necesarry, but is right now (2.2a3) find -name "*~" |xargs rm -f @@ -1422,9 +1352,6 @@ mv pydoc pydoc%{__python_ver} popd %endif -# Fix for bug #136654 -rm -f %{buildroot}%{pylibdir}/email/test/data/audiotest.au %{buildroot}%{pylibdir}/test/audiotest.au - # Fix bug #143667: python should own /usr/lib/python2.x on 64-bit machines %if "%{_lib}" == "lib64" install -d %{buildroot}%{_prefix}/lib/python%{pybasever}/site-packages @@ -1976,6 +1903,14 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Fri Nov 15 2019 Charalampos Stratakis - 2.7.17-2 +- Rebuild to regenerate properly the pyc and pyo files +Resolves: rhbz#1767887 + +* Thu Nov 07 2019 Charalampos Stratakis - 2.7.17-1 +- Update to 2.7.17 +Resolves: rhbz#1767887 + * Tue Jun 11 2019 Charalampos Stratakis - 2.7.16-6 - Security fix for CVE-2019-10160 Resolves: rhbz#1718924