diff --git a/SPECS/python3/CVE-2026-4360.patch b/SPECS/python3/CVE-2026-4360.patch new file mode 100644 index 00000000000..bae7b20fc54 --- /dev/null +++ b/SPECS/python3/CVE-2026-4360.patch @@ -0,0 +1,150 @@ +From 7c721a42009902c50b7707cb9f73aee88228f7f3 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Tue, 4 Aug 2026 11:28:03 +0200 +Subject: [PATCH] gh-151987: Pass filter_function to TarFile._extract_one() + during .extract() (GH-151988) (#152611) + +gh-151987: Pass filter_function to TarFile._extract_one() during .extract() (GH-151988) + +(cherry picked from commit 7ccdbaba2c54250a70d7f25632152df7655a5e0a) + +Co-authored-by: Petr Viktorin +Co-authored-by: Seth Michael Larson +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/python/cpython/commit/0367912be336348b30572f8029cec4a282782d92.patch +--- + Lib/tarfile.py | 3 +- + Lib/test/test_tarfile.py | 92 +++++++++++++++++++ + ...-06-23-14-19-30.gh-issue-151987.8mNIMf.rst | 2 + + 3 files changed, 96 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst + +diff --git a/Lib/tarfile.py b/Lib/tarfile.py +index 461ec16..d609c91 100755 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -2408,7 +2408,8 @@ class TarFile(object): + tarinfo, unfiltered = self._get_extract_tarinfo( + member, filter_function, path) + if tarinfo is not None: +- self._extract_one(tarinfo, path, set_attrs, numeric_owner) ++ self._extract_one(tarinfo, path, set_attrs, numeric_owner, ++ filter_function=filter_function) + + def _get_extract_tarinfo(self, member, filter_function, path): + """Get (filtered, unfiltered) TarInfos from *member* +diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py +index 717d1c1..ecb0404 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -4234,6 +4234,98 @@ class TestExtractionFilters(unittest.TestCase): + st_mode = cc.outerdir.stat().st_mode + self.assertNotEqual(st_mode & 0o777, 0o777) + ++ @symlink_test ++ @unittest.skipUnless(hasattr(os, 'chown'), "missing os.chown") ++ @unittest.skipUnless(hasattr(os, 'lchown'), "missing os.lchown") ++ @unittest.skipUnless(hasattr(os, 'geteuid'), "missing os.geteuid") ++ @support.subTests('link_type', (tarfile.SYMTYPE, tarfile.LNKTYPE)) ++ def test_chown_links_on_extract(self, link_type): ++ with ArchiveMaker() as arc: ++ arc.add("test.txt", ++ uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x') ++ arc.add("link", ++ type=link_type, ++ linkname='test.txt', ++ uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x') ++ ++ with ( ++ os_helper.temp_dir() as tmpdir, ++ arc.open() as tar, ++ unittest.mock.patch("os.chown") as mock_chown, ++ unittest.mock.patch("os.lchown") as mock_lchown, ++ unittest.mock.patch("os.geteuid") as mock_geteuid, ++ ): ++ # Set UID to 0 so chown() is attempted. ++ mock_geteuid.return_value = 0 ++ tar.extract("link", path=tmpdir, filter='data') ++ extract_path = os.path.join(tmpdir, "link") ++ ++ if link_type == tarfile.SYMTYPE: ++ mock_chown.assert_not_called() ++ mock_lchown.assert_called_once_with(extract_path, -1, -1) ++ else: ++ mock_chown.assert_has_calls([ ++ unittest.mock.call(extract_path, -1, -1), ++ unittest.mock.call(extract_path, -1, -1) ++ ]) ++ mock_lchown.assert_not_called() ++ ++ @symlink_test ++ @unittest.skipUnless(hasattr(os, 'chown'), "missing os.chown") ++ @unittest.skipUnless(hasattr(os, 'lchown'), "missing os.lchown") ++ @unittest.skipUnless(hasattr(os, 'geteuid'), "missing os.geteuid") ++ @support.subTests('link_type', (tarfile.SYMTYPE, tarfile.LNKTYPE)) ++ def test_chown_links_on_extractall(self, link_type): ++ with ArchiveMaker() as arc: ++ arc.add("test.txt", ++ uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x') ++ arc.add("link", ++ type=link_type, ++ linkname='test.txt', ++ uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x') ++ ++ with ( ++ os_helper.temp_dir() as tmpdir, ++ arc.open() as tar, ++ unittest.mock.patch("os.chown") as mock_chown, ++ unittest.mock.patch("os.lchown") as mock_lchown, ++ unittest.mock.patch("os.geteuid") as mock_geteuid, ++ ): ++ # Set UID to 0 so chown() is attempted. ++ mock_geteuid.return_value = 0 ++ tar.extractall(path=tmpdir, filter='data') ++ extract_link_path = os.path.join(tmpdir, "link") ++ extract_file_path = os.path.join(tmpdir, "test.txt") ++ ++ if link_type == tarfile.SYMTYPE: ++ mock_chown.assert_called_once_with(extract_file_path, -1, -1) ++ mock_lchown.assert_called_once_with(extract_link_path, -1, -1) ++ else: ++ mock_chown.assert_has_calls([ ++ unittest.mock.call(extract_file_path, -1, -1), ++ unittest.mock.call(extract_link_path, -1, -1) ++ ]) ++ mock_lchown.assert_not_called() ++ ++ def test_extract_filters_target(self): ++ # Test that when extract() falls back to extracting (rather than ++ # linking) a hardlink target, it filters the target. ++ with ArchiveMaker() as arc: ++ arc.add("target") ++ arc.add("link", hardlink_to="target") ++ def testing_filter(member, path): ++ if member.name == 'target': ++ # target: set read-only ++ return member.replace(mode=stat.S_IRUSR) ++ # link: don't overwrite the mode ++ return member.replace(mode=None) ++ tempdir = pathlib.Path(TEMPDIR) / 'extract' ++ with os_helper.temp_dir(tempdir), arc.open() as tar: ++ tar.extract("link", path=tempdir, filter=testing_filter) ++ path = tempdir / 'link' ++ if os_helper.can_chmod(): ++ self.assertFalse(path.stat().st_mode & stat.S_IWUSR) ++ + def test_link_fallback_normalizes(self): + # Make sure hardlink fallbacks work for non-normalized paths for all + # filters +diff --git a/Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst b/Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst +new file mode 100644 +index 0000000..9eea7b3 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst +@@ -0,0 +1,2 @@ ++The :meth:`tarfile.TarFile.extract` method now applies the given filter when ++it extracts a link target from the archive as a fallback. +-- +2.45.4 + diff --git a/SPECS/python3/python3.spec b/SPECS/python3/python3.spec index a6735e70ca8..ea8ebf9d6f4 100644 --- a/SPECS/python3/python3.spec +++ b/SPECS/python3/python3.spec @@ -6,7 +6,7 @@ Summary: A high-level scripting language Name: python3 Version: 3.12.9 -Release: 13%{?dist} +Release: 14%{?dist} License: PSF Vendor: Microsoft Corporation Distribution: Azure Linux @@ -35,6 +35,7 @@ Patch15: CVE-2026-1502.patch Patch16: CVE-2025-13462.patch Patch17: CVE-2026-8328.patch Patch18: CVE-2026-7774.patch +Patch19: CVE-2026-4360.patch BuildRequires: bzip2-devel BuildRequires: expat-devel >= 2.1.0 @@ -257,6 +258,9 @@ rm -rf %{buildroot}%{_bindir}/__pycache__ %{_libdir}/python%{majmin}/test/* %changelog +* Wed Aug 05 2026 Azure Linux Security Servicing Account - 3.12.9-14 +- Patch for CVE-2026-4360 + * Wed Jun 10 2026 Azure Linux Security Servicing Account - 3.12.9-13 - Patch for CVE-2026-7774 diff --git a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt index 5fda5c1c165..27a73fb5013 100644 --- a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt @@ -244,9 +244,9 @@ ca-certificates-base-3.0.0-15.azl3.noarch.rpm ca-certificates-3.0.0-15.azl3.noarch.rpm dwz-0.14-2.azl3.aarch64.rpm unzip-6.0-22.azl3.aarch64.rpm -python3-3.12.9-13.azl3.aarch64.rpm -python3-devel-3.12.9-13.azl3.aarch64.rpm -python3-libs-3.12.9-13.azl3.aarch64.rpm +python3-3.12.9-14.azl3.aarch64.rpm +python3-devel-3.12.9-14.azl3.aarch64.rpm +python3-libs-3.12.9-14.azl3.aarch64.rpm python3-setuptools-69.0.3-6.azl3.noarch.rpm python3-pygments-2.7.4-2.azl3.noarch.rpm which-2.21-8.azl3.aarch64.rpm diff --git a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt index a0ea892b228..48794950033 100644 --- a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt @@ -244,9 +244,9 @@ ca-certificates-base-3.0.0-15.azl3.noarch.rpm ca-certificates-3.0.0-15.azl3.noarch.rpm dwz-0.14-2.azl3.x86_64.rpm unzip-6.0-22.azl3.x86_64.rpm -python3-3.12.9-13.azl3.x86_64.rpm -python3-devel-3.12.9-13.azl3.x86_64.rpm -python3-libs-3.12.9-13.azl3.x86_64.rpm +python3-3.12.9-14.azl3.x86_64.rpm +python3-devel-3.12.9-14.azl3.x86_64.rpm +python3-libs-3.12.9-14.azl3.x86_64.rpm python3-setuptools-69.0.3-6.azl3.noarch.rpm python3-pygments-2.7.4-2.azl3.noarch.rpm which-2.21-8.azl3.x86_64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_aarch64.txt b/toolkit/resources/manifests/package/toolchain_aarch64.txt index 297878fa19c..a99a7be9a63 100644 --- a/toolkit/resources/manifests/package/toolchain_aarch64.txt +++ b/toolkit/resources/manifests/package/toolchain_aarch64.txt @@ -531,19 +531,19 @@ 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-2.azl3.noarch.rpm -python3-3.12.9-13.azl3.aarch64.rpm +python3-3.12.9-14.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-13.azl3.aarch64.rpm +python3-curses-3.12.9-14.azl3.aarch64.rpm python3-Cython-3.0.5-3.azl3.aarch64.rpm -python3-debuginfo-3.12.9-13.azl3.aarch64.rpm -python3-devel-3.12.9-13.azl3.aarch64.rpm +python3-debuginfo-3.12.9-14.azl3.aarch64.rpm +python3-devel-3.12.9-14.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-libmount-2.40.2-5.azl3.aarch64.rpm -python3-libs-3.12.9-13.azl3.aarch64.rpm +python3-libs-3.12.9-14.azl3.aarch64.rpm python3-libxml2-2.11.5-10.azl3.aarch64.rpm python3-lxml-4.9.3-2.azl3.aarch64.rpm python3-magic-5.45-1.azl3.noarch.rpm @@ -555,8 +555,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-6.azl3.noarch.rpm -python3-test-3.12.9-13.azl3.aarch64.rpm -python3-tools-3.12.9-13.azl3.aarch64.rpm +python3-test-3.12.9-14.azl3.aarch64.rpm +python3-tools-3.12.9-14.azl3.aarch64.rpm python3-wheel-0.43.0-2.azl3.noarch.rpm readline-8.2-2.azl3.aarch64.rpm readline-debuginfo-8.2-2.azl3.aarch64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_x86_64.txt b/toolkit/resources/manifests/package/toolchain_x86_64.txt index 115dd52ed94..80ae1c75cc9 100644 --- a/toolkit/resources/manifests/package/toolchain_x86_64.txt +++ b/toolkit/resources/manifests/package/toolchain_x86_64.txt @@ -539,19 +539,19 @@ 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-2.azl3.noarch.rpm -python3-3.12.9-13.azl3.x86_64.rpm +python3-3.12.9-14.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-13.azl3.x86_64.rpm +python3-curses-3.12.9-14.azl3.x86_64.rpm python3-Cython-3.0.5-3.azl3.x86_64.rpm -python3-debuginfo-3.12.9-13.azl3.x86_64.rpm -python3-devel-3.12.9-13.azl3.x86_64.rpm +python3-debuginfo-3.12.9-14.azl3.x86_64.rpm +python3-devel-3.12.9-14.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-libmount-2.40.2-5.azl3.x86_64.rpm -python3-libs-3.12.9-13.azl3.x86_64.rpm +python3-libs-3.12.9-14.azl3.x86_64.rpm python3-libxml2-2.11.5-10.azl3.x86_64.rpm python3-lxml-4.9.3-2.azl3.x86_64.rpm python3-magic-5.45-1.azl3.noarch.rpm @@ -563,8 +563,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-6.azl3.noarch.rpm -python3-test-3.12.9-13.azl3.x86_64.rpm -python3-tools-3.12.9-13.azl3.x86_64.rpm +python3-test-3.12.9-14.azl3.x86_64.rpm +python3-tools-3.12.9-14.azl3.x86_64.rpm python3-wheel-0.43.0-2.azl3.noarch.rpm readline-8.2-2.azl3.x86_64.rpm readline-debuginfo-8.2-2.azl3.x86_64.rpm