From 77fd32649b5c8c80ef1e237791fc3c7171613b2f Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Fri, 10 Oct 2025 13:21:13 +0200 Subject: [PATCH] Update to Python 3.12.12 --- ...l-control-flow-technology-for-x86-64.patch | 51 ----- 00467-CVE-2025-8194.patch | 215 ------------------ python3.12.spec | 60 ++--- sources | 4 +- 4 files changed, 27 insertions(+), 303 deletions(-) delete mode 100644 00459-apply-intel-control-flow-technology-for-x86-64.patch delete mode 100644 00467-CVE-2025-8194.patch diff --git a/00459-apply-intel-control-flow-technology-for-x86-64.patch b/00459-apply-intel-control-flow-technology-for-x86-64.patch deleted file mode 100644 index 380856c..0000000 --- a/00459-apply-intel-control-flow-technology-for-x86-64.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Charalampos Stratakis -Date: Wed, 8 Jan 2025 04:58:22 +0100 -Subject: 00459: Apply Intel Control-flow Technology for x86-64 - -Required for mitigation against return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks - -Proposed upstream: https://github.com/python/cpython/pull/128606 - -See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html ---- - Python/asm_trampoline.S | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S -index 460707717d..341d0bbe51 100644 ---- a/Python/asm_trampoline.S -+++ b/Python/asm_trampoline.S -@@ -9,6 +9,9 @@ - # } - _Py_trampoline_func_start: - #ifdef __x86_64__ -+#if defined(__CET__) && (__CET__ & 1) -+ endbr64 -+#endif - sub $8, %rsp - call *%rcx - add $8, %rsp -@@ -26,3 +29,22 @@ _Py_trampoline_func_start: - .globl _Py_trampoline_func_end - _Py_trampoline_func_end: - .section .note.GNU-stack,"",@progbits -+# Note for indicating the assembly code supports CET -+#if defined(__x86_64__) && defined(__CET__) && (__CET__ & 1) -+ .section .note.gnu.property,"a" -+ .align 8 -+ .long 1f - 0f -+ .long 4f - 1f -+ .long 5 -+0: -+ .string "GNU" -+1: -+ .align 8 -+ .long 0xc0000002 -+ .long 3f - 2f -+2: -+ .long 0x3 -+3: -+ .align 8 -+4: -+#endif // __x86_64__ diff --git a/00467-CVE-2025-8194.patch b/00467-CVE-2025-8194.patch deleted file mode 100644 index 8ac53fe..0000000 --- a/00467-CVE-2025-8194.patch +++ /dev/null @@ -1,215 +0,0 @@ -From c9d9f78feb1467e73fd29356c040bde1c104f29f Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Mon, 4 Aug 2025 13:45:06 +0200 -Subject: [PATCH] [3.12] gh-130577: tarfile now validates archives to ensure - member offsets are non-negative (GH-137027) (#137171) - -(cherry picked from commit 7040aa54f14676938970e10c5f74ea93cd56aa38) - -Co-authored-by: Alexander Urieles -Co-authored-by: Gregory P. Smith ---- - Lib/tarfile.py | 3 + - Lib/test/test_tarfile.py | 156 ++++++++++++++++++ - ...-07-23-00-35-29.gh-issue-130577.c7EITy.rst | 3 + - 3 files changed, 162 insertions(+) - create mode 100644 Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst - -diff --git a/Lib/tarfile.py b/Lib/tarfile.py -index 9999a99d54d8b9..59d3f6e5cce165 100755 ---- a/Lib/tarfile.py -+++ b/Lib/tarfile.py -@@ -1615,6 +1615,9 @@ def _block(self, count): - """Round up a byte count by BLOCKSIZE and return it, - e.g. _block(834) => 1024. - """ -+ # Only non-negative offsets are allowed -+ if count < 0: -+ raise InvalidHeaderError("invalid offset") - blocks, remainder = divmod(count, BLOCKSIZE) - if remainder: - blocks += 1 -diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py -index a184ba75a8851b..759fa03ead70b0 100644 ---- a/Lib/test/test_tarfile.py -+++ b/Lib/test/test_tarfile.py -@@ -50,6 +50,7 @@ def sha256sum(data): - xzname = os.path.join(TEMPDIR, "testtar.tar.xz") - tmpname = os.path.join(TEMPDIR, "tmp.tar") - dotlessname = os.path.join(TEMPDIR, "testtar") -+SPACE = b" " - - sha256_regtype = ( - "e09e4bc8b3c9d9177e77256353b36c159f5f040531bbd4b024a8f9b9196c71ce" -@@ -4488,6 +4489,161 @@ def extractall(self, ar): - ar.extractall(self.testdir, filter='fully_trusted') - - -+class OffsetValidationTests(unittest.TestCase): -+ tarname = tmpname -+ invalid_posix_header = ( -+ # name: 100 bytes -+ tarfile.NUL * tarfile.LENGTH_NAME -+ # mode, space, null terminator: 8 bytes -+ + b"000755" + SPACE + tarfile.NUL -+ # uid, space, null terminator: 8 bytes -+ + b"000001" + SPACE + tarfile.NUL -+ # gid, space, null terminator: 8 bytes -+ + b"000001" + SPACE + tarfile.NUL -+ # size, space: 12 bytes -+ + b"\xff" * 11 + SPACE -+ # mtime, space: 12 bytes -+ + tarfile.NUL * 11 + SPACE -+ # chksum: 8 bytes -+ + b"0011407" + tarfile.NUL -+ # type: 1 byte -+ + tarfile.REGTYPE -+ # linkname: 100 bytes -+ + tarfile.NUL * tarfile.LENGTH_LINK -+ # magic: 6 bytes, version: 2 bytes -+ + tarfile.POSIX_MAGIC -+ # uname: 32 bytes -+ + tarfile.NUL * 32 -+ # gname: 32 bytes -+ + tarfile.NUL * 32 -+ # devmajor, space, null terminator: 8 bytes -+ + tarfile.NUL * 6 + SPACE + tarfile.NUL -+ # devminor, space, null terminator: 8 bytes -+ + tarfile.NUL * 6 + SPACE + tarfile.NUL -+ # prefix: 155 bytes -+ + tarfile.NUL * tarfile.LENGTH_PREFIX -+ # padding: 12 bytes -+ + tarfile.NUL * 12 -+ ) -+ invalid_gnu_header = ( -+ # name: 100 bytes -+ tarfile.NUL * tarfile.LENGTH_NAME -+ # mode, null terminator: 8 bytes -+ + b"0000755" + tarfile.NUL -+ # uid, null terminator: 8 bytes -+ + b"0000001" + tarfile.NUL -+ # gid, space, null terminator: 8 bytes -+ + b"0000001" + tarfile.NUL -+ # size, space: 12 bytes -+ + b"\xff" * 11 + SPACE -+ # mtime, space: 12 bytes -+ + tarfile.NUL * 11 + SPACE -+ # chksum: 8 bytes -+ + b"0011327" + tarfile.NUL -+ # type: 1 byte -+ + tarfile.REGTYPE -+ # linkname: 100 bytes -+ + tarfile.NUL * tarfile.LENGTH_LINK -+ # magic: 8 bytes -+ + tarfile.GNU_MAGIC -+ # uname: 32 bytes -+ + tarfile.NUL * 32 -+ # gname: 32 bytes -+ + tarfile.NUL * 32 -+ # devmajor, null terminator: 8 bytes -+ + tarfile.NUL * 8 -+ # devminor, null terminator: 8 bytes -+ + tarfile.NUL * 8 -+ # padding: 167 bytes -+ + tarfile.NUL * 167 -+ ) -+ invalid_v7_header = ( -+ # name: 100 bytes -+ tarfile.NUL * tarfile.LENGTH_NAME -+ # mode, space, null terminator: 8 bytes -+ + b"000755" + SPACE + tarfile.NUL -+ # uid, space, null terminator: 8 bytes -+ + b"000001" + SPACE + tarfile.NUL -+ # gid, space, null terminator: 8 bytes -+ + b"000001" + SPACE + tarfile.NUL -+ # size, space: 12 bytes -+ + b"\xff" * 11 + SPACE -+ # mtime, space: 12 bytes -+ + tarfile.NUL * 11 + SPACE -+ # chksum: 8 bytes -+ + b"0010070" + tarfile.NUL -+ # type: 1 byte -+ + tarfile.REGTYPE -+ # linkname: 100 bytes -+ + tarfile.NUL * tarfile.LENGTH_LINK -+ # padding: 255 bytes -+ + tarfile.NUL * 255 -+ ) -+ valid_gnu_header = tarfile.TarInfo("filename").tobuf(tarfile.GNU_FORMAT) -+ data_block = b"\xff" * tarfile.BLOCKSIZE -+ -+ def _write_buffer(self, buffer): -+ with open(self.tarname, "wb") as f: -+ f.write(buffer) -+ -+ def _get_members(self, ignore_zeros=None): -+ with open(self.tarname, "rb") as f: -+ with tarfile.open( -+ mode="r", fileobj=f, ignore_zeros=ignore_zeros -+ ) as tar: -+ return tar.getmembers() -+ -+ def _assert_raises_read_error_exception(self): -+ with self.assertRaisesRegex( -+ tarfile.ReadError, "file could not be opened successfully" -+ ): -+ self._get_members() -+ -+ def test_invalid_offset_header_validations(self): -+ for tar_format, invalid_header in ( -+ ("posix", self.invalid_posix_header), -+ ("gnu", self.invalid_gnu_header), -+ ("v7", self.invalid_v7_header), -+ ): -+ with self.subTest(format=tar_format): -+ self._write_buffer(invalid_header) -+ self._assert_raises_read_error_exception() -+ -+ def test_early_stop_at_invalid_offset_header(self): -+ buffer = self.valid_gnu_header + self.invalid_gnu_header + self.valid_gnu_header -+ self._write_buffer(buffer) -+ members = self._get_members() -+ self.assertEqual(len(members), 1) -+ self.assertEqual(members[0].name, "filename") -+ self.assertEqual(members[0].offset, 0) -+ -+ def test_ignore_invalid_archive(self): -+ # 3 invalid headers with their respective data -+ buffer = (self.invalid_gnu_header + self.data_block) * 3 -+ self._write_buffer(buffer) -+ members = self._get_members(ignore_zeros=True) -+ self.assertEqual(len(members), 0) -+ -+ def test_ignore_invalid_offset_headers(self): -+ for first_block, second_block, expected_offset in ( -+ ( -+ (self.valid_gnu_header), -+ (self.invalid_gnu_header + self.data_block), -+ 0, -+ ), -+ ( -+ (self.invalid_gnu_header + self.data_block), -+ (self.valid_gnu_header), -+ 1024, -+ ), -+ ): -+ self._write_buffer(first_block + second_block) -+ members = self._get_members(ignore_zeros=True) -+ self.assertEqual(len(members), 1) -+ self.assertEqual(members[0].name, "filename") -+ self.assertEqual(members[0].offset, expected_offset) -+ -+ - def setUpModule(): - os_helper.unlink(TEMPDIR) - os.makedirs(TEMPDIR) -diff --git a/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst b/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst -new file mode 100644 -index 00000000000000..342cabbc865dc4 ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst -@@ -0,0 +1,3 @@ -+:mod:`tarfile` now validates archives to ensure member offsets are -+non-negative. (Contributed by Alexander Enrique Urieles Nieto in -+:gh:`130577`.) diff --git a/python3.12.spec b/python3.12.spec index be3e85d..17d43a4 100644 --- a/python3.12.spec +++ b/python3.12.spec @@ -13,11 +13,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}.11 +%global general_version %{pybasever}.12 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -72,7 +72,7 @@ License: Python-2.0.1 # from Python with the versions below. # This needs to be manually updated when we update Python. %global pip_version 25.0.1 -%global setuptools_version 67.6.1 +%global setuptools_version 79.0.1 %global wheel_version 0.40.0 # All of those also include a list of indirect bundled libs: # pip @@ -98,22 +98,25 @@ Provides: bundled(python3dist(typing-extensions)) = 4.12.2 Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools -# vendor.txt files not in .whl -# $ %%{_rpmconfigdir}/pythonbundles.py \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/setuptools/_vendor/vendored.txt) \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/pkg_resources/_vendor/vendored.txt) +# vendor.txt not in .whl +# %%{_rpmconfigdir}/pythonbundles.py <(unzip -l Lib/test/wheeldata/setuptools-*.whl | grep -E '_vendor/.+dist-info/RECORD' | sed -E 's@^.*/([^-]+)-([^-]+)\.dist-info/.*$@\1==\2@') %global setuptools_bundled_provides %{expand: -Provides: bundled(python3dist(importlib-metadata)) = 6 -Provides: bundled(python3dist(importlib-resources)) = 5.10.2 -Provides: bundled(python3dist(jaraco-text)) = 3.7 -Provides: bundled(python3dist(more-itertools)) = 8.8 -Provides: bundled(python3dist(ordered-set)) = 3.1.1 -Provides: bundled(python3dist(packaging)) = 23 -Provides: bundled(python3dist(platformdirs)) = 2.6.2 +Provides: bundled(python3dist(autocommand)) = 2.2.2 +Provides: bundled(python3dist(backports-tarfile)) = 1.2 +Provides: bundled(python3dist(importlib-metadata)) = 8 +Provides: bundled(python3dist(inflect)) = 7.3.1 +Provides: bundled(python3dist(jaraco-collections)) = 5.1 +Provides: bundled(python3dist(jaraco-context)) = 5.3 +Provides: bundled(python3dist(jaraco-functools)) = 4.0.1 +Provides: bundled(python3dist(jaraco-text)) = 3.12.1 +Provides: bundled(python3dist(more-itertools)) = 10.3 +Provides: bundled(python3dist(packaging)) = 24.2 +Provides: bundled(python3dist(platformdirs)) = 4.2.2 Provides: bundled(python3dist(tomli)) = 2.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.4 -Provides: bundled(python3dist(zipp)) = 3.7 +Provides: bundled(python3dist(typeguard)) = 4.3 +Provides: bundled(python3dist(typing-extensions)) = 4.12.2 +Provides: bundled(python3dist(wheel)) = 0.45.1 +Provides: bundled(python3dist(zipp)) = 3.19.2 } # wheel # $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheeldata/wheel-*.whl wheel/vendored/vendor.txt) @@ -401,16 +404,6 @@ Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-g # - https://access.redhat.com/articles/7004769 Patch397: 00397-tarfile-filter.patch -# 00459 # 906f6692bd85034012c9554f2434627ccfc04c67 -# Apply Intel Control-flow Technology for x86-64 -# -# Required for mitigation against return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks -# -# Proposed upstream: https://github.com/python/cpython/pull/128606 -# -# See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html -Patch459: 00459-apply-intel-control-flow-technology-for-x86-64.patch - # 00462 # 5324dc5f57e0068f7e4f7b2f20006e88ff5f4e47 # Fix PySSL_SetError handling SSL_ERROR_SYSCALL # @@ -441,14 +434,6 @@ Patch462: 00462-fix-pyssl_seterror-handling-ssl_error_syscall.patch # will not show the Python functions, irrespective of this patch. Patch464: 00464-enable-pac-and-bti-protections-for-aarch64.patch -# 00467 # -# CVE-2025-8194 -# -# tarfile now validates archives to ensure member offsets are non-negative. -# -# Upstream PR: https://github.com/python/cpython/pull/137171 -Patch467: 00467-CVE-2025-8194.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1813,6 +1798,11 @@ CheckPython optimized # ====================================================== %changelog +* Fri Oct 10 2025 Karolina Surma - 3.12.12-1 +- Update to 3.12.12 +- Security fix for CVE-2025-8291 +Resolves: RHEL-128361 + * Thu Aug 14 2025 Lumír Balhar - 3.12.11-3 - Security fix for CVE-2025-8194 Resolves: RHEL-106329 diff --git a/sources b/sources index 0587ac7..6b54e57 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.12.11.tar.xz) = 81f259c5bb293a5b685ebead1dff56c7c9d28eed12edb508b3e5e1a882991e762fc959803cf2734f4233bb1c5407b4f5303324c67b25d860b069d38bbebe4454 -SHA512 (Python-3.12.11.tar.xz.asc) = 3589deba17c5adcfcd614387a5207ad20db56cd9c7937eb44e21035a8745f1c6bb9a1b7cfe8bc5b58ecc7cca09ed49fd4c2878f65baecb2514e79c666f85a22e +SHA512 (Python-3.12.12.tar.xz) = 4b99d240dd96a6e154909dcffe87f8bb38193d634cd80a1c3d9e819b7a63af2afa46d5e6423e81f00dd388840dc29a4a71580f6aa1ce9a12e559c1d63f65a205 +SHA512 (Python-3.12.12.tar.xz.asc) = 32c10fd427c6f9f11595493d1b4d4c3cade85bffd439fe11e8b0b2c619e06734097b6aaedfdb4fe035b7fdd7196714dba77cdc806923e4454d5bcf60056991a0