diff --git a/00464-enable-pac-and-bti-protections-for-aarch64.patch b/00464-enable-pac-and-bti-protections-for-aarch64.patch new file mode 100644 index 0000000..1a7acf3 --- /dev/null +++ b/00464-enable-pac-and-bti-protections-for-aarch64.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Tue, 3 Jun 2025 03:02:15 +0200 +Subject: 00464: Enable PAC and BTI protections for aarch64 + +Apply protection against ROP/JOP attacks for aarch64 on asm_trampoline.S + +The BTI flag must be applied in the assembler sources for this class +of attacks to be mitigated on newer aarch64 processors. + +Upstream PR: https://github.com/python/cpython/pull/130864/files + +The upstream patch is incomplete but only for the case where +frame pointers are not used on 3.13+. + +Since on Fedora we always compile with frame pointers the BTI/PAC +hardware protections can be enabled without losing Perf unwinding. +--- + Python/asm_trampoline.S | 4 +++ + Python/asm_trampoline_aarch64.h | 50 +++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + create mode 100644 Python/asm_trampoline_aarch64.h + +diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S +index a14e68c0e8..2513cde4e7 100644 +--- a/Python/asm_trampoline.S ++++ b/Python/asm_trampoline.S +@@ -1,3 +1,5 @@ ++#include "asm_trampoline_aarch64.h" ++ + .text + .globl _Py_trampoline_func_start + # The following assembly is equivalent to: +@@ -21,10 +23,12 @@ _Py_trampoline_func_start: + #if defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__) + // ARM64 little endian, 64bit ABI + // generate with aarch64-linux-gnu-gcc 12.1 ++ SIGN_LR + stp x29, x30, [sp, -16]! + mov x29, sp + blr x3 + ldp x29, x30, [sp], 16 ++ VERIFY_LR + ret + #endif + #ifdef __riscv +diff --git a/Python/asm_trampoline_aarch64.h b/Python/asm_trampoline_aarch64.h +new file mode 100644 +index 0000000000..4b0ec4a7dc +--- /dev/null ++++ b/Python/asm_trampoline_aarch64.h +@@ -0,0 +1,50 @@ ++#ifndef ASM_TRAMPOLINE_AARCH_64_H_ ++#define ASM_TRAMPOLINE_AARCH_64_H_ ++ ++/* ++ * References: ++ * - https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros ++ * - https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst ++ */ ++ ++#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 ++ #define BTI_J hint 36 /* bti j: for jumps, IE br instructions */ ++ #define BTI_C hint 34 /* bti c: for calls, IE bl instructions */ ++ #define GNU_PROPERTY_AARCH64_BTI 1 /* bit 0 GNU Notes is for BTI support */ ++#else ++ #define BTI_J ++ #define BTI_C ++ #define GNU_PROPERTY_AARCH64_BTI 0 ++#endif ++ ++#if defined(__ARM_FEATURE_PAC_DEFAULT) ++ #if __ARM_FEATURE_PAC_DEFAULT & 1 ++ #define SIGN_LR hint 25 /* paciasp: sign with the A key */ ++ #define VERIFY_LR hint 29 /* autiasp: verify with the A key */ ++ #elif __ARM_FEATURE_PAC_DEFAULT & 2 ++ #define SIGN_LR hint 27 /* pacibsp: sign with the b key */ ++ #define VERIFY_LR hint 31 /* autibsp: verify with the b key */ ++ #endif ++ #define GNU_PROPERTY_AARCH64_POINTER_AUTH 2 /* bit 1 GNU Notes is for PAC support */ ++#else ++ #define SIGN_LR BTI_C ++ #define VERIFY_LR ++ #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 ++#endif ++ ++/* Add the BTI and PAC support to GNU Notes section */ ++#if GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 ++ .pushsection .note.gnu.property, "a"; /* Start a new allocatable section */ ++ .balign 8; /* align it on a byte boundry */ ++ .long 4; /* size of "GNU\0" */ ++ .long 0x10; /* size of descriptor */ ++ .long 0x5; /* NT_GNU_PROPERTY_TYPE_0 */ ++ .asciz "GNU"; ++ .long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ ++ .long 4; /* Four bytes of data */ ++ .long (GNU_PROPERTY_AARCH64_BTI|GNU_PROPERTY_AARCH64_POINTER_AUTH); /* BTI or PAC is enabled */ ++ .long 0; /* padding for 8 byte alignment */ ++ .popsection; /* end the section */ ++#endif ++ ++#endif diff --git a/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch b/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch deleted file mode 100644 index 15de467..0000000 --- a/00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Wed, 12 Aug 2026 15:18:39 +0200 -Subject: 00466: Downstream only: Lower XML_COMBINED_VERSION threshold for - reparse deferral - -RHEL 9 expat 2.5.0 has XML_SetReparseDeferralEnabled backported -via the CVE-2023-52425 fix, but XML_COMBINED_VERSION remains 20500. -CPython's #if XML_COMBINED_VERSION >= 20600 guards compile the setter -as a no-op, so SetReparseDeferralEnabled silently does nothing and -GetReparseDeferralEnabled always returns False, even though the expat -library actually supports (and enables) reparse deferral. - -Lower the threshold from 20600 to 20500 so that CPython uses the -backported function. This makes the Python API actually work on RHEL 9 -and fixes test failures (test_reparse_deferral_disabled, -test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). - -The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the -backported function is available. ---- - Lib/test/test_pyexpat.py | 6 +++--- - Lib/test/test_sax.py | 4 ++-- - Lib/test/test_xml_etree.py | 4 ++-- - Modules/pyexpat.c | 6 +++--- - 4 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py -index ae7cec6540..7f73a8c5e7 100644 ---- a/Lib/test/test_pyexpat.py -+++ b/Lib/test/test_pyexpat.py -@@ -1001,7 +1001,7 @@ def test_error_path_no_crash(self): - class ReparseDeferralTest(unittest.TestCase): - def test_getter_setter_round_trip(self): - parser = expat.ParserCreate() -- enabled = (expat.version_info >= (2, 6, 0)) -+ enabled = (expat.version_info >= (2, 5, 0)) - - self.assertIs(parser.GetReparseDeferralEnabled(), enabled) - parser.SetReparseDeferralEnabled(False) -@@ -1010,7 +1010,7 @@ def test_getter_setter_round_trip(self): - self.assertIs(parser.GetReparseDeferralEnabled(), enabled) - - def test_reparse_deferral_enabled(self): -- if expat.version_info < (2, 6, 0): -+ if expat.version_info < (2, 5, 0): - self.skipTest(f'Expat {expat.version_info} does not ' - 'support reparse deferral') - -@@ -1041,7 +1041,7 @@ def start_element(name, _): - - parser = expat.ParserCreate() - parser.StartElementHandler = start_element -- if expat.version_info >= (2, 6, 0): -+ if expat.version_info >= (2, 5, 0): - parser.SetReparseDeferralEnabled(False) - self.assertFalse(parser.GetReparseDeferralEnabled()) - -diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py -index 9b3014a94a..0e38c9488e 100644 ---- a/Lib/test/test_sax.py -+++ b/Lib/test/test_sax.py -@@ -1215,7 +1215,7 @@ def test_expat_incremental_reset(self): - - self.assertEqual(result.getvalue(), start + b"text") - -- @unittest.skipIf(pyexpat.version_info < (2, 6, 0), -+ @unittest.skipIf(pyexpat.version_info < (2, 5, 0), - f'Expat {pyexpat.version_info} does not ' - 'support reparse deferral') - def test_flush_reparse_deferral_enabled(self): -@@ -1249,7 +1249,7 @@ def test_flush_reparse_deferral_disabled(self): - for chunk in (""): - parser.feed(chunk) - -- if pyexpat.version_info >= (2, 6, 0): -+ if pyexpat.version_info >= (2, 5, 0): - parser._parser.SetReparseDeferralEnabled(False) - self.assertEqual(result.getvalue(), start) # i.e. no elements started - -diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 4a76a5be1e..effb899d7b 100644 ---- a/Lib/test/test_xml_etree.py -+++ b/Lib/test/test_xml_etree.py -@@ -1804,7 +1804,7 @@ def test_unknown_event(self): - with self.assertRaisesRegex(ValueError, "unknown event 'bogus'"): - ET.XMLPullParser(events=(x.decode() for x in (b'start', b'end', b'bogus'))) - -- @unittest.skipIf(pyexpat.version_info < (2, 6, 0), -+ @unittest.skipIf(pyexpat.version_info < (2, 5, 0), - f'Expat {pyexpat.version_info} does not ' - 'support reparse deferral') - def test_flush_reparse_deferral_enabled(self): -@@ -1834,7 +1834,7 @@ def test_flush_reparse_deferral_disabled(self): - for chunk in (""): - parser.feed(chunk) - -- if pyexpat.version_info >= (2, 6, 0): -+ if pyexpat.version_info >= (2, 5, 0): - if not ET is pyET: - self.skipTest(f'XMLParser.(Get|Set)ReparseDeferralEnabled ' - 'methods not available in C') -diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c -index 9e5d84eb5e..b008fe66c1 100644 ---- a/Modules/pyexpat.c -+++ b/Modules/pyexpat.c -@@ -781,7 +781,7 @@ pyexpat_xmlparser_SetReparseDeferralEnabled_impl(xmlparseobject *self, - int enabled) - /*[clinic end generated code: output=5ec539e3b63c8c49 input=021eb9e0bafc32c5]*/ - { --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - XML_SetReparseDeferralEnabled(self->itself, enabled ? XML_TRUE : XML_FALSE); - self->reparse_deferral_enabled = (bool)enabled; - #endif -@@ -1446,7 +1446,7 @@ newxmlparseobject(pyexpat_state *state, const char *encoding, - self->ns_prefixes = 0; - self->handlers = NULL; - self->intern = Py_XNewRef(intern); --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - self->reparse_deferral_enabled = true; - #else - self->reparse_deferral_enabled = false; -@@ -2332,7 +2332,7 @@ pyexpat_exec(PyObject *mod) - #else - capi->SetHashSalt16Bytes = NULL; - #endif --#if XML_COMBINED_VERSION >= 20600 -+#if XML_COMBINED_VERSION >= 20500 - capi->SetReparseDeferralEnabled = XML_SetReparseDeferralEnabled; - #else - capi->SetReparseDeferralEnabled = NULL; diff --git a/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch b/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch new file mode 100644 index 0000000..643501b --- /dev/null +++ b/00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Tue, 24 Jun 2025 11:12:13 +0200 +Subject: 00466: Downstream only: Skip tests not working with older expat + version + +We want to run these tests in Fedora and EPEL 10, but not in EPEL 9, +which has too old version of expat. We set the upper bound version +in the conditionalized skip to a release available in CentOS Stream 10, +which is tested as working. +--- + Lib/test/test_pyexpat.py | 2 ++ + Lib/test/test_sax.py | 2 ++ + Lib/test/test_xml_etree.py | 6 ++++++ + 3 files changed, 10 insertions(+) + +diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py +index 2309353503..fca62245d4 100644 +--- a/Lib/test/test_pyexpat.py ++++ b/Lib/test/test_pyexpat.py +@@ -901,6 +901,8 @@ def start_element(name, _): + + self.assertEqual(started, ['doc']) + ++ @unittest.skipIf(expat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_reparse_deferral_disabled(self): + started = [] + +diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py +index 9b3014a94a..90401e0d8f 100644 +--- a/Lib/test/test_sax.py ++++ b/Lib/test/test_sax.py +@@ -1240,6 +1240,8 @@ def test_flush_reparse_deferral_enabled(self): + + self.assertEqual(result.getvalue(), start + b"") + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_flush_reparse_deferral_disabled(self): + result = BytesIO() + xmlgen = XMLGenerator(result) +diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py +index 597ec83061..bf2db1779c 100644 +--- a/Lib/test/test_xml_etree.py ++++ b/Lib/test/test_xml_etree.py +@@ -1574,9 +1574,13 @@ def test_simple_xml(self, chunk_size=None, flush=False): + self.assert_event_tags(parser, [('end', 'root')]) + self.assertIsNone(parser.close()) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_simple_xml_chunk_1(self): + self.test_simple_xml(chunk_size=1, flush=True) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_simple_xml_chunk_5(self): + self.test_simple_xml(chunk_size=5, flush=True) + +@@ -1803,6 +1807,8 @@ def test_flush_reparse_deferral_enabled(self): + + self.assert_event_tags(parser, [('end', 'doc')]) + ++ @unittest.skipIf(pyexpat.version_info < (2, 7, 1), ++ f"Skip for expat < 2.7.1 (version available in RHEL 10)") + def test_flush_reparse_deferral_disabled(self): + parser = ET.XMLPullParser(events=('start', 'end')) + diff --git a/00474-cve-2025-15366.patch b/00474-cve-2025-15366.patch new file mode 100644 index 0000000..32aa4c3 --- /dev/null +++ b/00474-cve-2025-15366.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Tue, 20 Jan 2026 14:45:42 -0600 +Subject: 00474: CVE-2025-15366 + +Reject control characters in IMAP commands +--- + Lib/imaplib.py | 4 +++- + Lib/test/test_imaplib.py | 6 ++++++ + .../Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 + + 3 files changed, 10 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst + +diff --git a/Lib/imaplib.py b/Lib/imaplib.py +index 141e639894..f282e5c061 100644 +--- a/Lib/imaplib.py ++++ b/Lib/imaplib.py +@@ -132,7 +132,7 @@ + # We compile these in _mode_xxx. + _Literal = br'.*{(?P\d+)}$' + _Untagged_status = br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?' +- ++_control_chars = re.compile(b'[\x00-\x1F\x7F]') + + + class IMAP4: +@@ -1000,6 +1000,8 @@ def _command(self, name, *args): + if arg is None: continue + if isinstance(arg, str): + arg = bytes(arg, self._encoding) ++ if _control_chars.search(arg): ++ raise ValueError("Control characters not allowed in commands") + data = data + b' ' + arg + + literal = self.literal +diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py +index 9f1f682d02..820c2a5db5 100644 +--- a/Lib/test/test_imaplib.py ++++ b/Lib/test/test_imaplib.py +@@ -515,6 +515,12 @@ def test_login(self): + self.assertEqual(data[0], b'LOGIN completed') + self.assertEqual(client.state, 'AUTH') + ++ def test_control_characters(self): ++ client, _ = self._setup(SimpleIMAPHandler) ++ for c0 in support.control_characters_c0(): ++ with self.assertRaises(ValueError): ++ client.login(f'user{c0}', 'pass') ++ + def test_logout(self): + client, _ = self._setup(SimpleIMAPHandler) + typ, data = client.login('user', 'pass') +diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst +new file mode 100644 +index 0000000000..4e13fe92bc +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst +@@ -0,0 +1 @@ ++Reject control characters in IMAP commands. diff --git a/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch b/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch index f860aa1..2f47bac 100644 --- a/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch +++ b/00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch @@ -81,10 +81,10 @@ index 2a17c891dd..64017c666c 100644 } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in -index 2363b99a25..f1a07645f0 100644 +index ecf77bdc41..91bfd06a78 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in -@@ -3159,3 +3159,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h +@@ -3153,3 +3153,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h # Local Variables: # mode: makefile # End: @@ -92,10 +92,10 @@ index 2363b99a25..f1a07645f0 100644 +# Fedora-specific, downstream only +PY_STDMODULE_CFLAGS += -D_PyHack_check_version_on_modinit=1 diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c -index 1996488a0e..cfdffd8ec4 100644 +index 0200f59020..bb647555c0 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c -@@ -5011,6 +5011,12 @@ curses_destructor(PyObject *op) +@@ -4763,6 +4763,12 @@ curses_destructor(PyObject *op) PyMODINIT_FUNC PyInit__curses(void) { @@ -109,10 +109,10 @@ index 1996488a0e..cfdffd8ec4 100644 /* Initialize object type */ diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c -index 4e8d75e8e1..32e58755aa 100644 +index 14efe18db5..70597c2815 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c -@@ -3499,6 +3499,12 @@ static struct PyModuleDef _tkintermodule = { +@@ -3431,6 +3431,12 @@ static struct PyModuleDef _tkintermodule = { PyMODINIT_FUNC PyInit__tkinter(void) { @@ -143,10 +143,10 @@ index 0b85187e5f..87f358ed07 100644 m = PyModule_Create(&module_def); if (m == NULL) diff --git a/Modules/readline.c b/Modules/readline.c -index 7a612deae4..8b2f47eec1 100644 +index f9362c312d..66f1ec65a6 100644 --- a/Modules/readline.c +++ b/Modules/readline.c -@@ -1548,6 +1548,12 @@ static struct PyModuleDef readlinemodule = { +@@ -1540,6 +1540,12 @@ static struct PyModuleDef readlinemodule = { PyMODINIT_FUNC PyInit_readline(void) { diff --git a/plan.fmf b/plan.fmf index 9c9afb8..432f1a3 100644 --- a/plan.fmf +++ b/plan.fmf @@ -43,9 +43,6 @@ discover: - name: marshalparser path: /marshalparser test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh" - - name: required_symbols - path: /required-symbols - test: "VERSION=${pybasever} ./check.sh" prepare: - name: Install dependencies @@ -65,9 +62,8 @@ prepare: - virtualenv # for virtualenv tests - glibc-all-langpacks # for locale tests - marshalparser # for testing compatibility (magic numbers) with marshalparser - - binutils # for nm (symbol inspection) - rpm # for debugging - - dnf # for upgrade and downgrade + - dnf # for upgrade - name: Update packages how: shell script: dnf upgrade -y diff --git a/python3.13.spec b/python3.13.spec index 4045e62..0a196bb 100644 --- a/python3.13.spec +++ b/python3.13.spec @@ -45,11 +45,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.15 +%global general_version %{pybasever}.13 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -109,30 +109,31 @@ License: Python-2.0.1 # This needs to be manually updated when we update Python. # Explore the sources tarball (you need the version before %%prep is executed): # $ tar -tf Python-%%{upstream_version}.tar.xz | grep whl -%global pip_version 26.2.1 +%global pip_version 26.0.1 %global setuptools_version 79.0.1 # All of those also include a list of indirect bundled libs: # pip # $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) %global pip_bundled_provides %{expand: Provides: bundled(python3dist(cachecontrol)) = 0.14.4 -Provides: bundled(python3dist(certifi)) = 2026.6.17 -Provides: bundled(python3dist(distlib)) = 0.4.2 +Provides: bundled(python3dist(certifi)) = 2026.1.4 +Provides: bundled(python3dist(dependency-groups)) = 1.3.1 +Provides: bundled(python3dist(distlib)) = 0.4 Provides: bundled(python3dist(distro)) = 1.9 -Provides: bundled(python3dist(idna)) = 3.18 +Provides: bundled(python3dist(idna)) = 3.11 Provides: bundled(python3dist(msgpack)) = 1.1.2 -Provides: bundled(python3dist(packaging)) = 26.2 -Provides: bundled(python3dist(platformdirs)) = 4.10 -Provides: bundled(python3dist(pygments)) = 2.20 +Provides: bundled(python3dist(packaging)) = 26 +Provides: bundled(python3dist(platformdirs)) = 4.5.1 +Provides: bundled(python3dist(pygments)) = 2.19.2 Provides: bundled(python3dist(pyproject-hooks)) = 1.2 -Provides: bundled(python3dist(requests)) = 2.34.2 +Provides: bundled(python3dist(requests)) = 2.32.5 Provides: bundled(python3dist(resolvelib)) = 1.2.1 Provides: bundled(python3dist(rich)) = 14.2 Provides: bundled(python3dist(setuptools)) = 70.3 -Provides: bundled(python3dist(tomli)) = 2.4.1 +Provides: bundled(python3dist(tomli)) = 2.3 Provides: bundled(python3dist(tomli-w)) = 1.2 Provides: bundled(python3dist(truststore)) = 0.10.4 -Provides: bundled(python3dist(urllib3)) = 2.7 +Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools # vendor.txt not in .whl @@ -254,7 +255,7 @@ Obsoletes: python%{pybasever}%{?1:-%{1}}\ BuildRequires: autoconf BuildRequires: bluez-libs-devel BuildRequires: bzip2-devel -BuildRequires: expat-devel >= 2.5.0-2 +BuildRequires: expat-devel BuildRequires: findutils BuildRequires: gcc BuildRequires: gdbm-devel @@ -267,6 +268,7 @@ BuildRequires: libuuid-devel BuildRequires: make BuildRequires: mpdecimal-devel BuildRequires: ncurses-devel +BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: python-rpm-macros BuildRequires: readline-devel @@ -279,10 +281,6 @@ BuildRequires: xz-devel BuildRequires: zlib-devel BuildRequires: /usr/bin/dtrace -# Support for OpenSSL 4 only landed in Python 3.15 for now -# https://github.com/python/cpython/issues/146207 -BuildRequires: (openssl-devel < 1:4 or openssl3-devel) - %if %{undefined rhel} BuildRequires: libb2-devel %endif @@ -370,24 +368,37 @@ Source11: idle3.appdata.xml # pypa/distutils integration: https://github.com/pypa/distutils/pull/70 Patch251: 00251-change-user-install-location.patch -# 00466 # 713a1368544eddd55088d67f88a23ce31722a4cb -# Downstream only: Lower XML_COMBINED_VERSION threshold for reparse deferral +# 00464 # 292acffec7a379cb6d1f3c47b9e5a2f170bbadb6 +# Enable PAC and BTI protections for aarch64 # -# RHEL 9 expat 2.5.0 has XML_SetReparseDeferralEnabled backported -# via the CVE-2023-52425 fix, but XML_COMBINED_VERSION remains 20500. -# CPython's #if XML_COMBINED_VERSION >= 20600 guards compile the setter -# as a no-op, so SetReparseDeferralEnabled silently does nothing and -# GetReparseDeferralEnabled always returns False, even though the expat -# library actually supports (and enables) reparse deferral. +# Apply protection against ROP/JOP attacks for aarch64 on asm_trampoline.S # -# Lower the threshold from 20600 to 20500 so that CPython uses the -# backported function. This makes the Python API actually work on RHEL 9 -# and fixes test failures (test_reparse_deferral_disabled, -# test_flush_reparse_deferral_disabled, test_simple_xml_chunk_*). +# The BTI flag must be applied in the assembler sources for this class +# of attacks to be mitigated on newer aarch64 processors. # -# The spec file BuildRequires expat-devel >= 2.5.0-2 to ensure the -# backported function is available. -Patch466: 00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch +# Upstream PR: https://github.com/python/cpython/pull/130864/files +# +# The upstream patch is incomplete but only for the case where +# frame pointers are not used on 3.13+. +# +# Since on Fedora we always compile with frame pointers the BTI/PAC +# hardware protections can be enabled without losing Perf unwinding. +Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch + +# 00466 # e10760fb955ee33d2917f8a57bb4e24d71e5341c +# Downstream only: Skip tests not working with older expat version +# +# We want to run these tests in Fedora and EPEL 10, but not in EPEL 9, +# which has too old version of expat. We set the upper bound version +# in the conditionalized skip to a release available in CentOS Stream 10, +# which is tested as working. +Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch + +# 00474 # 837ddca0372fa87ff9cee47142200caa21e77def +# CVE-2025-15366 +# +# Reject control characters in IMAP commands +Patch474: 00474-cve-2025-15366.patch # 00475 # d44fac01037662db286449a78c8fb819788f764c # CVE-2025-15367 @@ -534,7 +545,7 @@ Summary: Python runtime libraries # Combined manually from https://docs.python.org/3.13/license.html # Hash of Doc/license.rst which is compared in %%prep, generated with: # $ sha256sum Doc/license.rst | cut -f1 -d" " -%global license_file_hash 952ac05720d7f1dcb63589b35eb0931b1442eb250230a4ad31198eddf0ad6abc +%global license_file_hash 62f2c9c2c75d511170eb464ad5f83b78cc1f37eb2eb49c2846c9aa6c4557ee99 # Licenses of incorporated software: # Mersenne Twister in _random C extension contains code under BSD-3-Clause # socket.getaddrinfo() and socket.getnameinfo() are BSD-3-Clause @@ -557,11 +568,10 @@ Summary: Python runtime libraries # mimalloc is MIT # parts of asyncio from uvloop are MIT # Python/qsbr.c is adapted from code under BSD-2-Clause -# An extract of the `Unicode Character Database` converted to an internal format is Unicode-3.0 # Bundled libb2 is not declared in the upstream document, but it's: # CC0-1.0, covered by grandfathering exception # We don't query upstream for changes, as 3.13 is the last Python version containing it. -%global libs_license Python-2.0.1 AND CC0-1.0 AND MIT AND BSD-3-Clause AND MIT-CMU AND HPND-SMC AND BSD-2-Clause AND dtoa AND Unicode-3.0 +%global libs_license Python-2.0.1 AND CC0-1.0 AND MIT AND BSD-3-Clause AND MIT-CMU AND HPND-SMC AND BSD-2-Clause AND dtoa %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 License: %{libs_license} @@ -608,12 +618,10 @@ Requires: tzdata # This breaks many things, including python -m venv. # We avoid this problem by requiring at least the same version of expat that # was used during the build time. -# We also include release, in case pyxpat uses ABI that was backported -# (e.g. XML_SetReparseDeferralEnabled was added in c9s expat 2.5.0-2). # Other subpackages (like -debug) also need this, but they all depend on -libs. # Since expat 2.7.4, the library has versioned symbols and this is no longer needed, # as the generated requirement will be in the form of libexpat.so.1(LIBEXPAT_2.7.2) etc. -%global expat_version %(LANG=C rpm -q --qf '%%{version}-%%{release}' expat.%{_target_cpu} | sed 's/.*not installed/0/') +%global expat_version %(LANG=C rpm -q --qf '%%{version}' expat.%{_target_cpu} | sed 's/.*not installed/0/') %if v"%{expat_version}" < v"2.7.4" Requires: expat%{?_isa} >= %{expat_version} %endif @@ -1818,18 +1826,6 @@ CheckPython freethreading # ====================================================== %changelog -* Wed Aug 12 2026 Miro Hrončok - 3.13.15-2 -- On EPEL 9, also supports reparse deferral in expat - -* Mon Aug 10 2026 Karolina Surma - 3.13.15-1 -- Update to Python 3.13.15 - -* Thu Jul 16 2026 Fedora Release Engineering - 3.13.14-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild - -* Thu Jun 11 2026 Karolina Surma - 3.13.14-1 -- Update to Python 3.13.14 - * Wed Apr 08 2026 Tomáš Hrnčiar - 3.13.13-1 - Update to 3.13.13 diff --git a/sources b/sources index d6a2436..8ca0534 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.13.15.tar.xz) = b0ab766a3de0b4cfdbf0b93300d7330c734d3f7057577bb03e95e39da4cdade81993e769c7fa6dfdcc13b9d43a3b399d9cd89b5477b413662e9e691c1b7886b8 -SHA512 (Python-3.13.15.tar.xz.asc) = 662c00be95f62e80db43cf42099fef91f764ff7a4433cadf7eb19dedb5e4775adb12878d5ed2295fcea187731de186163ad9672ab72cde62a2335ca58ec1ad86 +SHA512 (Python-3.13.13.tar.xz) = 0ef615150a52865fe7ca0d0e106cf98488f113a56e5ae1b1437673f03880423839d04abe1999006f9835c77d8802d5ae94a1bdf63d18074a9a19c81e6f7b69e8 +SHA512 (Python-3.13.13.tar.xz.asc) = 21e5235cd9a9df3546370feb55ac32539e08601b79ee7b1e39006028f192be6be0434f2f8384fdcc993b70bde7471be3b36ce9850abf0473d1fe2c7cdc98304b