From 205f0cd0ded4b0c7b39202eac7b9d6c2470626b6 Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Fri, 14 Sep 2018 09:39:57 +0200 Subject: python: fix for CVE-2018-1060 & CVE-2018-1061 References: https://bugs.python.org/issue32981 https://nvd.nist.gov/vuln/detail/CVE-2018-1060 https://nvd.nist.gov/vuln/detail/CVE-2018-1061 Patch is taken from https://github.com/python/cpython/tree/2.7 Change-Id: I3c561499076480c344fe7d34d2edea84615ac9fa Signed-off-by: Sona Sarmadi --- .../python/CVE-2018-1060_CVE-2018-1061.patch | 149 +++++++++++++++++++++ recipes-devtools/python/python_%.bbappend | 5 + 2 files changed, 154 insertions(+) create mode 100644 recipes-devtools/python/python/CVE-2018-1060_CVE-2018-1061.patch create mode 100644 recipes-devtools/python/python_%.bbappend diff --git a/recipes-devtools/python/python/CVE-2018-1060_CVE-2018-1061.patch b/recipes-devtools/python/python/CVE-2018-1060_CVE-2018-1061.patch new file mode 100644 index 0000000..bb7aaf6 --- /dev/null +++ b/recipes-devtools/python/python/CVE-2018-1060_CVE-2018-1061.patch @@ -0,0 +1,149 @@ +From e052d40cea15f582b50947f7d906b39744dc62a2 Mon Sep 17 00:00:00 2001 +From: Benjamin Peterson +Date: Sat, 3 Mar 2018 22:18:17 -0800 +Subject: [PATCH] [2.7] bpo-32981: Fix catastrophic backtracking vulns + (GH-5955) + +* Prevent low-grade poplib REDOS (CVE-2018-1060) + +The regex to test a mail server's timestamp is susceptible to +catastrophic backtracking on long evil responses from the server. + +Happily, the maximum length of malicious inputs is 2K thanks +to a limit introduced in the fix for CVE-2013-1752. + +A 2KB evil response from the mail server would result in small slowdowns +(milliseconds vs. microseconds) accumulated over many apop calls. +This is a potential DOS vector via accumulated slowdowns. + +Replace it with a similar non-vulnerable regex. + +The new regex is RFC compliant. +The old regex was non-compliant in edge cases. + +* Prevent difflib REDOS (CVE-2018-1061) + +The default regex for IS_LINE_JUNK is susceptible to +catastrophic backtracking. +This is a potential DOS vector. + +Replace it with an equivalent non-vulnerable regex. + +Also introduce unit and REDOS tests for difflib. + +CVE: CVE-2018-1060 CVE-2018-1061 +Upstream-Status: Backport + +Co-authored-by: Tim Peters +Co-authored-by: Christian Heimes . +(cherry picked from commit 0e6c8ee2358a2e23117501826c008842acb835ac) +Signed-off-by: Sona Sarmadi +--- + Lib/difflib.py | 2 +- + Lib/poplib.py | 2 +- + Lib/test/test_difflib.py | 22 +++++++++++++++++++++- + Lib/test/test_poplib.py | 10 ++++++++++ + Misc/ACKS | 2 ++ + .../2018-03-02-10-24-52.bpo-32981.O_qDyj.rst | 4 ++++ + 6 files changed, 39 insertions(+), 3 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst + +diff --git a/Lib/difflib.py b/Lib/difflib.py +index 1c6fbdb..788a92d 100644 +--- a/Lib/difflib.py ++++ b/Lib/difflib.py +@@ -1103,7 +1103,7 @@ class Differ: + + 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 b91e5f7..a238510 100644 +--- a/Lib/poplib.py ++++ b/Lib/poplib.py +@@ -274,7 +274,7 @@ class POP3: + 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 35f2c36..d8277b7 100644 +--- a/Lib/test/test_difflib.py ++++ b/Lib/test/test_difflib.py +@@ -269,13 +269,33 @@ class TestOutputFormat(unittest.TestCase): + 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 23d6887..d214375 100644 +--- a/Lib/test/test_poplib.py ++++ b/Lib/test/test_poplib.py +@@ -211,6 +211,16 @@ class TestPOP3Class(TestCase): + 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/Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst b/Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst +new file mode 100644 +index 0000000..9ebabb4 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst +@@ -0,0 +1,4 @@ ++Regexes in difflib and poplib were vulnerable to catastrophic backtracking. ++These regexes formed potential DOS vectors (REDOS). They have been ++refactored. This resolves CVE-2018-1060 and CVE-2018-1061. ++Patch by Jamie Davis. +-- +1.9.1 + diff --git a/recipes-devtools/python/python_%.bbappend b/recipes-devtools/python/python_%.bbappend new file mode 100644 index 0000000..b111f1a --- /dev/null +++ b/recipes-devtools/python/python_%.bbappend @@ -0,0 +1,5 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/python:" + +SRC_URI += "file://CVE-2018-1060_CVE-2018-1061.patch \ + " + -- cgit v1.2.3-54-g00ecf