diff options
| author | Sona Sarmadi <sona.sarmadi@enea.com> | 2018-09-14 09:39:57 +0200 |
|---|---|---|
| committer | Sona Sarmadi <sona.sarmadi@enea.com> | 2018-09-14 10:12:35 +0200 |
| commit | 205f0cd0ded4b0c7b39202eac7b9d6c2470626b6 (patch) | |
| tree | 0653b07a7a5092e346710d4b620e4328aea344ce /recipes-devtools | |
| parent | 13e2bdb030f67e2c75ff9873343c008bc13daf16 (diff) | |
| download | meta-el-common-205f0cd0ded4b0c7b39202eac7b9d6c2470626b6.tar.gz | |
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 <sona.sarmadi@enea.com>
Diffstat (limited to 'recipes-devtools')
| -rw-r--r-- | recipes-devtools/python/python/CVE-2018-1060_CVE-2018-1061.patch | 149 | ||||
| -rw-r--r-- | recipes-devtools/python/python_%.bbappend | 5 |
2 files changed, 154 insertions, 0 deletions
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 @@ | |||
| 1 | From e052d40cea15f582b50947f7d906b39744dc62a2 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Benjamin Peterson <benjamin@python.org> | ||
| 3 | Date: Sat, 3 Mar 2018 22:18:17 -0800 | ||
| 4 | Subject: [PATCH] [2.7] bpo-32981: Fix catastrophic backtracking vulns | ||
| 5 | (GH-5955) | ||
| 6 | |||
| 7 | * Prevent low-grade poplib REDOS (CVE-2018-1060) | ||
| 8 | |||
| 9 | The regex to test a mail server's timestamp is susceptible to | ||
| 10 | catastrophic backtracking on long evil responses from the server. | ||
| 11 | |||
| 12 | Happily, the maximum length of malicious inputs is 2K thanks | ||
| 13 | to a limit introduced in the fix for CVE-2013-1752. | ||
| 14 | |||
| 15 | A 2KB evil response from the mail server would result in small slowdowns | ||
| 16 | (milliseconds vs. microseconds) accumulated over many apop calls. | ||
| 17 | This is a potential DOS vector via accumulated slowdowns. | ||
| 18 | |||
| 19 | Replace it with a similar non-vulnerable regex. | ||
| 20 | |||
| 21 | The new regex is RFC compliant. | ||
| 22 | The old regex was non-compliant in edge cases. | ||
| 23 | |||
| 24 | * Prevent difflib REDOS (CVE-2018-1061) | ||
| 25 | |||
| 26 | The default regex for IS_LINE_JUNK is susceptible to | ||
| 27 | catastrophic backtracking. | ||
| 28 | This is a potential DOS vector. | ||
| 29 | |||
| 30 | Replace it with an equivalent non-vulnerable regex. | ||
| 31 | |||
| 32 | Also introduce unit and REDOS tests for difflib. | ||
| 33 | |||
| 34 | CVE: CVE-2018-1060 CVE-2018-1061 | ||
| 35 | Upstream-Status: Backport | ||
| 36 | |||
| 37 | Co-authored-by: Tim Peters <tim.peters@gmail.com> | ||
| 38 | Co-authored-by: Christian Heimes <christian@python.org>. | ||
| 39 | (cherry picked from commit 0e6c8ee2358a2e23117501826c008842acb835ac) | ||
| 40 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 41 | --- | ||
| 42 | Lib/difflib.py | 2 +- | ||
| 43 | Lib/poplib.py | 2 +- | ||
| 44 | Lib/test/test_difflib.py | 22 +++++++++++++++++++++- | ||
| 45 | Lib/test/test_poplib.py | 10 ++++++++++ | ||
| 46 | Misc/ACKS | 2 ++ | ||
| 47 | .../2018-03-02-10-24-52.bpo-32981.O_qDyj.rst | 4 ++++ | ||
| 48 | 6 files changed, 39 insertions(+), 3 deletions(-) | ||
| 49 | create mode 100644 Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst | ||
| 50 | |||
| 51 | diff --git a/Lib/difflib.py b/Lib/difflib.py | ||
| 52 | index 1c6fbdb..788a92d 100644 | ||
| 53 | --- a/Lib/difflib.py | ||
| 54 | +++ b/Lib/difflib.py | ||
| 55 | @@ -1103,7 +1103,7 @@ class Differ: | ||
| 56 | |||
| 57 | import re | ||
| 58 | |||
| 59 | -def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match): | ||
| 60 | +def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): | ||
| 61 | r""" | ||
| 62 | Return 1 for ignorable line: iff `line` is blank or contains a single '#'. | ||
| 63 | |||
| 64 | diff --git a/Lib/poplib.py b/Lib/poplib.py | ||
| 65 | index b91e5f7..a238510 100644 | ||
| 66 | --- a/Lib/poplib.py | ||
| 67 | +++ b/Lib/poplib.py | ||
| 68 | @@ -274,7 +274,7 @@ class POP3: | ||
| 69 | return self._shortcmd('RPOP %s' % user) | ||
| 70 | |||
| 71 | |||
| 72 | - timestamp = re.compile(r'\+OK.*(<[^>]+>)') | ||
| 73 | + timestamp = re.compile(br'\+OK.[^<]*(<.*>)') | ||
| 74 | |||
| 75 | def apop(self, user, secret): | ||
| 76 | """Authorisation | ||
| 77 | diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py | ||
| 78 | index 35f2c36..d8277b7 100644 | ||
| 79 | --- a/Lib/test/test_difflib.py | ||
| 80 | +++ b/Lib/test/test_difflib.py | ||
| 81 | @@ -269,13 +269,33 @@ class TestOutputFormat(unittest.TestCase): | ||
| 82 | self.assertEqual(fmt(3,6), '4,6') | ||
| 83 | self.assertEqual(fmt(0,0), '0') | ||
| 84 | |||
| 85 | +class TestJunkAPIs(unittest.TestCase): | ||
| 86 | + def test_is_line_junk_true(self): | ||
| 87 | + for line in ['#', ' ', ' #', '# ', ' # ', '']: | ||
| 88 | + self.assertTrue(difflib.IS_LINE_JUNK(line), repr(line)) | ||
| 89 | + | ||
| 90 | + def test_is_line_junk_false(self): | ||
| 91 | + for line in ['##', ' ##', '## ', 'abc ', 'abc #', 'Mr. Moose is up!']: | ||
| 92 | + self.assertFalse(difflib.IS_LINE_JUNK(line), repr(line)) | ||
| 93 | + | ||
| 94 | + def test_is_line_junk_REDOS(self): | ||
| 95 | + evil_input = ('\t' * 1000000) + '##' | ||
| 96 | + self.assertFalse(difflib.IS_LINE_JUNK(evil_input)) | ||
| 97 | + | ||
| 98 | + def test_is_character_junk_true(self): | ||
| 99 | + for char in [' ', '\t']: | ||
| 100 | + self.assertTrue(difflib.IS_CHARACTER_JUNK(char), repr(char)) | ||
| 101 | + | ||
| 102 | + def test_is_character_junk_false(self): | ||
| 103 | + for char in ['a', '#', '\n', '\f', '\r', '\v']: | ||
| 104 | + self.assertFalse(difflib.IS_CHARACTER_JUNK(char), repr(char)) | ||
| 105 | |||
| 106 | def test_main(): | ||
| 107 | difflib.HtmlDiff._default_prefix = 0 | ||
| 108 | Doctests = doctest.DocTestSuite(difflib) | ||
| 109 | run_unittest( | ||
| 110 | TestWithAscii, TestAutojunk, TestSFpatches, TestSFbugs, | ||
| 111 | - TestOutputFormat, Doctests) | ||
| 112 | + TestOutputFormat, TestJunkAPIs) | ||
| 113 | |||
| 114 | if __name__ == '__main__': | ||
| 115 | test_main() | ||
| 116 | diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py | ||
| 117 | index 23d6887..d214375 100644 | ||
| 118 | --- a/Lib/test/test_poplib.py | ||
| 119 | +++ b/Lib/test/test_poplib.py | ||
| 120 | @@ -211,6 +211,16 @@ class TestPOP3Class(TestCase): | ||
| 121 | def test_rpop(self): | ||
| 122 | self.assertOK(self.client.rpop('foo')) | ||
| 123 | |||
| 124 | + def test_apop_REDOS(self): | ||
| 125 | + # Replace welcome with very long evil welcome. | ||
| 126 | + # NB The upper bound on welcome length is currently 2048. | ||
| 127 | + # At this length, evil input makes each apop call take | ||
| 128 | + # on the order of milliseconds instead of microseconds. | ||
| 129 | + evil_welcome = b'+OK' + (b'<' * 1000000) | ||
| 130 | + with test_support.swap_attr(self.client, 'welcome', evil_welcome): | ||
| 131 | + # The evil welcome is invalid, so apop should throw. | ||
| 132 | + self.assertRaises(poplib.error_proto, self.client.apop, 'a', 'kb') | ||
| 133 | + | ||
| 134 | def test_top(self): | ||
| 135 | expected = ('+OK 116 bytes', | ||
| 136 | ['From: postmaster@python.org', 'Content-Type: text/plain', | ||
| 137 | 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 | ||
| 138 | new file mode 100644 | ||
| 139 | index 0000000..9ebabb4 | ||
| 140 | --- /dev/null | ||
| 141 | +++ b/Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst | ||
| 142 | @@ -0,0 +1,4 @@ | ||
| 143 | +Regexes in difflib and poplib were vulnerable to catastrophic backtracking. | ||
| 144 | +These regexes formed potential DOS vectors (REDOS). They have been | ||
| 145 | +refactored. This resolves CVE-2018-1060 and CVE-2018-1061. | ||
| 146 | +Patch by Jamie Davis. | ||
| 147 | -- | ||
| 148 | 1.9.1 | ||
| 149 | |||
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 @@ | |||
| 1 | FILESEXTRAPATHS_prepend := "${THISDIR}/python:" | ||
| 2 | |||
| 3 | SRC_URI += "file://CVE-2018-1060_CVE-2018-1061.patch \ | ||
| 4 | " | ||
| 5 | |||
