Skip to content

Commit 607eba4

Browse files
[AutoPR- Security] Patch python3 for CVE-2026-4224 [MEDIUM] (#16559)
Co-authored-by: SumitJenaHCL <v-sumitjena@microsoft.com>
1 parent 6a6ea42 commit 607eba4

6 files changed

Lines changed: 155 additions & 27 deletions

File tree

SPECS/python3/CVE-2026-4224.patch

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
From 18fded65fbf6833e9c942c6ae9102a6b1e047d52 Mon Sep 17 00:00:00 2001
2+
From: Stan Ulbrych <stan@python.org>
3+
Date: Wed, 8 Apr 2026 11:27:42 +0100
4+
Subject: [PATCH] gh-145986: Avoid unbound C recursion in `conv_content_model`
5+
in `pyexpat.c` (CVE 2026-4224) (GH-145987) (#146002)
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset=UTF-8
8+
Content-Transfer-Encoding: 8bit
9+
10+
* [3.10] gh-145986: Avoid unbound C recursion in `conv_content_model` in `pyexpat.c` (CVE 2026-4224) (GH-145987)
11+
12+
Fix C stack overflow (CVE-2026-4224) when an Expat parser
13+
with a registered `ElementDeclHandler` parses inline DTD
14+
containing deeply nested content model.
15+
16+
---------
17+
(cherry picked from commit eb0e8be3a7e11b87d198a2c3af1ed0eccf532768)
18+
(cherry picked from commit e5caf45faac74b0ed869e3336420cffd3510ce6e)
19+
20+
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
21+
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
22+
23+
* Update Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst
24+
25+
---------
26+
27+
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
28+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
29+
Upstream-reference: https://github.com/python/cpython/commit/af856a7177326ac25d9f66cc6dd28b554d914fee.patch
30+
---
31+
Lib/test/test_pyexpat.py | 19 +++++++++++++++++++
32+
.../2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst | 4 ++++
33+
Modules/pyexpat.c | 8 +++++++-
34+
3 files changed, 30 insertions(+), 1 deletion(-)
35+
create mode 100644 Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst
36+
37+
diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py
38+
index 5212c7a..95d85bb 100644
39+
--- a/Lib/test/test_pyexpat.py
40+
+++ b/Lib/test/test_pyexpat.py
41+
@@ -8,10 +8,12 @@ import sys
42+
import sysconfig
43+
import unittest
44+
import traceback
45+
+import textwrap
46+
47+
from xml.parsers import expat
48+
from xml.parsers.expat import errors
49+
50+
+from test import support
51+
from test.support import sortdict
52+
53+
54+
@@ -643,6 +645,23 @@ class ChardataBufferTest(unittest.TestCase):
55+
parser.Parse(xml2, True)
56+
self.assertEqual(self.n, 4)
57+
58+
+class ElementDeclHandlerTest(unittest.TestCase):
59+
+ def test_deeply_nested_content_model(self):
60+
+ # This should raise a RecursionError and not crash.
61+
+ # See https://github.com/python/cpython/issues/145986.
62+
+ N = 500_000
63+
+ data = (
64+
+ b'<!DOCTYPE root [\n<!ELEMENT root '
65+
+ + b'(a, ' * N + b'a' + b')' * N
66+
+ + b'>\n]>\n<root/>\n'
67+
+ )
68+
+
69+
+ parser = expat.ParserCreate()
70+
+ parser.ElementDeclHandler = lambda _1, _2: None
71+
+ with support.infinite_recursion():
72+
+ with self.assertRaises(RecursionError):
73+
+ parser.Parse(data)
74+
+
75+
class MalformedInputTest(unittest.TestCase):
76+
def test1(self):
77+
xml = b"\0\r\n"
78+
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
79+
new file mode 100644
80+
index 0000000..cb9dbad
81+
--- /dev/null
82+
+++ b/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst
83+
@@ -0,0 +1,4 @@
84+
+:mod:`xml.parsers.expat`: Fixed a crash caused by unbounded C recursion when
85+
+converting deeply nested XML content models with
86+
+:meth:`~xml.parsers.expat.xmlparser.ElementDeclHandler`.
87+
+This addresses `CVE-2026-4224 <https://www.cve.org/CVERecord?id=CVE-2026-4224>`_.
88+
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
89+
index e0c3e10..60a2561 100644
90+
--- a/Modules/pyexpat.c
91+
+++ b/Modules/pyexpat.c
92+
@@ -515,6 +515,10 @@ static PyObject *
93+
conv_content_model(XML_Content * const model,
94+
PyObject *(*conv_string)(const XML_Char *))
95+
{
96+
+ if (Py_EnterRecursiveCall(" in conv_content_model")) {
97+
+ return NULL;
98+
+ }
99+
+
100+
PyObject *result = NULL;
101+
PyObject *children = PyTuple_New(model->numchildren);
102+
int i;
103+
@@ -526,7 +530,7 @@ conv_content_model(XML_Content * const model,
104+
conv_string);
105+
if (child == NULL) {
106+
Py_XDECREF(children);
107+
- return NULL;
108+
+ goto done;
109+
}
110+
PyTuple_SET_ITEM(children, i, child);
111+
}
112+
@@ -534,6 +538,8 @@ conv_content_model(XML_Content * const model,
113+
model->type, model->quant,
114+
conv_string,model->name, children);
115+
}
116+
+done:
117+
+ Py_LeaveRecursiveCall();
118+
return result;
119+
}
120+
121+
--
122+
2.45.4
123+

