Compare commits
3 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3a2a2f198 | ||
|
|
4244427aac | ||
|
|
900ee2da17 |
10 changed files with 258 additions and 501 deletions
|
|
@ -30,7 +30,7 @@ Co-authored-by: Lumír Balhar <frenzy.madness@gmail.com>
|
||||||
3 files changed, 72 insertions(+), 4 deletions(-)
|
3 files changed, 72 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
diff --git a/Lib/site.py b/Lib/site.py
|
diff --git a/Lib/site.py b/Lib/site.py
|
||||||
index 041dca113a..ca6320df2f 100644
|
index aedf36399c..2ae49a8029 100644
|
||||||
--- a/Lib/site.py
|
--- a/Lib/site.py
|
||||||
+++ b/Lib/site.py
|
+++ b/Lib/site.py
|
||||||
@@ -415,8 +415,15 @@ def getsitepackages(prefixes=None):
|
@@ -415,8 +415,15 @@ def getsitepackages(prefixes=None):
|
||||||
|
|
@ -51,7 +51,7 @@ index 041dca113a..ca6320df2f 100644
|
||||||
if os.path.isdir(sitedir):
|
if os.path.isdir(sitedir):
|
||||||
addsitedir(sitedir, known_paths)
|
addsitedir(sitedir, known_paths)
|
||||||
diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py
|
diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py
|
||||||
index 43edebce34..40e85568ea 100644
|
index f7bd675bb3..f1ff347c3d 100644
|
||||||
--- a/Lib/sysconfig/__init__.py
|
--- a/Lib/sysconfig/__init__.py
|
||||||
+++ b/Lib/sysconfig/__init__.py
|
+++ b/Lib/sysconfig/__init__.py
|
||||||
@@ -106,6 +106,12 @@
|
@@ -106,6 +106,12 @@
|
||||||
|
|
@ -130,7 +130,7 @@ index 43edebce34..40e85568ea 100644
|
||||||
# On Windows we want to substitute 'lib' for schemes rather
|
# On Windows we want to substitute 'lib' for schemes rather
|
||||||
# than the native value (without modifying vars, in case it
|
# than the native value (without modifying vars, in case it
|
||||||
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
|
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
|
||||||
index ce17206a3c..fd95071099 100644
|
index 9723300f51..310706652a 100644
|
||||||
--- a/Lib/test/test_sysconfig.py
|
--- a/Lib/test/test_sysconfig.py
|
||||||
+++ b/Lib/test/test_sysconfig.py
|
+++ b/Lib/test/test_sysconfig.py
|
||||||
@@ -130,8 +130,19 @@ def test_get_path(self):
|
@@ -130,8 +130,19 @@ def test_get_path(self):
|
||||||
|
|
@ -154,7 +154,7 @@ index ce17206a3c..fd95071099 100644
|
||||||
os.path.normpath(expected),
|
os.path.normpath(expected),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -395,7 +406,7 @@ def test_get_config_h_filename(self):
|
@@ -393,7 +404,7 @@ def test_get_config_h_filename(self):
|
||||||
self.assertTrue(os.path.isfile(config_h), config_h)
|
self.assertTrue(os.path.isfile(config_h), config_h)
|
||||||
|
|
||||||
def test_get_scheme_names(self):
|
def test_get_scheme_names(self):
|
||||||
|
|
@ -163,7 +163,7 @@ index ce17206a3c..fd95071099 100644
|
||||||
if HAS_USER_BASE:
|
if HAS_USER_BASE:
|
||||||
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
|
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
|
||||||
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
|
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
|
||||||
@@ -407,6 +418,8 @@ def test_symlink(self): # Issue 7880
|
@@ -405,6 +416,8 @@ def test_symlink(self): # Issue 7880
|
||||||
cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
|
cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
|
||||||
self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))
|
self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
|
||||||
|
Date: Fri, 25 Apr 2025 09:33:37 +0200
|
||||||
|
Subject: 00461: Downstream only: Install wheel in test venvs when setuptools <
|
||||||
|
71
|
||||||
|
|
||||||
|
---
|
||||||
|
Lib/test/support/__init__.py | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
|
||||||
|
index 4605938b87..a0055d6887 100644
|
||||||
|
--- a/Lib/test/support/__init__.py
|
||||||
|
+++ b/Lib/test/support/__init__.py
|
||||||
|
@@ -2462,9 +2462,16 @@ def run_command(cmd):
|
||||||
|
else:
|
||||||
|
python = os.path.join(venv, 'bin', python_exe)
|
||||||
|
|
||||||
|
+ setuptools_whl = _findwheel('setuptools')
|
||||||
|
+ whl_filename = os.path.basename(setuptools_whl)
|
||||||
|
+ setuptools_major = int(whl_filename.split('-')[1].split('.')[0])
|
||||||
|
+ if setuptools_major >= 71: # we need 70.1+, but that's OK
|
||||||
|
+ wheels = (setuptools_whl,)
|
||||||
|
+ else:
|
||||||
|
+ wheels = (setuptools_whl, _findwheel('wheel'))
|
||||||
|
cmd = (python, '-X', 'dev',
|
||||||
|
'-m', 'pip', 'install',
|
||||||
|
- _findwheel('setuptools'),
|
||||||
|
+ *wheels,
|
||||||
|
)
|
||||||
|
run_command(cmd)
|
||||||
|
|
||||||
102
00464-enable-pac-and-bti-protections-for-aarch64.patch
Normal file
102
00464-enable-pac-and-bti-protections-for-aarch64.patch
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Charalampos Stratakis <cstratak@redhat.com>
|
||||||
|
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
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
|
|
||||||
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"<doc>text</doc>")
|
|
||||||
|
|
||||||
- @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 ("<doc", ">"):
|
|
||||||
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 ("<doc", ">"):
|
|
||||||
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;
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Karolina Surma <ksurma@redhat.com>
|
||||||
|
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 a091430463..55ebf34c52 100644
|
||||||
|
--- a/Lib/test/test_pyexpat.py
|
||||||
|
+++ b/Lib/test/test_pyexpat.py
|
||||||
|
@@ -826,6 +826,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"<doc></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):
|
||||||
|
result = BytesIO()
|
||||||
|
xmlgen = XMLGenerator(result)
|
||||||
|
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
|
||||||
|
index 78598b35da..802d1399ea 100644
|
||||||
|
--- a/Lib/test/test_xml_etree.py
|
||||||
|
+++ b/Lib/test/test_xml_etree.py
|
||||||
|
@@ -1548,9 +1548,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)
|
||||||
|
|
||||||
|
@@ -1777,6 +1781,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'))
|
||||||
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Seth Michael Larson <seth@python.org>
|
|
||||||
Date: Tue, 20 Jan 2026 14:46:32 -0600
|
|
||||||
Subject: 00475: CVE-2025-15367
|
|
||||||
|
|
||||||
Reject control characters in POP3 commands
|
|
||||||
---
|
|
||||||
Lib/poplib.py | 2 ++
|
|
||||||
Lib/test/test_poplib.py | 8 ++++++++
|
|
||||||
.../2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 +
|
|
||||||
3 files changed, 11 insertions(+)
|
|
||||||
create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
|
|
||||||
|
|
||||||
diff --git a/Lib/poplib.py b/Lib/poplib.py
|
|
||||||
index 4469bff44b..b97274c5c3 100644
|
|
||||||
--- a/Lib/poplib.py
|
|
||||||
+++ b/Lib/poplib.py
|
|
||||||
@@ -122,6 +122,8 @@ def _putline(self, line):
|
|
||||||
def _putcmd(self, line):
|
|
||||||
if self._debugging: print('*cmd*', repr(line))
|
|
||||||
line = bytes(line, self.encoding)
|
|
||||||
+ if re.search(b'[\x00-\x1F\x7F]', line):
|
|
||||||
+ raise ValueError('Control characters not allowed in commands')
|
|
||||||
self._putline(line)
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py
|
|
||||||
index eb6dab4015..bd621caee4 100644
|
|
||||||
--- a/Lib/test/test_poplib.py
|
|
||||||
+++ b/Lib/test/test_poplib.py
|
|
||||||
@@ -18,6 +18,7 @@
|
|
||||||
from test.support import asynchat
|
|
||||||
from test.support import asyncore
|
|
||||||
from test.support.testcase import ExtraAssertions
|
|
||||||
+from test.support import control_characters_c0
|
|
||||||
|
|
||||||
|
|
||||||
test_support.requires_working_socket(module=True)
|
|
||||||
@@ -396,6 +397,13 @@ def test_quit(self):
|
|
||||||
self.assertIsNone(self.client.sock)
|
|
||||||
self.assertIsNone(self.client.file)
|
|
||||||
|
|
||||||
+ def test_control_characters(self):
|
|
||||||
+ for c0 in control_characters_c0():
|
|
||||||
+ with self.assertRaises(ValueError):
|
|
||||||
+ self.client.user(f'user{c0}')
|
|
||||||
+ with self.assertRaises(ValueError):
|
|
||||||
+ self.client.pass_(f'{c0}pass')
|
|
||||||
+
|
|
||||||
@requires_ssl
|
|
||||||
def test_stls_capa(self):
|
|
||||||
capa = self.client.capa()
|
|
||||||
diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..3cde4df3e0
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+Reject control characters in POP3 commands.
|
|
||||||
|
|
@ -1,173 +0,0 @@
|
||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Petr Viktorin <encukou@gmail.com>
|
|
||||||
Date: Mon, 9 Feb 2026 10:44:21 +0100
|
|
||||||
Subject: 00477: Raise an error when importing stdlib modules compiled for a
|
|
||||||
different Python version
|
|
||||||
|
|
||||||
This is a downstream workaround "implementing" python#137212 -
|
|
||||||
the mechanism for the check exists in Python 3.15+, where it needs to be
|
|
||||||
added to the standard library modules.
|
|
||||||
In Fedora, we need it also in previous Python versions, as we experience
|
|
||||||
segmentation fault when importing stdlib modules after update while
|
|
||||||
Python is running.
|
|
||||||
|
|
||||||
_curses, _tkinter, _tracemalloc and readline are not calling PyModuleDef_Init,
|
|
||||||
which is modified with this patch, hence they need a
|
|
||||||
direct call to the check function.
|
|
||||||
|
|
||||||
Co-Authored-By: Karolina Surma <ksurma@redhat.com>
|
|
||||||
---
|
|
||||||
Include/moduleobject.h | 43 +++++++++++++++++++++++++++++++++++++++++
|
|
||||||
Makefile.pre.in | 3 +++
|
|
||||||
Modules/_cursesmodule.c | 6 ++++++
|
|
||||||
Modules/_tkinter.c | 6 ++++++
|
|
||||||
Modules/_tracemalloc.c | 6 ++++++
|
|
||||||
Modules/readline.c | 6 ++++++
|
|
||||||
Objects/moduleobject.c | 1 +
|
|
||||||
7 files changed, 71 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/Include/moduleobject.h b/Include/moduleobject.h
|
|
||||||
index 2a17c891dd..64017c666c 100644
|
|
||||||
--- a/Include/moduleobject.h
|
|
||||||
+++ b/Include/moduleobject.h
|
|
||||||
@@ -116,6 +116,49 @@ struct PyModuleDef {
|
|
||||||
freefunc m_free;
|
|
||||||
};
|
|
||||||
|
|
||||||
+#if defined(_PyHack_check_version_on_modinit) && defined(Py_BUILD_CORE)
|
|
||||||
+/* The mechanism for the check has been implemented on Python 3.15+:
|
|
||||||
+ * https://github.com/python/cpython/pull/137212.
|
|
||||||
+ * In Fedora, we need this in older Pythons too:
|
|
||||||
+ * if somebody attempts to import a module compiled for a different Python version,
|
|
||||||
+ * instead of segmentation fault a meaningful error is raised.
|
|
||||||
+ */
|
|
||||||
+PyAPI_DATA(const unsigned long) Py_Version;
|
|
||||||
+
|
|
||||||
+static inline int
|
|
||||||
+_PyHack_CheckInternalAPIVersion(const char *mod_name)
|
|
||||||
+{
|
|
||||||
+ if (PY_VERSION_HEX != Py_Version) {
|
|
||||||
+ PyErr_Format(
|
|
||||||
+ PyExc_ImportError,
|
|
||||||
+ "internal Python C API version mismatch: "
|
|
||||||
+ "module %s compiled with %lu.%lu.%lu; "
|
|
||||||
+ "runtime version is %lu.%lu.%lu",
|
|
||||||
+ mod_name,
|
|
||||||
+ (const unsigned long)((PY_VERSION_HEX >> 24) & 0xFF),
|
|
||||||
+ (const unsigned long)((PY_VERSION_HEX >> 16) & 0xFF),
|
|
||||||
+ (const unsigned long)((PY_VERSION_HEX >> 8) & 0xFF),
|
|
||||||
+ (const unsigned long)((Py_Version >> 24) & 0xFF),
|
|
||||||
+ (const unsigned long)((Py_Version >> 16) & 0xFF),
|
|
||||||
+ (const unsigned long)((Py_Version >> 8) & 0xFF)
|
|
||||||
+ );
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline PyObject *
|
|
||||||
+PyModuleDef_Init_with_check(PyModuleDef *def)
|
|
||||||
+{
|
|
||||||
+ if (_PyHack_CheckInternalAPIVersion(def->m_name) < 0) {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ return PyModuleDef_Init(def);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#define PyModuleDef_Init PyModuleDef_Init_with_check
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
diff --git a/Makefile.pre.in b/Makefile.pre.in
|
|
||||||
index 2363b99a25..f1a07645f0 100644
|
|
||||||
--- a/Makefile.pre.in
|
|
||||||
+++ b/Makefile.pre.in
|
|
||||||
@@ -3159,3 +3159,6 @@ MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h
|
|
||||||
# Local Variables:
|
|
||||||
# mode: makefile
|
|
||||||
# End:
|
|
||||||
+
|
|
||||||
+# 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
|
|
||||||
--- a/Modules/_cursesmodule.c
|
|
||||||
+++ b/Modules/_cursesmodule.c
|
|
||||||
@@ -5011,6 +5011,12 @@ curses_destructor(PyObject *op)
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
PyInit__curses(void)
|
|
||||||
{
|
|
||||||
+ #ifdef _PyHack_check_version_on_modinit
|
|
||||||
+ if (_PyHack_CheckInternalAPIVersion("_curses") < 0) {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ #endif
|
|
||||||
+
|
|
||||||
PyObject *m, *d, *v, *c_api_object;
|
|
||||||
|
|
||||||
/* Initialize object type */
|
|
||||||
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
|
|
||||||
index 4e8d75e8e1..32e58755aa 100644
|
|
||||||
--- a/Modules/_tkinter.c
|
|
||||||
+++ b/Modules/_tkinter.c
|
|
||||||
@@ -3499,6 +3499,12 @@ static struct PyModuleDef _tkintermodule = {
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
PyInit__tkinter(void)
|
|
||||||
{
|
|
||||||
+ #ifdef _PyHack_check_version_on_modinit
|
|
||||||
+ if (_PyHack_CheckInternalAPIVersion("_tkinter") < 0) {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ #endif
|
|
||||||
+
|
|
||||||
PyObject *m, *uexe, *cexe;
|
|
||||||
|
|
||||||
tcl_lock = PyThread_allocate_lock();
|
|
||||||
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
|
|
||||||
index 0b85187e5f..87f358ed07 100644
|
|
||||||
--- a/Modules/_tracemalloc.c
|
|
||||||
+++ b/Modules/_tracemalloc.c
|
|
||||||
@@ -215,6 +215,12 @@ static struct PyModuleDef module_def = {
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
PyInit__tracemalloc(void)
|
|
||||||
{
|
|
||||||
+ #ifdef _PyHack_check_version_on_modinit
|
|
||||||
+ if (_PyHack_CheckInternalAPIVersion("_tracemalloc") < 0) {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ #endif
|
|
||||||
+
|
|
||||||
PyObject *m;
|
|
||||||
m = PyModule_Create(&module_def);
|
|
||||||
if (m == NULL)
|
|
||||||
diff --git a/Modules/readline.c b/Modules/readline.c
|
|
||||||
index 7a612deae4..8b2f47eec1 100644
|
|
||||||
--- a/Modules/readline.c
|
|
||||||
+++ b/Modules/readline.c
|
|
||||||
@@ -1548,6 +1548,12 @@ static struct PyModuleDef readlinemodule = {
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
PyInit_readline(void)
|
|
||||||
{
|
|
||||||
+ #ifdef _PyHack_check_version_on_modinit
|
|
||||||
+ if (_PyHack_CheckInternalAPIVersion("readline") < 0) {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ #endif
|
|
||||||
+
|
|
||||||
const char *backend = "readline";
|
|
||||||
PyObject *m;
|
|
||||||
readlinestate *mod_state;
|
|
||||||
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
|
|
||||||
index d787f29004..31175ceb3f 100644
|
|
||||||
--- a/Objects/moduleobject.c
|
|
||||||
+++ b/Objects/moduleobject.c
|
|
||||||
@@ -43,6 +43,7 @@ _PyModule_IsExtension(PyObject *obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+#undef PyModuleDef_Init
|
|
||||||
PyObject*
|
|
||||||
PyModuleDef_Init(PyModuleDef* def)
|
|
||||||
{
|
|
||||||
6
plan.fmf
6
plan.fmf
|
|
@ -43,9 +43,6 @@ discover:
|
||||||
- name: marshalparser
|
- name: marshalparser
|
||||||
path: /marshalparser
|
path: /marshalparser
|
||||||
test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh"
|
test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh"
|
||||||
- name: required_symbols
|
|
||||||
path: /required-symbols
|
|
||||||
test: "VERSION=${pybasever} ./check.sh"
|
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|
@ -65,9 +62,8 @@ prepare:
|
||||||
- virtualenv # for virtualenv tests
|
- virtualenv # for virtualenv tests
|
||||||
- glibc-all-langpacks # for locale tests
|
- glibc-all-langpacks # for locale tests
|
||||||
- marshalparser # for testing compatibility (magic numbers) with marshalparser
|
- marshalparser # for testing compatibility (magic numbers) with marshalparser
|
||||||
- binutils # for nm (symbol inspection)
|
|
||||||
- rpm # for debugging
|
- rpm # for debugging
|
||||||
- dnf # for upgrade and downgrade
|
- dnf # for upgrade
|
||||||
- name: Update packages
|
- name: Update packages
|
||||||
how: shell
|
how: shell
|
||||||
script: dnf upgrade -y
|
script: dnf upgrade -y
|
||||||
|
|
|
||||||
175
python3.13.spec
175
python3.13.spec
|
|
@ -45,11 +45,11 @@ URL: https://www.python.org/
|
||||||
|
|
||||||
# WARNING When rebasing to a new Python version,
|
# WARNING When rebasing to a new Python version,
|
||||||
# remember to update the python3-docs package as well
|
# remember to update the python3-docs package as well
|
||||||
%global general_version %{pybasever}.15
|
%global general_version %{pybasever}.9
|
||||||
#global prerel ...
|
#global prerel ...
|
||||||
%global upstream_version %{general_version}%{?prerel}
|
%global upstream_version %{general_version}%{?prerel}
|
||||||
Version: %{general_version}%{?prerel:~%{prerel}}
|
Version: %{general_version}%{?prerel:~%{prerel}}
|
||||||
Release: 2%{?dist}
|
Release: 1%{?dist}
|
||||||
License: Python-2.0.1
|
License: Python-2.0.1
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,10 +78,9 @@ License: Python-2.0.1
|
||||||
|
|
||||||
# PEP 744: JIT Compilation
|
# PEP 744: JIT Compilation
|
||||||
# Whether to build with the experimental JIT compiler
|
# Whether to build with the experimental JIT compiler
|
||||||
# We can only have this on Fedora 40+, where clang 18+ is available
|
# On EPEL 10.0 clang 18 is not available, hence it's disabled
|
||||||
# And only on certain architectures: https://peps.python.org/pep-0744/#support
|
|
||||||
# The freethreading build (when enabled) does not support JIT yet
|
# The freethreading build (when enabled) does not support JIT yet
|
||||||
%bcond jit %[(0%{?fedora} >= 40 || 0%{?epel} >= 10) && ("%{_arch}" == "x86_64" || "%{_arch}" == "aarch64")]
|
%bcond jit 0
|
||||||
%if %{with jit}
|
%if %{with jit}
|
||||||
# When built with JIT, it still needs to be enabled on runtime via PYTHON_JIT=1
|
# When built with JIT, it still needs to be enabled on runtime via PYTHON_JIT=1
|
||||||
%global jit_flag --enable-experimental-jit=yes-off
|
%global jit_flag --enable-experimental-jit=yes-off
|
||||||
|
|
@ -109,30 +108,31 @@ License: Python-2.0.1
|
||||||
# This needs to be manually updated when we update Python.
|
# This needs to be manually updated when we update Python.
|
||||||
# Explore the sources tarball (you need the version before %%prep is executed):
|
# Explore the sources tarball (you need the version before %%prep is executed):
|
||||||
# $ tar -tf Python-%%{upstream_version}.tar.xz | grep whl
|
# $ tar -tf Python-%%{upstream_version}.tar.xz | grep whl
|
||||||
%global pip_version 26.2.1
|
%global pip_version 25.2
|
||||||
%global setuptools_version 79.0.1
|
%global setuptools_version 79.0.1
|
||||||
# All of those also include a list of indirect bundled libs:
|
# All of those also include a list of indirect bundled libs:
|
||||||
# pip
|
# pip
|
||||||
# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt)
|
# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt)
|
||||||
%global pip_bundled_provides %{expand:
|
%global pip_bundled_provides %{expand:
|
||||||
Provides: bundled(python3dist(cachecontrol)) = 0.14.4
|
Provides: bundled(python3dist(cachecontrol)) = 0.14.3
|
||||||
Provides: bundled(python3dist(certifi)) = 2026.6.17
|
Provides: bundled(python3dist(certifi)) = 2025.7.14
|
||||||
Provides: bundled(python3dist(distlib)) = 0.4.2
|
Provides: bundled(python3dist(dependency-groups)) = 1.3.1
|
||||||
|
Provides: bundled(python3dist(distlib)) = 0.4
|
||||||
Provides: bundled(python3dist(distro)) = 1.9
|
Provides: bundled(python3dist(distro)) = 1.9
|
||||||
Provides: bundled(python3dist(idna)) = 3.18
|
Provides: bundled(python3dist(idna)) = 3.10
|
||||||
Provides: bundled(python3dist(msgpack)) = 1.1.2
|
Provides: bundled(python3dist(msgpack)) = 1.1.1
|
||||||
Provides: bundled(python3dist(packaging)) = 26.2
|
Provides: bundled(python3dist(packaging)) = 25
|
||||||
Provides: bundled(python3dist(platformdirs)) = 4.10
|
Provides: bundled(python3dist(platformdirs)) = 4.3.8
|
||||||
Provides: bundled(python3dist(pygments)) = 2.20
|
Provides: bundled(python3dist(pygments)) = 2.19.2
|
||||||
Provides: bundled(python3dist(pyproject-hooks)) = 1.2
|
Provides: bundled(python3dist(pyproject-hooks)) = 1.2
|
||||||
Provides: bundled(python3dist(requests)) = 2.34.2
|
Provides: bundled(python3dist(requests)) = 2.32.4
|
||||||
Provides: bundled(python3dist(resolvelib)) = 1.2.1
|
Provides: bundled(python3dist(resolvelib)) = 1.2
|
||||||
Provides: bundled(python3dist(rich)) = 14.2
|
Provides: bundled(python3dist(rich)) = 14.1
|
||||||
Provides: bundled(python3dist(setuptools)) = 70.3
|
Provides: bundled(python3dist(setuptools)) = 70.3
|
||||||
Provides: bundled(python3dist(tomli)) = 2.4.1
|
Provides: bundled(python3dist(tomli)) = 2.2.1
|
||||||
Provides: bundled(python3dist(tomli-w)) = 1.2
|
Provides: bundled(python3dist(tomli-w)) = 1.2
|
||||||
Provides: bundled(python3dist(truststore)) = 0.10.4
|
Provides: bundled(python3dist(truststore)) = 0.10.1
|
||||||
Provides: bundled(python3dist(urllib3)) = 2.7
|
Provides: bundled(python3dist(urllib3)) = 1.26.20
|
||||||
}
|
}
|
||||||
# setuptools
|
# setuptools
|
||||||
# vendor.txt not in .whl
|
# vendor.txt not in .whl
|
||||||
|
|
@ -254,7 +254,7 @@ Obsoletes: python%{pybasever}%{?1:-%{1}}\
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: bluez-libs-devel
|
BuildRequires: bluez-libs-devel
|
||||||
BuildRequires: bzip2-devel
|
BuildRequires: bzip2-devel
|
||||||
BuildRequires: expat-devel >= 2.5.0-2
|
BuildRequires: expat-devel
|
||||||
BuildRequires: findutils
|
BuildRequires: findutils
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
BuildRequires: gdbm-devel
|
BuildRequires: gdbm-devel
|
||||||
|
|
@ -267,6 +267,7 @@ BuildRequires: libuuid-devel
|
||||||
BuildRequires: make
|
BuildRequires: make
|
||||||
BuildRequires: mpdecimal-devel
|
BuildRequires: mpdecimal-devel
|
||||||
BuildRequires: ncurses-devel
|
BuildRequires: ncurses-devel
|
||||||
|
BuildRequires: openssl-devel
|
||||||
BuildRequires: pkgconfig
|
BuildRequires: pkgconfig
|
||||||
BuildRequires: python-rpm-macros
|
BuildRequires: python-rpm-macros
|
||||||
BuildRequires: readline-devel
|
BuildRequires: readline-devel
|
||||||
|
|
@ -279,10 +280,6 @@ BuildRequires: xz-devel
|
||||||
BuildRequires: zlib-devel
|
BuildRequires: zlib-devel
|
||||||
BuildRequires: /usr/bin/dtrace
|
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}
|
%if %{undefined rhel}
|
||||||
BuildRequires: libb2-devel
|
BuildRequires: libb2-devel
|
||||||
%endif
|
%endif
|
||||||
|
|
@ -370,45 +367,35 @@ Source11: idle3.appdata.xml
|
||||||
# pypa/distutils integration: https://github.com/pypa/distutils/pull/70
|
# pypa/distutils integration: https://github.com/pypa/distutils/pull/70
|
||||||
Patch251: 00251-change-user-install-location.patch
|
Patch251: 00251-change-user-install-location.patch
|
||||||
|
|
||||||
# 00466 # 713a1368544eddd55088d67f88a23ce31722a4cb
|
# 00461 # 920175020b21c0aff5edcc4c28d688b5061f591c
|
||||||
# Downstream only: Lower XML_COMBINED_VERSION threshold for reparse deferral
|
# Downstream only: Install wheel in test venvs when setuptools < 71
|
||||||
#
|
Patch461: 00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch
|
||||||
# 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.
|
|
||||||
Patch466: 00466-downstream-only-lower-xml_combined_version-threshold-for-reparse-deferral.patch
|
|
||||||
|
|
||||||
# 00475 # d44fac01037662db286449a78c8fb819788f764c
|
# 00464 # 292acffec7a379cb6d1f3c47b9e5a2f170bbadb6
|
||||||
# CVE-2025-15367
|
# Enable PAC and BTI protections for aarch64
|
||||||
#
|
#
|
||||||
# Reject control characters in POP3 commands
|
# Apply protection against ROP/JOP attacks for aarch64 on asm_trampoline.S
|
||||||
Patch475: 00475-cve-2025-15367.patch
|
#
|
||||||
|
# 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.
|
||||||
|
Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch
|
||||||
|
|
||||||
# 00477 # 9c62c492e7f2e3b152dbf287c08d307c3f013221
|
# 00466 # e10760fb955ee33d2917f8a57bb4e24d71e5341c
|
||||||
# Raise an error when importing stdlib modules compiled for a different Python version
|
# Downstream only: Skip tests not working with older expat version
|
||||||
#
|
#
|
||||||
# This is a downstream workaround "implementing" python#137212 -
|
# We want to run these tests in Fedora and EPEL 10, but not in EPEL 9,
|
||||||
# the mechanism for the check exists in Python 3.15+, where it needs to be
|
# which has too old version of expat. We set the upper bound version
|
||||||
# added to the standard library modules.
|
# in the conditionalized skip to a release available in CentOS Stream 10,
|
||||||
# In Fedora, we need it also in previous Python versions, as we experience
|
# which is tested as working.
|
||||||
# segmentation fault when importing stdlib modules after update while
|
Patch466: 00466-downstream-only-skip-tests-not-working-with-older-expat-version.patch
|
||||||
# Python is running.
|
|
||||||
#
|
|
||||||
# _curses, _tkinter, _tracemalloc and readline are not calling PyModuleDef_Init,
|
|
||||||
# which is modified with this patch, hence they need a
|
|
||||||
# direct call to the check function.
|
|
||||||
Patch477: 00477-raise-an-error-when-importing-stdlib-modules-compiled-for-a-different-python-version.patch
|
|
||||||
|
|
||||||
# (New patches go here ^^^)
|
# (New patches go here ^^^)
|
||||||
#
|
#
|
||||||
|
|
@ -534,7 +521,7 @@ Summary: Python runtime libraries
|
||||||
# Combined manually from https://docs.python.org/3.13/license.html
|
# Combined manually from https://docs.python.org/3.13/license.html
|
||||||
# Hash of Doc/license.rst which is compared in %%prep, generated with:
|
# Hash of Doc/license.rst which is compared in %%prep, generated with:
|
||||||
# $ sha256sum Doc/license.rst | cut -f1 -d" "
|
# $ sha256sum Doc/license.rst | cut -f1 -d" "
|
||||||
%global license_file_hash 952ac05720d7f1dcb63589b35eb0931b1442eb250230a4ad31198eddf0ad6abc
|
%global license_file_hash 62f2c9c2c75d511170eb464ad5f83b78cc1f37eb2eb49c2846c9aa6c4557ee99
|
||||||
# Licenses of incorporated software:
|
# Licenses of incorporated software:
|
||||||
# Mersenne Twister in _random C extension contains code under BSD-3-Clause
|
# Mersenne Twister in _random C extension contains code under BSD-3-Clause
|
||||||
# socket.getaddrinfo() and socket.getnameinfo() are BSD-3-Clause
|
# socket.getaddrinfo() and socket.getnameinfo() are BSD-3-Clause
|
||||||
|
|
@ -557,11 +544,10 @@ Summary: Python runtime libraries
|
||||||
# mimalloc is MIT
|
# mimalloc is MIT
|
||||||
# parts of asyncio from uvloop are MIT
|
# parts of asyncio from uvloop are MIT
|
||||||
# Python/qsbr.c is adapted from code under BSD-2-Clause
|
# 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:
|
# Bundled libb2 is not declared in the upstream document, but it's:
|
||||||
# CC0-1.0, covered by grandfathering exception
|
# CC0-1.0, covered by grandfathering exception
|
||||||
# We don't query upstream for changes, as 3.13 is the last Python version containing it.
|
# 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}
|
%if %{with rpmwheels}
|
||||||
Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2
|
Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2
|
||||||
License: %{libs_license}
|
License: %{libs_license}
|
||||||
|
|
@ -597,28 +583,6 @@ Recommends: (%{pkgname}-tkinter%{?_isa} = %{version}-%{release} if tk%{?_isa})
|
||||||
# The zoneinfo module needs tzdata
|
# The zoneinfo module needs tzdata
|
||||||
Requires: tzdata
|
Requires: tzdata
|
||||||
|
|
||||||
# The requirement on libexpat is generated, but we need to version it.
|
|
||||||
# When built with a specific expat version, but installed with an older one,
|
|
||||||
# we sometimes get:
|
|
||||||
# ImportError: /usr/lib64/python3.X/lib-dynload/pyexpat.cpython-....so:
|
|
||||||
# undefined symbol: XML_...
|
|
||||||
# The pyexpat module has build-time checks for expat version to only use the
|
|
||||||
# available symbols. However, there is no runtime protection, so when the module
|
|
||||||
# is later installed with an older expat, it may error due to undefined symbols.
|
|
||||||
# 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/')
|
|
||||||
%if v"%{expat_version}" < v"2.7.4"
|
|
||||||
Requires: expat%{?_isa} >= %{expat_version}
|
|
||||||
%endif
|
|
||||||
|
|
||||||
|
|
||||||
%description -n %{pkgname}-libs
|
%description -n %{pkgname}-libs
|
||||||
This package contains runtime libraries for use by Python:
|
This package contains runtime libraries for use by Python:
|
||||||
- the majority of the Python standard library
|
- the majority of the Python standard library
|
||||||
|
|
@ -795,9 +759,6 @@ License: %{libs_license} AND Apache-2.0 AND ISC AND LGPL-2.1-only AND MPL-2.0 AN
|
||||||
Provides: bundled(libb2) = 0.98.1
|
Provides: bundled(libb2) = 0.98.1
|
||||||
Provides: bundled(mimalloc) = 2.12
|
Provides: bundled(mimalloc) = 2.12
|
||||||
Requires: tzdata
|
Requires: tzdata
|
||||||
%if v"%{expat_version}" < v"2.7.4"
|
|
||||||
Requires: expat%{?_isa} >= %{expat_version}
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%description -n python%{pybasever}-freethreading
|
%description -n python%{pybasever}-freethreading
|
||||||
The provisional Free Threading (PEP 703) build of Python.
|
The provisional Free Threading (PEP 703) build of Python.
|
||||||
|
|
@ -1301,11 +1262,6 @@ for file in %{buildroot}%{pylibdir}/pydoc_data/topics.py $(grep --include='*.py'
|
||||||
rm ${directory}/{__pycache__/${module}.cpython-%{pyshortver}.opt-?.pyc,${module}.py}
|
rm ${directory}/{__pycache__/${module}.cpython-%{pyshortver}.opt-?.pyc,${module}.py}
|
||||||
done
|
done
|
||||||
|
|
||||||
%if %{without rpmwheels}
|
|
||||||
# Inject SBOM into the installed wheels (if the macro is available)
|
|
||||||
%{?python_wheel_inject_sbom:%python_wheel_inject_sbom %{buildroot}%{pylibdir}/ensurepip/_bundled/*.whl}
|
|
||||||
%endif
|
|
||||||
|
|
||||||
# ======================================================
|
# ======================================================
|
||||||
# Checks for packaging issues
|
# Checks for packaging issues
|
||||||
# ======================================================
|
# ======================================================
|
||||||
|
|
@ -1818,39 +1774,6 @@ CheckPython freethreading
|
||||||
# ======================================================
|
# ======================================================
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Wed Aug 12 2026 Miro Hrončok <mhroncok@redhat.com> - 3.13.15-2
|
|
||||||
- On EPEL 9, also supports reparse deferral in expat
|
|
||||||
|
|
||||||
* Mon Aug 10 2026 Karolina Surma <ksurma@redhat.com> - 3.13.15-1
|
|
||||||
- Update to Python 3.13.15
|
|
||||||
|
|
||||||
* Thu Jul 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 3.13.14-2
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild
|
|
||||||
|
|
||||||
* Thu Jun 11 2026 Karolina Surma <ksurma@redhat.com> - 3.13.14-1
|
|
||||||
- Update to Python 3.13.14
|
|
||||||
|
|
||||||
* Wed Apr 08 2026 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.13.13-1
|
|
||||||
- Update to 3.13.13
|
|
||||||
|
|
||||||
* Thu Mar 26 2026 Lumír Balhar <lbalhar@redhat.com> - 3.13.12-2
|
|
||||||
- Security fix for CVE-2026-4519 (rhbz#2449729)
|
|
||||||
|
|
||||||
* Wed Feb 04 2026 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.13.12-1
|
|
||||||
- Update to 3.13.12
|
|
||||||
|
|
||||||
* Sat Jan 17 2026 Fedora Release Engineering <releng@fedoraproject.org> - 3.13.11-3
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
|
|
||||||
|
|
||||||
* Tue Jan 06 2026 Karolina Surma <ksurma@redhat.com> - 3.13.11-2
|
|
||||||
- Require at least the same expat version as used during the build time
|
|
||||||
|
|
||||||
* Fri Dec 05 2025 Miro Hrončok <mhroncok@redhat.com> - 3.13.11-1
|
|
||||||
- Update to 3.13.11
|
|
||||||
|
|
||||||
* Wed Dec 03 2025 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.13.10-1
|
|
||||||
- Update to 3.13.10
|
|
||||||
|
|
||||||
* Tue Oct 14 2025 Miro Hrončok <mhroncok@redhat.com> - 3.13.9-1
|
* Tue Oct 14 2025 Miro Hrončok <mhroncok@redhat.com> - 3.13.9-1
|
||||||
- Update to Python 3.13.9
|
- Update to Python 3.13.9
|
||||||
|
|
||||||
|
|
|
||||||
4
sources
4
sources
|
|
@ -1,2 +1,2 @@
|
||||||
SHA512 (Python-3.13.15.tar.xz) = b0ab766a3de0b4cfdbf0b93300d7330c734d3f7057577bb03e95e39da4cdade81993e769c7fa6dfdcc13b9d43a3b399d9cd89b5477b413662e9e691c1b7886b8
|
SHA512 (Python-3.13.9.tar.xz) = ffc9b6e545bf5cf8f3b945f85442eb4bd28cca9adb92d8c253f44078ec2e9758f802bf72c48e0d7e503c02b2dc754c58ee913cd3b7d8e8808fac2a0aa4e006a8
|
||||||
SHA512 (Python-3.13.15.tar.xz.asc) = 662c00be95f62e80db43cf42099fef91f764ff7a4433cadf7eb19dedb5e4775adb12878d5ed2295fcea187731de186163ad9672ab72cde62a2335ca58ec1ad86
|
SHA512 (Python-3.13.9.tar.xz.asc) = c33fba3a6b22dccc08beb7f13bd61a25a30f609a54da7c8dfd3b3b4a3490a7b24c11f9617a835388f22709fb09375d35febc417cf104a18f5bec3b43ec999e82
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue