From: Amaury Couderc <[email protected]> Backport patch to fix CVE-2026-4224. https://nvd.nist.gov/vuln/detail/CVE-2026-4224
Upstream fix: https://github.com/python/cpython/commit/642865ddf4b232da1f3b1f7abcfa3254c4bfe785 Tested with ptest: Before: PASSED: 40007, FAILED: 0, SKIPPED: 1877 After: PASSED: 40006, FAILED: 0, SKIPPED: 1877 Signed-off-by: Amaury Couderc <[email protected]> --- .../python/python3/CVE-2026-4224.patch | 121 ++++++++++++++++++ .../python/python3_3.12.13.bb | 1 + 2 files changed, 122 insertions(+) create mode 100644 meta/recipes-devtools/python/python3/CVE-2026-4224.patch diff --git a/meta/recipes-devtools/python/python3/CVE-2026-4224.patch b/meta/recipes-devtools/python/python3/CVE-2026-4224.patch new file mode 100644 index 0000000000..2555912347 --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2026-4224.patch @@ -0,0 +1,121 @@ +From ca301e24e20d1d9d58bbd432ff103cab2cb87128 Mon Sep 17 00:00:00 2001 +From: Stan Ulbrych <[email protected]> +Date: Wed, 8 Apr 2026 11:27:39 +0100 +Subject: [PATCH] gh-145986: Avoid unbound C recursion in `conv_content_model` + in `pyexpat.c` (CVE-2026-4224) (GH-145987) (#146000) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* [3.11] gh-145986: Avoid unbound C recursion in `conv_content_model` in `pyexpat.c` (CVE-2026-4224) (GH-145987) + +Fix C stack overflow (CVE-2026-4224) when an Expat parser +with a registered `ElementDeclHandler` parses inline DTD +containing deeply nested content model. + +--------- +(cherry picked from commit eb0e8be3a7e11b87d198a2c3af1ed0eccf532768) +(cherry picked from commit e5caf45faac74b0ed869e3336420cffd3510ce6e) + +Co-authored-by: Stan Ulbrych <[email protected]> +Co-authored-by: Bénédikt Tran <[email protected]> + +* Update Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst + +--------- + +Co-authored-by: Bénédikt Tran <[email protected]> + +CVE: CVE-2026-4224 +Upstream-Status: Backport [https://github.com/python/cpython/commit/642865ddf4b232da1f3b1f7abcfa3254c4bfe785] + +Signed-off-by: Amaury Couderc <[email protected]> +--- + Lib/test/test_pyexpat.py | 18 ++++++++++++++++++ + ...6-03-14-17-31-39.gh-issue-145986.ifSSr8.rst | 4 ++++ + Modules/pyexpat.c | 9 ++++++++- + 3 files changed, 30 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst + +diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py +index 38f951573f0..37d9086f40a 100644 +--- a/Lib/test/test_pyexpat.py ++++ b/Lib/test/test_pyexpat.py +@@ -675,6 +675,24 @@ class ChardataBufferTest(unittest.TestCase): + parser.Parse(xml2, True) + self.assertEqual(self.n, 4) + ++class ElementDeclHandlerTest(unittest.TestCase): ++ def test_deeply_nested_content_model(self): ++ # This should raise a RecursionError and not crash. ++ # See https://github.com/python/cpython/issues/145986. ++ N = 500_000 ++ data = ( ++ b'<!DOCTYPE root [\n<!ELEMENT root ' ++ + b'(a, ' * N + b'a' + b')' * N ++ + b'>\n]>\n<root/>\n' ++ ) ++ ++ parser = expat.ParserCreate() ++ parser.ElementDeclHandler = lambda _1, _2: None ++ with support.infinite_recursion(): ++ with self.assertRaises(RecursionError): ++ parser.Parse(data) ++ ++ + class MalformedInputTest(unittest.TestCase): + def test1(self): + xml = b"\0\r\n" +diff --git a/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst b/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst +new file mode 100644 +index 00000000000..cb9dbadb72d +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst +@@ -0,0 +1,4 @@ ++:mod:`xml.parsers.expat`: Fixed a crash caused by unbounded C recursion when ++converting deeply nested XML content models with ++:meth:`~xml.parsers.expat.xmlparser.ElementDeclHandler`. ++This addresses `CVE-2026-4224 <https://www.cve.org/CVERecord?id=CVE-2026-4224>`_. +diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c +index 79492ca5c4f..8673540f358 100644 +--- a/Modules/pyexpat.c ++++ b/Modules/pyexpat.c +@@ -3,6 +3,7 @@ + #endif + + #include "Python.h" ++#include "pycore_ceval.h" // _Py_EnterRecursiveCall() + #include "pycore_runtime.h" // _Py_ID() + #include <ctype.h> + +@@ -578,6 +579,10 @@ static PyObject * + conv_content_model(XML_Content * const model, + PyObject *(*conv_string)(const XML_Char *)) + { ++ if (_Py_EnterRecursiveCall(" in conv_content_model")) { ++ return NULL; ++ } ++ + PyObject *result = NULL; + PyObject *children = PyTuple_New(model->numchildren); + int i; +@@ -589,7 +594,7 @@ conv_content_model(XML_Content * const model, + conv_string); + if (child == NULL) { + Py_XDECREF(children); +- return NULL; ++ goto done; + } + PyTuple_SET_ITEM(children, i, child); + } +@@ -597,6 +602,8 @@ conv_content_model(XML_Content * const model, + model->type, model->quant, + conv_string,model->name, children); + } ++done: ++ _Py_LeaveRecursiveCall(); + return result; + } + +-- +2.34.1 diff --git a/meta/recipes-devtools/python/python3_3.12.13.bb b/meta/recipes-devtools/python/python3_3.12.13.bb index 5fa25235fe..631ae684c3 100644 --- a/meta/recipes-devtools/python/python3_3.12.13.bb +++ b/meta/recipes-devtools/python/python3_3.12.13.bb @@ -34,6 +34,7 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \ file://0001-test_deadlock-skip-problematic-test.patch \ file://0001-test_active_children-skip-problematic-test.patch \ file://0001-test_readline-skip-limited-history-test.patch \ + file://CVE-2026-4224.patch \ " SRC_URI:append:class-native = " \ -- 2.44.1
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#239638): https://lists.openembedded.org/g/openembedded-core/message/239638 Mute This Topic: https://lists.openembedded.org/mt/119990400/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