SPECS/python3/python3.spec

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
Summary: A high-level scripting language
1313
Name: python3
1414
Version: 3.9.19
15-
Release: 20%{?dist}
15+
Release: 21%{?dist}
1616
License: PSF
1717
Vendor: Microsoft Corporation
1818
Distribution: Mariner
@@ -45,6 +45,7 @@ Patch21: CVE-2025-12084.patch
4545
Patch22: CVE-2026-0865.patch
4646
Patch23: CVE-2025-13837.patch
4747
Patch24: CVE-2025-11468.patch
48+
Patch25: CVE-2026-4224.patch
4849

4950
# Patch for setuptools, resolved in 65.5.1
5051
Patch1000: CVE-2022-40897.patch
@@ -216,6 +217,7 @@ The test package contains all regression tests for Python as well as the modules
216217
%patch22 -p1
217218
%patch23 -p1
218219
%patch24 -p1
220+
%patch25 -p1
219221

220222
%build
221223
# Remove GCC specs and build environment linker scripts
@@ -391,6 +393,9 @@ make test TESTOPTS="-x test_multiprocessing_spawn -x test_socket -x test_email"
391393
%{_libdir}/python%{majmin}/test/*
392394

393395
%changelog
396+
* Fri Apr 10 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 3.9.19-21
397+
- Patch for CVE-2026-4224
398+
394399
* Tue Mar 03 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 3.9.19-20
395400
- Patch for CVE-2025-13837, CVE-2025-11468
396401

toolkit/resources/manifests/package/pkggen_core_aarch64.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,10 @@ ca-certificates-base-2.0.0-25.cm2.noarch.rpm
237237
ca-certificates-2.0.0-25.cm2.noarch.rpm
238238
dwz-0.14-2.cm2.aarch64.rpm
239239
unzip-6.0-22.cm2.aarch64.rpm
240-
python3-3.9.19-20.cm2.aarch64.rpm
241-
python3-devel-3.9.19-20.cm2.aarch64.rpm
242-
python3-libs-3.9.19-20.cm2.aarch64.rpm
243-
python3-setuptools-3.9.19-20.cm2.noarch.rpm
240+
python3-3.9.19-21.cm2.aarch64.rpm
241+
python3-devel-3.9.19-21.cm2.aarch64.rpm
242+
python3-libs-3.9.19-21.cm2.aarch64.rpm
243+
python3-setuptools-3.9.19-21.cm2.noarch.rpm
244244
python3-pygments-2.4.2-7.cm2.noarch.rpm
245245
which-2.21-8.cm2.aarch64.rpm
246246
libselinux-3.2-1.cm2.aarch64.rpm

toolkit/resources/manifests/package/pkggen_core_x86_64.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,10 @@ ca-certificates-base-2.0.0-25.cm2.noarch.rpm
237237
ca-certificates-2.0.0-25.cm2.noarch.rpm
238238
dwz-0.14-2.cm2.x86_64.rpm
239239
unzip-6.0-22.cm2.x86_64.rpm
240-
python3-3.9.19-20.cm2.x86_64.rpm
241-
python3-devel-3.9.19-20.cm2.x86_64.rpm
242-
python3-libs-3.9.19-20.cm2.x86_64.rpm
243-
python3-setuptools-3.9.19-20.cm2.noarch.rpm
240+
python3-3.9.19-21.cm2.x86_64.rpm
241+
python3-devel-3.9.19-21.cm2.x86_64.rpm
242+
python3-libs-3.9.19-21.cm2.x86_64.rpm
243+
python3-setuptools-3.9.19-21.cm2.noarch.rpm
244244
python3-pygments-2.4.2-7.cm2.noarch.rpm
245245
which-2.21-8.cm2.x86_64.rpm
246246
libselinux-3.2-1.cm2.x86_64.rpm

toolkit/resources/manifests/package/toolchain_aarch64.txt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -510,28 +510,28 @@ procps-ng-devel-3.3.17-2.cm2.aarch64.rpm
510510
procps-ng-lang-3.3.17-2.cm2.aarch64.rpm
511511
pyproject-rpm-macros-1.0.0~rc1-4.cm2.noarch.rpm
512512
python-markupsafe-debuginfo-2.1.0-1.cm2.aarch64.rpm
513-
python3-3.9.19-20.cm2.aarch64.rpm
513+
python3-3.9.19-21.cm2.aarch64.rpm
514514
python3-audit-3.0.6-8.cm2.aarch64.rpm
515515
python3-cracklib-2.9.7-5.cm2.aarch64.rpm
516-
python3-curses-3.9.19-20.cm2.aarch64.rpm
516+
python3-curses-3.9.19-21.cm2.aarch64.rpm
517517
python3-Cython-0.29.33-2.cm2.aarch64.rpm
518-
python3-debuginfo-3.9.19-20.cm2.aarch64.rpm
519-
python3-devel-3.9.19-20.cm2.aarch64.rpm
518+
python3-debuginfo-3.9.19-21.cm2.aarch64.rpm
519+
python3-devel-3.9.19-21.cm2.aarch64.rpm
520520
python3-gpg-1.16.0-2.cm2.aarch64.rpm
521521
python3-jinja2-3.0.3-7.cm2.noarch.rpm
522522
python3-libcap-ng-0.8.2-2.cm2.aarch64.rpm
523-
python3-libs-3.9.19-20.cm2.aarch64.rpm
523+
python3-libs-3.9.19-21.cm2.aarch64.rpm
524524
python3-libxml2-2.10.4-11.cm2.aarch64.rpm
525525
python3-lxml-4.9.1-1.cm2.aarch64.rpm
526526
python3-magic-5.40-3.cm2.noarch.rpm
527527
python3-markupsafe-2.1.0-1.cm2.aarch64.rpm
528528
python3-newt-0.52.21-5.cm2.aarch64.rpm
529-
python3-pip-3.9.19-20.cm2.noarch.rpm
529+
python3-pip-3.9.19-21.cm2.noarch.rpm
530530
python3-pygments-2.4.2-7.cm2.noarch.rpm
531531
python3-rpm-4.18.0-4.cm2.aarch64.rpm
532-
python3-setuptools-3.9.19-20.cm2.noarch.rpm
533-
python3-test-3.9.19-20.cm2.aarch64.rpm
534-
python3-tools-3.9.19-20.cm2.aarch64.rpm
532+
python3-setuptools-3.9.19-21.cm2.noarch.rpm
533+
python3-test-3.9.19-21.cm2.aarch64.rpm
534+
python3-tools-3.9.19-21.cm2.aarch64.rpm
535535
readline-8.1-1.cm2.aarch64.rpm
536536
readline-debuginfo-8.1-1.cm2.aarch64.rpm
537537
readline-devel-8.1-1.cm2.aarch64.rpm

toolkit/resources/manifests/package/toolchain_x86_64.txt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -516,28 +516,28 @@ procps-ng-devel-3.3.17-2.cm2.x86_64.rpm
516516
procps-ng-lang-3.3.17-2.cm2.x86_64.rpm
517517
pyproject-rpm-macros-1.0.0~rc1-4.cm2.noarch.rpm
518518
python-markupsafe-debuginfo-2.1.0-1.cm2.x86_64.rpm
519-
python3-3.9.19-20.cm2.x86_64.rpm
519+
python3-3.9.19-21.cm2.x86_64.rpm
520520
python3-audit-3.0.6-8.cm2.x86_64.rpm
521521
python3-cracklib-2.9.7-5.cm2.x86_64.rpm
522-
python3-curses-3.9.19-20.cm2.x86_64.rpm
522+
python3-curses-3.9.19-21.cm2.x86_64.rpm
523523
python3-Cython-0.29.33-2.cm2.x86_64.rpm
524-
python3-debuginfo-3.9.19-20.cm2.x86_64.rpm
525-
python3-devel-3.9.19-20.cm2.x86_64.rpm
524+
python3-debuginfo-3.9.19-21.cm2.x86_64.rpm
525+
python3-devel-3.9.19-21.cm2.x86_64.rpm
526526
python3-gpg-1.16.0-2.cm2.x86_64.rpm
527527
python3-jinja2-3.0.3-7.cm2.noarch.rpm
528528
python3-libcap-ng-0.8.2-2.cm2.x86_64.rpm
529-
python3-libs-3.9.19-20.cm2.x86_64.rpm
529+
python3-libs-3.9.19-21.cm2.x86_64.rpm
530530
python3-libxml2-2.10.4-11.cm2.x86_64.rpm
531531
python3-lxml-4.9.1-1.cm2.x86_64.rpm
532532
python3-magic-5.40-3.cm2.noarch.rpm
533533
python3-markupsafe-2.1.0-1.cm2.x86_64.rpm
534534
python3-newt-0.52.21-5.cm2.x86_64.rpm
535-
python3-pip-3.9.19-20.cm2.noarch.rpm
535+
python3-pip-3.9.19-21.cm2.noarch.rpm
536536
python3-pygments-2.4.2-7.cm2.noarch.rpm
537537
python3-rpm-4.18.0-4.cm2.x86_64.rpm
538-
python3-setuptools-3.9.19-20.cm2.noarch.rpm
539-
python3-test-3.9.19-20.cm2.x86_64.rpm
540-
python3-tools-3.9.19-20.cm2.x86_64.rpm
538+
python3-setuptools-3.9.19-21.cm2.noarch.rpm
539+
python3-test-3.9.19-21.cm2.x86_64.rpm
540+
python3-tools-3.9.19-21.cm2.x86_64.rpm
541541
readline-8.1-1.cm2.x86_64.rpm
542542
readline-debuginfo-8.1-1.cm2.x86_64.rpm
543543
readline-devel-8.1-1.cm2.x86_64.rpm

0 commit comments

Comments
 (0)