diff options
| author | Ankur Tyagi <ankur.tyagi85@gmail.com> | 2026-01-15 02:00:51 +1300 |
|---|---|---|
| committer | Anuj Mittal <anuj.mittal@oss.qualcomm.com> | 2026-01-19 12:15:42 +0530 |
| commit | e2b431389facf4bb69c25f9cbb3446bf4f237bc5 (patch) | |
| tree | 3edc5aa103ff0c0515a89d76ed1df590f4465e9b /meta-python/recipes-devtools/python/python3-tornado | |
| parent | cfa04fece146248b8f0c3c522aa29f8e0f3a3cf3 (diff) | |
| download | meta-openembedded-e2b431389facf4bb69c25f9cbb3446bf4f237bc5.tar.gz | |
python3-tornado: patch CVE-2025-67726
Details: https://nvd.nist.gov/vuln/detail/CVE-2025-67726
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
Diffstat (limited to 'meta-python/recipes-devtools/python/python3-tornado')
| -rw-r--r-- | meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67726.patch | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67726.patch b/meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67726.patch new file mode 100644 index 0000000000..7b210aea42 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67726.patch | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | From 4cdca826270483d8b774461a5fdd64f61af62659 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Ben Darnell <ben@bendarnell.com> | ||
| 3 | Date: Wed, 10 Dec 2025 10:55:02 -0500 | ||
| 4 | Subject: [PATCH] httputil: Fix quadratic behavior in _parseparam | ||
| 5 | |||
| 6 | Prior to this change, _parseparam had O(n^2) behavior when parsing | ||
| 7 | certain inputs, which could be a DoS vector. This change adapts | ||
| 8 | logic from the equivalent function in the python standard library | ||
| 9 | in https://github.com/python/cpython/pull/136072/files | ||
| 10 | |||
| 11 | CVE: CVE-2025-67726 | ||
| 12 | Upstream-Status: Backport [https://github.com/tornadoweb/tornado/commit/771472cfdaeebc0d89a9cc46e249f8891a6b29cd] | ||
| 13 | (cherry picked from commit 771472cfdaeebc0d89a9cc46e249f8891a6b29cd) | ||
| 14 | Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> | ||
| 15 | --- | ||
| 16 | tornado/httputil.py | 29 ++++++++++++++++++++++------- | ||
| 17 | tornado/test/httputil_test.py | 23 +++++++++++++++++++++++ | ||
| 18 | 2 files changed, 45 insertions(+), 7 deletions(-) | ||
| 19 | |||
| 20 | diff --git a/tornado/httputil.py b/tornado/httputil.py | ||
| 21 | index 090a977d..bbacd4a4 100644 | ||
| 22 | --- a/tornado/httputil.py | ||
| 23 | +++ b/tornado/httputil.py | ||
| 24 | @@ -926,19 +926,34 @@ def parse_response_start_line(line: str) -> ResponseStartLine: | ||
| 25 | # It has also been modified to support valueless parameters as seen in | ||
| 26 | # websocket extension negotiations, and to support non-ascii values in | ||
| 27 | # RFC 2231/5987 format. | ||
| 28 | +# | ||
| 29 | +# _parseparam has been further modified with the logic from | ||
| 30 | +# https://github.com/python/cpython/pull/136072/files | ||
| 31 | +# to avoid quadratic behavior when parsing semicolons in quoted strings. | ||
| 32 | +# | ||
| 33 | +# TODO: See if we can switch to email.message.Message for this functionality. | ||
| 34 | +# This is the suggested replacement for the cgi.py module now that cgi has | ||
| 35 | +# been removed from recent versions of Python. We need to verify that | ||
| 36 | +# the email module is consistent with our existing behavior (and all relevant | ||
| 37 | +# RFCs for multipart/form-data) before making this change. | ||
| 38 | |||
| 39 | |||
| 40 | def _parseparam(s: str) -> Generator[str, None, None]: | ||
| 41 | - while s[:1] == ";": | ||
| 42 | - s = s[1:] | ||
| 43 | - end = s.find(";") | ||
| 44 | - while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: | ||
| 45 | - end = s.find(";", end + 1) | ||
| 46 | + start = 0 | ||
| 47 | + while s.find(";", start) == start: | ||
| 48 | + start += 1 | ||
| 49 | + end = s.find(";", start) | ||
| 50 | + ind, diff = start, 0 | ||
| 51 | + while end > 0: | ||
| 52 | + diff += s.count('"', ind, end) - s.count('\\"', ind, end) | ||
| 53 | + if diff % 2 == 0: | ||
| 54 | + break | ||
| 55 | + end, ind = ind, s.find(";", end + 1) | ||
| 56 | if end < 0: | ||
| 57 | end = len(s) | ||
| 58 | - f = s[:end] | ||
| 59 | + f = s[start:end] | ||
| 60 | yield f.strip() | ||
| 61 | - s = s[end:] | ||
| 62 | + start = end | ||
| 63 | |||
| 64 | |||
| 65 | def _parse_header(line: str) -> Tuple[str, Dict[str, str]]: | ||
| 66 | diff --git a/tornado/test/httputil_test.py b/tornado/test/httputil_test.py | ||
| 67 | index 9494d0c1..22b1681b 100644 | ||
| 68 | --- a/tornado/test/httputil_test.py | ||
| 69 | +++ b/tornado/test/httputil_test.py | ||
| 70 | @@ -262,6 +262,29 @@ Foo | ||
| 71 | self.assertEqual(file["filename"], "ab.txt") | ||
| 72 | self.assertEqual(file["body"], b"Foo") | ||
| 73 | |||
| 74 | + def test_disposition_param_linear_performance(self): | ||
| 75 | + # This is a regression test for performance of parsing parameters | ||
| 76 | + # to the content-disposition header, specifically for semicolons within | ||
| 77 | + # quoted strings. | ||
| 78 | + def f(n): | ||
| 79 | + start = time.time() | ||
| 80 | + message = ( | ||
| 81 | + b"--1234\r\nContent-Disposition: form-data; " | ||
| 82 | + + b'x="' | ||
| 83 | + + b";" * n | ||
| 84 | + + b'"; ' | ||
| 85 | + + b'name="files"; filename="a.txt"\r\n\r\nFoo\r\n--1234--\r\n' | ||
| 86 | + ) | ||
| 87 | + args: dict[str, list[bytes]] = {} | ||
| 88 | + files: dict[str, list[HTTPFile]] = {} | ||
| 89 | + parse_multipart_form_data(b"1234", message, args, files) | ||
| 90 | + return time.time() - start | ||
| 91 | + | ||
| 92 | + d1 = f(1_000) | ||
| 93 | + d2 = f(10_000) | ||
| 94 | + if d2 / d1 > 20: | ||
| 95 | + self.fail(f"Disposition param parsing is not linear: {d1=} vs {d2=}") | ||
| 96 | + | ||
| 97 | |||
| 98 | class HTTPHeadersTest(unittest.TestCase): | ||
| 99 | def test_multi_line(self): | ||
