import python3-3.6.8-31.el8
This commit is contained in:
parent
08ad15e6fb
commit
87132fa408
@ -200,3 +200,19 @@ index 0f2dfc4..da37896 100644
|
||||
] )
|
||||
|
||||
if (ssl_incs is not None and
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 01c66fe..1e6d515 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -4772,9 +4772,9 @@ AC_MSG_RESULT($LDVERSION)
|
||||
dnl define LIBPL after ABIFLAGS and LDVERSION is defined.
|
||||
AC_SUBST(PY_ENABLE_SHARED)
|
||||
if test x$PLATFORM_TRIPLET = x; then
|
||||
- LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}"
|
||||
+ LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}"
|
||||
else
|
||||
- LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}"
|
||||
+ LIBPL='$(prefix)'"/lib64/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}"
|
||||
fi
|
||||
AC_SUBST(LIBPL)
|
||||
|
||||
|
@ -1,30 +0,0 @@
|
||||
diff -r 39b9b05c3085 Lib/distutils/sysconfig.py
|
||||
--- a/Lib/distutils/sysconfig.py Wed Apr 10 00:27:23 2013 +0200
|
||||
+++ b/Lib/distutils/sysconfig.py Wed Apr 10 10:14:18 2013 +0200
|
||||
@@ -362,7 +362,10 @@
|
||||
done[n] = item = ""
|
||||
if found:
|
||||
after = value[m.end():]
|
||||
- value = value[:m.start()] + item + after
|
||||
+ value = value[:m.start()]
|
||||
+ if item.strip() not in value:
|
||||
+ value += item
|
||||
+ value += after
|
||||
if "$" in after:
|
||||
notdone[name] = value
|
||||
else:
|
||||
diff -r 39b9b05c3085 Lib/sysconfig.py
|
||||
--- a/Lib/sysconfig.py Wed Apr 10 00:27:23 2013 +0200
|
||||
+++ b/Lib/sysconfig.py Wed Apr 10 10:14:18 2013 +0200
|
||||
@@ -296,7 +296,10 @@
|
||||
|
||||
if found:
|
||||
after = value[m.end():]
|
||||
- value = value[:m.start()] + item + after
|
||||
+ value = value[:m.start()]
|
||||
+ if item.strip() not in value:
|
||||
+ value += item
|
||||
+ value += after
|
||||
if "$" in after:
|
||||
notdone[name] = value
|
||||
else:
|
@ -1,12 +0,0 @@
|
||||
diff -up Python-3.5.0/Makefile.pre.in.lib Python-3.5.0/Makefile.pre.in
|
||||
--- Python-3.5.0/Makefile.pre.in.lib 2015-09-21 15:39:47.928286620 +0200
|
||||
+++ Python-3.5.0/Makefile.pre.in 2015-09-21 15:42:58.004042762 +0200
|
||||
@@ -1340,7 +1340,7 @@ inclinstall:
|
||||
|
||||
# Install the library and miscellaneous stuff needed for extending/embedding
|
||||
# This goes into $(exec_prefix)
|
||||
-LIBPL= @LIBPL@
|
||||
+LIBPL= $(LIBDEST)/config-$(LDVERSION)-$(MULTIARCH)
|
||||
|
||||
# pkgconfig directory
|
||||
LIBPC= $(LIBDIR)/pkgconfig
|
File diff suppressed because it is too large
Load Diff
22
SOURCES/00338-fix-test_gdb-for-LTO.patch
Normal file
22
SOURCES/00338-fix-test_gdb-for-LTO.patch
Normal file
@ -0,0 +1,22 @@
|
||||
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py
|
||||
index 9c15fca..c972409 100644
|
||||
--- a/Lib/test/test_gdb.py
|
||||
+++ b/Lib/test/test_gdb.py
|
||||
@@ -279,8 +279,15 @@ class DebuggerTests(unittest.TestCase):
|
||||
# gdb can insert additional '\n' and space characters in various places
|
||||
# in its output, depending on the width of the terminal it's connected
|
||||
# to (using its "wrap_here" function)
|
||||
- m = re.match(r'.*#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)\)\s+at\s+\S*Python/bltinmodule.c.*',
|
||||
- gdb_output, re.DOTALL)
|
||||
+ m = re.search(
|
||||
+ # Match '#0 builtin_id(self=..., v=...)'
|
||||
+ r'#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)?\)'
|
||||
+ # Match ' at Python/bltinmodule.c'.
|
||||
+ # bpo-38239: builtin_id() is defined in Python/bltinmodule.c,
|
||||
+ # but accept any "Directory\file.c" to support Link Time
|
||||
+ # Optimization (LTO).
|
||||
+ r'\s+at\s+\S*[A-Za-z]+/[A-Za-z0-9_-]+\.c',
|
||||
+ gdb_output, re.DOTALL)
|
||||
if not m:
|
||||
self.fail('Unexpected gdb output: %r\n%s' % (gdb_output, gdb_output))
|
||||
return m.group(1), gdb_output
|
54
SOURCES/00344-CVE-2019-16935.patch
Normal file
54
SOURCES/00344-CVE-2019-16935.patch
Normal file
@ -0,0 +1,54 @@
|
||||
diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py
|
||||
index 0090333..d2adb21 100644
|
||||
--- a/Lib/test/test_docxmlrpc.py
|
||||
+++ b/Lib/test/test_docxmlrpc.py
|
||||
@@ -1,5 +1,6 @@
|
||||
from xmlrpc.server import DocXMLRPCServer
|
||||
import http.client
|
||||
+import re
|
||||
import sys
|
||||
from test import support
|
||||
threading = support.import_module('threading')
|
||||
@@ -193,6 +194,21 @@ class DocXMLRPCHTTPGETServer(unittest.TestCase):
|
||||
b'method_annotation</strong></a>(x: bytes)</dt></dl>'),
|
||||
response.read())
|
||||
|
||||
+ def test_server_title_escape(self):
|
||||
+ # bpo-38243: Ensure that the server title and documentation
|
||||
+ # are escaped for HTML.
|
||||
+ self.serv.set_server_title('test_title<script>')
|
||||
+ self.serv.set_server_documentation('test_documentation<script>')
|
||||
+ self.assertEqual('test_title<script>', self.serv.server_title)
|
||||
+ self.assertEqual('test_documentation<script>',
|
||||
+ self.serv.server_documentation)
|
||||
+
|
||||
+ generated = self.serv.generate_html_documentation()
|
||||
+ title = re.search(r'<title>(.+?)</title>', generated).group()
|
||||
+ documentation = re.search(r'<p><tt>(.+?)</tt></p>', generated).group()
|
||||
+ self.assertEqual('<title>Python: test_title<script></title>', title)
|
||||
+ self.assertEqual('<p><tt>test_documentation<script></tt></p>', documentation)
|
||||
+
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py
|
||||
index 3e0dca0..efe5937 100644
|
||||
--- a/Lib/xmlrpc/server.py
|
||||
+++ b/Lib/xmlrpc/server.py
|
||||
@@ -106,6 +106,7 @@ server.handle_request()
|
||||
|
||||
from xmlrpc.client import Fault, dumps, loads, gzip_encode, gzip_decode
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
+import html
|
||||
import http.server
|
||||
import socketserver
|
||||
import sys
|
||||
@@ -904,7 +905,7 @@ class XMLRPCDocGenerator:
|
||||
methods
|
||||
)
|
||||
|
||||
- return documenter.page(self.server_title, documentation)
|
||||
+ return documenter.page(html.escape(self.server_title), documentation)
|
||||
|
||||
class DocXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||
"""XML-RPC and documentation request handler class.
|
44
SOURCES/00345-fix-test_site-with-extra-pth-files.patch
Normal file
44
SOURCES/00345-fix-test_site-with-extra-pth-files.patch
Normal file
@ -0,0 +1,44 @@
|
||||
diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
|
||||
index d0cd84f..9d2c28c 100644
|
||||
--- a/Lib/test/test_site.py
|
||||
+++ b/Lib/test/test_site.py
|
||||
@@ -10,6 +10,7 @@ from test import support
|
||||
from test.support import (captured_stderr, TESTFN, EnvironmentVarGuard,
|
||||
change_cwd)
|
||||
import builtins
|
||||
+import glob
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
@@ -500,6 +501,23 @@ class ImportSideEffectTests(unittest.TestCase):
|
||||
class StartupImportTests(unittest.TestCase):
|
||||
|
||||
def test_startup_imports(self):
|
||||
+ # Get sys.path in isolated mode (python3 -I)
|
||||
+ popen = subprocess.Popen([sys.executable, '-I', '-c',
|
||||
+ 'import sys; print(repr(sys.path))'],
|
||||
+ stdout=subprocess.PIPE,
|
||||
+ encoding='utf-8')
|
||||
+ stdout = popen.communicate()[0]
|
||||
+ self.assertEqual(popen.returncode, 0, repr(stdout))
|
||||
+ isolated_paths = eval(stdout)
|
||||
+
|
||||
+ # bpo-27807: Even with -I, the site module executes all .pth files
|
||||
+ # found in sys.path (see site.addpackage()). Skip the test if at least
|
||||
+ # one .pth file is found.
|
||||
+ for path in isolated_paths:
|
||||
+ pth_files = glob.glob(os.path.join(path, "*.pth"))
|
||||
+ if pth_files:
|
||||
+ self.skipTest(f"found {len(pth_files)} .pth files in: {path}")
|
||||
+
|
||||
# This tests checks which modules are loaded by Python when it
|
||||
# initially starts upon startup.
|
||||
popen = subprocess.Popen([sys.executable, '-I', '-v', '-c',
|
||||
@@ -508,6 +526,7 @@ class StartupImportTests(unittest.TestCase):
|
||||
stderr=subprocess.PIPE,
|
||||
encoding='utf-8')
|
||||
stdout, stderr = popen.communicate()
|
||||
+ self.assertEqual(popen.returncode, 0, (stdout, stderr))
|
||||
modules = eval(stdout)
|
||||
|
||||
self.assertIn('site', modules)
|
193
SOURCES/00346-CVE-2020-8492.patch
Normal file
193
SOURCES/00346-CVE-2020-8492.patch
Normal file
@ -0,0 +1,193 @@
|
||||
diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py
|
||||
index 876fcd4..fe9a32b 100644
|
||||
--- a/Lib/test/test_urllib2.py
|
||||
+++ b/Lib/test/test_urllib2.py
|
||||
@@ -1445,40 +1445,64 @@ class HandlerTests(unittest.TestCase):
|
||||
bypass = {'exclude_simple': True, 'exceptions': []}
|
||||
self.assertTrue(_proxy_bypass_macosx_sysconf('test', bypass))
|
||||
|
||||
- def test_basic_auth(self, quote_char='"'):
|
||||
- opener = OpenerDirector()
|
||||
- password_manager = MockPasswordManager()
|
||||
- auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager)
|
||||
- realm = "ACME Widget Store"
|
||||
- http_handler = MockHTTPHandler(
|
||||
- 401, 'WWW-Authenticate: Basic realm=%s%s%s\r\n\r\n' %
|
||||
- (quote_char, realm, quote_char))
|
||||
- opener.add_handler(auth_handler)
|
||||
- opener.add_handler(http_handler)
|
||||
- self._test_basic_auth(opener, auth_handler, "Authorization",
|
||||
- realm, http_handler, password_manager,
|
||||
- "http://acme.example.com/protected",
|
||||
- "http://acme.example.com/protected",
|
||||
- )
|
||||
-
|
||||
- def test_basic_auth_with_single_quoted_realm(self):
|
||||
- self.test_basic_auth(quote_char="'")
|
||||
-
|
||||
- def test_basic_auth_with_unquoted_realm(self):
|
||||
- opener = OpenerDirector()
|
||||
- password_manager = MockPasswordManager()
|
||||
- auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager)
|
||||
- realm = "ACME Widget Store"
|
||||
- http_handler = MockHTTPHandler(
|
||||
- 401, 'WWW-Authenticate: Basic realm=%s\r\n\r\n' % realm)
|
||||
- opener.add_handler(auth_handler)
|
||||
- opener.add_handler(http_handler)
|
||||
- with self.assertWarns(UserWarning):
|
||||
+ def check_basic_auth(self, headers, realm):
|
||||
+ with self.subTest(realm=realm, headers=headers):
|
||||
+ opener = OpenerDirector()
|
||||
+ password_manager = MockPasswordManager()
|
||||
+ auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager)
|
||||
+ body = '\r\n'.join(headers) + '\r\n\r\n'
|
||||
+ http_handler = MockHTTPHandler(401, body)
|
||||
+ opener.add_handler(auth_handler)
|
||||
+ opener.add_handler(http_handler)
|
||||
self._test_basic_auth(opener, auth_handler, "Authorization",
|
||||
- realm, http_handler, password_manager,
|
||||
- "http://acme.example.com/protected",
|
||||
- "http://acme.example.com/protected",
|
||||
- )
|
||||
+ realm, http_handler, password_manager,
|
||||
+ "http://acme.example.com/protected",
|
||||
+ "http://acme.example.com/protected")
|
||||
+
|
||||
+ def test_basic_auth(self):
|
||||
+ realm = "realm2@example.com"
|
||||
+ realm2 = "realm2@example.com"
|
||||
+ basic = f'Basic realm="{realm}"'
|
||||
+ basic2 = f'Basic realm="{realm2}"'
|
||||
+ other_no_realm = 'Otherscheme xxx'
|
||||
+ digest = (f'Digest realm="{realm2}", '
|
||||
+ f'qop="auth, auth-int", '
|
||||
+ f'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", '
|
||||
+ f'opaque="5ccc069c403ebaf9f0171e9517f40e41"')
|
||||
+ for realm_str in (
|
||||
+ # test "quote" and 'quote'
|
||||
+ f'Basic realm="{realm}"',
|
||||
+ f"Basic realm='{realm}'",
|
||||
+
|
||||
+ # charset is ignored
|
||||
+ f'Basic realm="{realm}", charset="UTF-8"',
|
||||
+
|
||||
+ # Multiple challenges per header
|
||||
+ f'{basic}, {basic2}',
|
||||
+ f'{basic}, {other_no_realm}',
|
||||
+ f'{other_no_realm}, {basic}',
|
||||
+ f'{basic}, {digest}',
|
||||
+ f'{digest}, {basic}',
|
||||
+ ):
|
||||
+ headers = [f'WWW-Authenticate: {realm_str}']
|
||||
+ self.check_basic_auth(headers, realm)
|
||||
+
|
||||
+ # no quote: expect a warning
|
||||
+ with support.check_warnings(("Basic Auth Realm was unquoted",
|
||||
+ UserWarning)):
|
||||
+ headers = [f'WWW-Authenticate: Basic realm={realm}']
|
||||
+ self.check_basic_auth(headers, realm)
|
||||
+
|
||||
+ # Multiple headers: one challenge per header.
|
||||
+ # Use the first Basic realm.
|
||||
+ for challenges in (
|
||||
+ [basic, basic2],
|
||||
+ [basic, digest],
|
||||
+ [digest, basic],
|
||||
+ ):
|
||||
+ headers = [f'WWW-Authenticate: {challenge}'
|
||||
+ for challenge in challenges]
|
||||
+ self.check_basic_auth(headers, realm)
|
||||
|
||||
def test_proxy_basic_auth(self):
|
||||
opener = OpenerDirector()
|
||||
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
|
||||
index c9945d9..6624e04 100644
|
||||
--- a/Lib/urllib/request.py
|
||||
+++ b/Lib/urllib/request.py
|
||||
@@ -945,8 +945,15 @@ class AbstractBasicAuthHandler:
|
||||
|
||||
# allow for double- and single-quoted realm values
|
||||
# (single quotes are a violation of the RFC, but appear in the wild)
|
||||
- rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
|
||||
- 'realm=(["\']?)([^"\']*)\\2', re.I)
|
||||
+ rx = re.compile('(?:^|,)' # start of the string or ','
|
||||
+ '[ \t]*' # optional whitespaces
|
||||
+ '([^ \t]+)' # scheme like "Basic"
|
||||
+ '[ \t]+' # mandatory whitespaces
|
||||
+ # realm=xxx
|
||||
+ # realm='xxx'
|
||||
+ # realm="xxx"
|
||||
+ 'realm=(["\']?)([^"\']*)\\2',
|
||||
+ re.I)
|
||||
|
||||
# XXX could pre-emptively send auth info already accepted (RFC 2617,
|
||||
# end of section 2, and section 1.2 immediately after "credentials"
|
||||
@@ -958,27 +965,51 @@ class AbstractBasicAuthHandler:
|
||||
self.passwd = password_mgr
|
||||
self.add_password = self.passwd.add_password
|
||||
|
||||
+ def _parse_realm(self, header):
|
||||
+ # parse WWW-Authenticate header: accept multiple challenges per header
|
||||
+ found_challenge = False
|
||||
+ for mo in AbstractBasicAuthHandler.rx.finditer(header):
|
||||
+ scheme, quote, realm = mo.groups()
|
||||
+ if quote not in ['"', "'"]:
|
||||
+ warnings.warn("Basic Auth Realm was unquoted",
|
||||
+ UserWarning, 3)
|
||||
+
|
||||
+ yield (scheme, realm)
|
||||
+
|
||||
+ found_challenge = True
|
||||
+
|
||||
+ if not found_challenge:
|
||||
+ if header:
|
||||
+ scheme = header.split()[0]
|
||||
+ else:
|
||||
+ scheme = ''
|
||||
+ yield (scheme, None)
|
||||
+
|
||||
def http_error_auth_reqed(self, authreq, host, req, headers):
|
||||
# host may be an authority (without userinfo) or a URL with an
|
||||
# authority
|
||||
- # XXX could be multiple headers
|
||||
- authreq = headers.get(authreq, None)
|
||||
+ headers = headers.get_all(authreq)
|
||||
+ if not headers:
|
||||
+ # no header found
|
||||
+ return
|
||||
|
||||
- if authreq:
|
||||
- scheme = authreq.split()[0]
|
||||
- if scheme.lower() != 'basic':
|
||||
- raise ValueError("AbstractBasicAuthHandler does not"
|
||||
- " support the following scheme: '%s'" %
|
||||
- scheme)
|
||||
- else:
|
||||
- mo = AbstractBasicAuthHandler.rx.search(authreq)
|
||||
- if mo:
|
||||
- scheme, quote, realm = mo.groups()
|
||||
- if quote not in ['"',"'"]:
|
||||
- warnings.warn("Basic Auth Realm was unquoted",
|
||||
- UserWarning, 2)
|
||||
- if scheme.lower() == 'basic':
|
||||
- return self.retry_http_basic_auth(host, req, realm)
|
||||
+ unsupported = None
|
||||
+ for header in headers:
|
||||
+ for scheme, realm in self._parse_realm(header):
|
||||
+ if scheme.lower() != 'basic':
|
||||
+ unsupported = scheme
|
||||
+ continue
|
||||
+
|
||||
+ if realm is not None:
|
||||
+ # Use the first matching Basic challenge.
|
||||
+ # Ignore following challenges even if they use the Basic
|
||||
+ # scheme.
|
||||
+ return self.retry_http_basic_auth(host, req, realm)
|
||||
+
|
||||
+ if unsupported is not None:
|
||||
+ raise ValueError("AbstractBasicAuthHandler does not "
|
||||
+ "support the following scheme: %r"
|
||||
+ % (scheme,))
|
||||
|
||||
def retry_http_basic_auth(self, host, req, realm):
|
||||
user, pw = self.passwd.find_user_password(realm, host)
|
@ -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).
|
@ -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).
|
@ -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: 23%{?dist}
|
||||
Release: 31%{?dist}
|
||||
License: Python
|
||||
|
||||
|
||||
@ -170,6 +170,7 @@ BuildRequires: gcc-c++
|
||||
%if %{with gdbm}
|
||||
BuildRequires: gdbm-devel >= 1:1.13
|
||||
%endif
|
||||
BuildRequires: git-core
|
||||
BuildRequires: glibc-devel
|
||||
BuildRequires: gmp-devel
|
||||
BuildRequires: libappstream-glib
|
||||
@ -309,22 +310,11 @@ Patch163: 00163-disable-parts-of-test_socket-in-rpm-build.patch
|
||||
# See https://bugzilla.redhat.com/show_bug.cgi?id=614680
|
||||
Patch170: 00170-gc-assertions.patch
|
||||
|
||||
# 00178 #
|
||||
# Don't duplicate various FLAGS in sysconfig values
|
||||
# http://bugs.python.org/issue17679
|
||||
# Does not affect python2 AFAICS (different sysconfig values initialization)
|
||||
Patch178: 00178-dont-duplicate-flags-in-sysconfig.patch
|
||||
|
||||
# 00189 #
|
||||
# Instead of bundled wheels, use our RPM packaged wheels from
|
||||
# /usr/share/python3-wheels
|
||||
Patch189: 00189-use-rpm-wheels.patch
|
||||
|
||||
# 00205 #
|
||||
# LIBPL variable in makefile takes LIBPL from configure.ac
|
||||
# but the LIBPL variable defined there doesn't respect libdir macro
|
||||
Patch205: 00205-make-libpl-respect-lib64.patch
|
||||
|
||||
# 00251
|
||||
# Set values of prefix and exec_prefix in distutils install command
|
||||
# to /usr/local if executable is /usr/bin/python* and RPM build
|
||||
@ -488,6 +478,47 @@ Patch332: 00332-CVE-2019-16056.patch
|
||||
# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749576
|
||||
Patch333: 00333-reduce-pgo-tests.patch
|
||||
|
||||
# 00338 #
|
||||
# Fix test_gdb for when compiling python with Link Time Optimizations
|
||||
# Fixed upstream: https://bugs.python.org/issue38239
|
||||
Patch338: 00338-fix-test_gdb-for-LTO.patch
|
||||
|
||||
# 00344 #
|
||||
# Fix CVE-2019-16935: XSS vulnerability in the ocumentation XML-RPC server in server_title field
|
||||
# Fixed upstream: https://bugs.python.org/issue38243
|
||||
# Resolves: https://bugzilla.redhat.com/how_bug.cgi?id=1798001
|
||||
Patch344: 00344-CVE-2019-16935.patch
|
||||
|
||||
# 00345 #
|
||||
# Skip from test_site the test_startup_imports case if a path of sys.path
|
||||
# contains a .pth file
|
||||
# Fixed upstream: https://bugs.python.org/issue27807
|
||||
# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1814392
|
||||
Patch345: 00345-fix-test_site-with-extra-pth-files.patch
|
||||
|
||||
# 00346 #
|
||||
# Fix CVE-2020-8492: wrong backtracking in urllib.request.AbstractBasicAuthHandler allows for a ReDoS
|
||||
# Fixed upstream: https://bugs.python.org/issue39503
|
||||
# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1810618
|
||||
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.,
|
||||
@ -778,14 +809,12 @@ rm -r Modules/zlib
|
||||
%patch160 -p1
|
||||
%patch163 -p1
|
||||
%patch170 -p1
|
||||
%patch178 -p1
|
||||
|
||||
%if %{with rpmwheels}
|
||||
%patch189 -p1
|
||||
rm Lib/ensurepip/_bundled/*.whl
|
||||
%endif
|
||||
|
||||
%patch205 -p1
|
||||
%patch251 -p1
|
||||
%patch262 -p1
|
||||
%patch274 -p1
|
||||
@ -803,7 +832,15 @@ rm Lib/ensurepip/_bundled/*.whl
|
||||
%patch330 -p1
|
||||
%patch332 -p1
|
||||
%patch333 -p1
|
||||
%patch338 -p1
|
||||
%patch344 -p1
|
||||
%patch345 -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)
|
||||
@ -845,14 +882,14 @@ topdir=$(pwd)
|
||||
# RHEL packages utilizing %%py3_build will use them as well
|
||||
# https://fedoraproject.org/wiki/Changes/Python_Extension_Flags
|
||||
export CFLAGS="%{extension_cflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
export CFLAGS_NODIST="%{build_cflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
export CFLAGS_NODIST="%{build_cflags} -D_GNU_SOURCE -fPIC -fwrapv -fno-semantic-interposition"
|
||||
export CXXFLAGS="%{extension_cxxflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
export CPPFLAGS="$(pkg-config --cflags-only-I libffi)"
|
||||
export OPT="%{extension_cflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
export LINKCC="gcc"
|
||||
export CFLAGS="$CFLAGS $(pkg-config --cflags openssl)"
|
||||
export LDFLAGS="%{extension_ldflags} -g $(pkg-config --libs-only-L openssl)"
|
||||
export LDFLAGS_NODIST="%{build_ldflags} -g $(pkg-config --libs-only-L openssl)"
|
||||
export LDFLAGS_NODIST="%{build_ldflags} -fno-semantic-interposition -g $(pkg-config --libs-only-L openssl)"
|
||||
|
||||
# We can build several different configurations of Python: regular and debug.
|
||||
# Define a common function that does one build:
|
||||
@ -1720,6 +1757,42 @@ fi
|
||||
# ======================================================
|
||||
|
||||
%changelog
|
||||
* Mon Aug 17 2020 Tomas Orsava <torsava@redhat.com> - 3.6.8-31
|
||||
- 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
|
||||
|
||||
* Thu Jun 25 2020 Victor Stinner <vstinner@python.org> - 3.6.8-30
|
||||
- Remove downstream 00178-dont-duplicate-flags-in-sysconfig.patch which
|
||||
introduced a bug on distutils.sysconfig.get_config_var('LIBPL')
|
||||
(rhbz#1851090).
|
||||
|
||||
* Thu Jun 18 2020 Victor Stinner <vstinner@python.org> - 3.6.8-29
|
||||
- Fix python3-config --configdir (rhbz#1772992).
|
||||
|
||||
* Fri Apr 03 2020 Charalampos Stratakis <cstratak@redhat.com> - 3.6.8-28
|
||||
- Security fix for CVE-2020-8492
|
||||
Resolves: rhbz#1810618
|
||||
|
||||
* Tue Mar 31 2020 Charalampos Stratakis <cstratak@redhat.com> - 3.6.8-27
|
||||
- Add a sentinel value on the Hmac_members table of the fips compliant hmac module
|
||||
Resolves: rhbz#1800512
|
||||
|
||||
* Mon Mar 23 2020 Charalampos Stratakis <cstratak@redhat.com> - 3.6.8-26
|
||||
- Skip test_startup_imports from test_site if we have a .pth file in sys.path
|
||||
Resolves: rhbz#1814392
|
||||
|
||||
* Fri Mar 20 2020 Charalampos Stratakis <cstratak@redhat.com> - 3.6.8-25
|
||||
- Security fix for CVE-2019-16935
|
||||
Resolves: rhbz#1798001
|
||||
|
||||
* Mon Mar 16 2020 Charalampos Stratakis <cstratak@redhat.com> - 3.6.8-24
|
||||
- Build Python with -fno-semantic-interposition for better performance
|
||||
- https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup
|
||||
- Also fix test_gdb failures with Link Time Optimizations
|
||||
Resolves: rhbz#1724996
|
||||
|
||||
* Wed Nov 27 2019 Charalampos Stratakis <cstratak@redhat.com> - 3.6.8-23
|
||||
- Modify the test suite to better handle disabled SSL/TLS versions and FIPS mode
|
||||
- Use OpenSSL's DRBG and disable os.getrandom() function in FIPS mode
|
||||
|
Loading…
Reference in New Issue
Block a user