Skip to content

[AutoPR- Security] Patch python3 for CVE-2025-8194 [HIGH] #14443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: fasttrack/3.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions SPECS/python3/CVE-2025-8194.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
From f6e8423fca302558e250b6538d092678b2a27003 Mon Sep 17 00:00:00 2001
From: Alexander Urieles <[email protected]>
Date: Mon, 28 Jul 2025 17:37:26 +0200
Subject: [PATCH] gh-130577: tarfile now validates archives to ensure member
offsets are non-negative (GH-137027) (cherry picked from commit
7040aa54f14676938970e10c5f74ea93cd56aa38)

Co-authored-by: Alexander Urieles <[email protected]>
Co-authored-by: Gregory P. Smith <[email protected]>
Signed-off-by: Azure Linux Security Servicing Account <[email protected]>
Upstream-reference: https://github.com/python/cpython/pull/137171.patch
---
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 9999a99..59d3f6e 100755
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -1615,6 +1615,9 @@ class TarInfo(object):
"""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 1c598e1..a6925bf 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -50,6 +50,7 @@ bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2")
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"
@@ -4485,6 +4486,161 @@ class OverwriteTests(archiver_tests.OverwriteTests, unittest.TestCase):
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 0000000..342cabb
--- /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`.)
--
2.45.4

6 changes: 5 additions & 1 deletion SPECS/python3/python3.spec
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Summary: A high-level scripting language
Name: python3
Version: 3.12.9
Release: 3%{?dist}
Release: 4%{?dist}
License: PSF
Vendor: Microsoft Corporation
Distribution: Azure Linux
Expand All @@ -20,6 +20,7 @@ Patch0: cgi3.patch
Patch1: CVE-2025-4516.patch
Patch2: CVE-2025-4517.patch
Patch3: CVE-2025-6069.patch
Patch4: CVE-2025-8194.patch

BuildRequires: bzip2-devel
BuildRequires: expat-devel >= 2.1.0
Expand Down Expand Up @@ -242,6 +243,9 @@ rm -rf %{buildroot}%{_bindir}/__pycache__
%{_libdir}/python%{majmin}/test/*

%changelog
* Wed Aug 06 2025 Azure Linux Security Servicing Account <[email protected]> - 3.12.9-4
- Patch for CVE-2025-8194

* Tue Jul 01 2025 Jyoti Kanase <[email protected]> - 3.12.9-3
- Patch CVE-2025-6069
- Fixed the test in %check
Expand Down
6 changes: 3 additions & 3 deletions toolkit/resources/manifests/package/pkggen_core_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ ca-certificates-base-3.0.0-8.azl3.noarch.rpm
ca-certificates-3.0.0-8.azl3.noarch.rpm
dwz-0.14-2.azl3.aarch64.rpm
unzip-6.0-22.azl3.aarch64.rpm
python3-3.12.9-3.azl3.aarch64.rpm
python3-devel-3.12.9-3.azl3.aarch64.rpm
python3-libs-3.12.9-3.azl3.aarch64.rpm
python3-3.12.9-4.azl3.aarch64.rpm
python3-devel-3.12.9-4.azl3.aarch64.rpm
python3-libs-3.12.9-4.azl3.aarch64.rpm
python3-setuptools-69.0.3-5.azl3.noarch.rpm
python3-pygments-2.7.4-2.azl3.noarch.rpm
which-2.21-8.azl3.aarch64.rpm
Expand Down
6 changes: 3 additions & 3 deletions toolkit/resources/manifests/package/pkggen_core_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ ca-certificates-base-3.0.0-8.azl3.noarch.rpm
ca-certificates-3.0.0-8.azl3.noarch.rpm
dwz-0.14-2.azl3.x86_64.rpm
unzip-6.0-22.azl3.x86_64.rpm
python3-3.12.9-3.azl3.x86_64.rpm
python3-devel-3.12.9-3.azl3.x86_64.rpm
python3-libs-3.12.9-3.azl3.x86_64.rpm
python3-3.12.9-4.azl3.x86_64.rpm
python3-devel-3.12.9-4.azl3.x86_64.rpm
python3-libs-3.12.9-4.azl3.x86_64.rpm
python3-setuptools-69.0.3-5.azl3.noarch.rpm
python3-pygments-2.7.4-2.azl3.noarch.rpm
which-2.21-8.azl3.x86_64.rpm
Expand Down
14 changes: 7 additions & 7 deletions toolkit/resources/manifests/package/toolchain_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -531,18 +531,18 @@ pyproject-rpm-macros-1.12.0-2.azl3.noarch.rpm
pyproject-srpm-macros-1.12.0-2.azl3.noarch.rpm
python-markupsafe-debuginfo-2.1.3-1.azl3.aarch64.rpm
python-wheel-wheel-0.43.0-1.azl3.noarch.rpm
python3-3.12.9-3.azl3.aarch64.rpm
python3-3.12.9-4.azl3.aarch64.rpm
python3-audit-3.1.2-1.azl3.aarch64.rpm
python3-cracklib-2.9.11-1.azl3.aarch64.rpm
python3-curses-3.12.9-3.azl3.aarch64.rpm
python3-curses-3.12.9-4.azl3.aarch64.rpm
python3-Cython-3.0.5-2.azl3.aarch64.rpm
python3-debuginfo-3.12.9-3.azl3.aarch64.rpm
python3-devel-3.12.9-3.azl3.aarch64.rpm
python3-debuginfo-3.12.9-4.azl3.aarch64.rpm
python3-devel-3.12.9-4.azl3.aarch64.rpm
python3-flit-core-3.9.0-1.azl3.noarch.rpm
python3-gpg-1.23.2-2.azl3.aarch64.rpm
python3-jinja2-3.1.2-3.azl3.noarch.rpm
python3-libcap-ng-0.8.4-1.azl3.aarch64.rpm
python3-libs-3.12.9-3.azl3.aarch64.rpm
python3-libs-3.12.9-4.azl3.aarch64.rpm
python3-libxml2-2.11.5-6.azl3.aarch64.rpm
python3-lxml-4.9.3-1.azl3.aarch64.rpm
python3-magic-5.45-1.azl3.noarch.rpm
Expand All @@ -554,8 +554,8 @@ python3-pygments-2.7.4-2.azl3.noarch.rpm
python3-rpm-4.18.2-1.azl3.aarch64.rpm
python3-rpm-generators-14-11.azl3.noarch.rpm
python3-setuptools-69.0.3-5.azl3.noarch.rpm
python3-test-3.12.9-3.azl3.aarch64.rpm
python3-tools-3.12.9-3.azl3.aarch64.rpm
python3-test-3.12.9-4.azl3.aarch64.rpm
python3-tools-3.12.9-4.azl3.aarch64.rpm
python3-wheel-0.43.0-1.azl3.noarch.rpm
readline-8.2-2.azl3.aarch64.rpm
readline-debuginfo-8.2-2.azl3.aarch64.rpm
Expand Down
14 changes: 7 additions & 7 deletions toolkit/resources/manifests/package/toolchain_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -539,18 +539,18 @@ pyproject-rpm-macros-1.12.0-2.azl3.noarch.rpm
pyproject-srpm-macros-1.12.0-2.azl3.noarch.rpm
python-markupsafe-debuginfo-2.1.3-1.azl3.x86_64.rpm
python-wheel-wheel-0.43.0-1.azl3.noarch.rpm
python3-3.12.9-3.azl3.x86_64.rpm
python3-3.12.9-4.azl3.x86_64.rpm
python3-audit-3.1.2-1.azl3.x86_64.rpm
python3-cracklib-2.9.11-1.azl3.x86_64.rpm
python3-curses-3.12.9-3.azl3.x86_64.rpm
python3-curses-3.12.9-4.azl3.x86_64.rpm
python3-Cython-3.0.5-2.azl3.x86_64.rpm
python3-debuginfo-3.12.9-3.azl3.x86_64.rpm
python3-devel-3.12.9-3.azl3.x86_64.rpm
python3-debuginfo-3.12.9-4.azl3.x86_64.rpm
python3-devel-3.12.9-4.azl3.x86_64.rpm
python3-flit-core-3.9.0-1.azl3.noarch.rpm
python3-gpg-1.23.2-2.azl3.x86_64.rpm
python3-jinja2-3.1.2-3.azl3.noarch.rpm
python3-libcap-ng-0.8.4-1.azl3.x86_64.rpm
python3-libs-3.12.9-3.azl3.x86_64.rpm
python3-libs-3.12.9-4.azl3.x86_64.rpm
python3-libxml2-2.11.5-6.azl3.x86_64.rpm
python3-lxml-4.9.3-1.azl3.x86_64.rpm
python3-magic-5.45-1.azl3.noarch.rpm
Expand All @@ -562,8 +562,8 @@ python3-pygments-2.7.4-2.azl3.noarch.rpm
python3-rpm-4.18.2-1.azl3.x86_64.rpm
python3-rpm-generators-14-11.azl3.noarch.rpm
python3-setuptools-69.0.3-5.azl3.noarch.rpm
python3-test-3.12.9-3.azl3.x86_64.rpm
python3-tools-3.12.9-3.azl3.x86_64.rpm
python3-test-3.12.9-4.azl3.x86_64.rpm
python3-tools-3.12.9-4.azl3.x86_64.rpm
python3-wheel-0.43.0-1.azl3.noarch.rpm
readline-8.2-2.azl3.x86_64.rpm
readline-debuginfo-8.2-2.azl3.x86_64.rpm
Expand Down
Loading