diff --git a/00492-cve-2026-11940.patch b/00492-cve-2026-11940.patch new file mode 100644 index 0000000..182c373 --- /dev/null +++ b/00492-cve-2026-11940.patch @@ -0,0 +1,59 @@ +From a235238fe0884e85cdacbc986a4749c5c4717212 Mon Sep 17 00:00:00 2001 +From: Stan Ulbrych +Date: Tue, 23 Jun 2026 14:31:38 +0100 +Subject: [PATCH] gh-151558: Fix symlink escape via `tarfile` + hardlink-extraction fallback (GH-151559) + +--- + Lib/tarfile.py | 3 +++ + Lib/test/test_tarfile.py | 23 +++++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +diff --git a/Lib/tarfile.py b/Lib/tarfile.py +index 3e03ebf..61d7e46 100755 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -2642,6 +2642,9 @@ class TarFile(object): + "makelink_with_filter: if filter_function is not None, " + + "extraction_root must also not be None") + try: ++ filter_function( ++ unfiltered.replace(name=tarinfo.name, deep=False), ++ extraction_root) + filtered = filter_function(unfiltered, extraction_root) + except _FILTER_ERRORS as cause: + raise LinkFallbackError(tarinfo, unfiltered.name) from cause +diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py +index 0a7586a..d43559a 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -3543,6 +3543,29 @@ class TestExtractionFilters(unittest.TestCase): + self.expect_file("boom", symlink_to='../../link_here') + self.expect_file("c", symlink_to='b') + ++ def test_sneaky_hardlink_fallback_deep(self): ++ # (CVE-2026-11940) ++ with ArchiveMaker() as arc: ++ arc.add("a/b/s", symlink_to=os.path.join("..", "escape")) ++ arc.add("s", hardlink_to=os.path.join("a", "b", "s")) ++ ++ with self.check_context(arc.open(), 'data'): ++ e = self.expect_exception( ++ tarfile.LinkFallbackError, ++ "link 's' would be extracted as a copy of " ++ + "'a/b/s', which was rejected") ++ self.assertIsInstance(e.__cause__, ++ tarfile.LinkOutsideDestinationError) ++ ++ for filter in 'tar', 'fully_trusted': ++ with self.subTest(filter), self.check_context(arc.open(), filter): ++ if not support.can_symlink(): ++ self.expect_file("a/") ++ self.expect_file("a/b/") ++ else: ++ self.expect_file("a/b/s", symlink_to=os.path.join('..', 'escape')) ++ self.expect_file("s", symlink_to=os.path.join('..', 'escape')) ++ + def test_exfiltration_via_symlink(self): + # (CVE-2025-4138) + # Test changing symlinks that result in a symlink pointing outside diff --git a/python3.spec b/python3.spec index dd1b332..85b496e 100644 --- a/python3.spec +++ b/python3.spec @@ -14,7 +14,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well Version: %{pybasever}.8 -Release: 77%{?dist} +Release: 78%{?dist} License: Python @@ -1028,6 +1028,12 @@ Patch482: 00482-cve-2026-6100.patch # only joined and parsed once enough has piled up. Patch490: 00490-cve-2026-15308.patch +# 00492 # +# CVE-2026-11940 +# +# gh-151558: Fix symlink escape via tarfile hardlink-extraction fallback (GH-151559) +Patch492: 00492-cve-2026-11940.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1409,6 +1415,7 @@ GIT_DIR=$PWD git apply %{PATCH351} %patch480 -p1 %patch482 -p1 %patch490 -p1 +%patch492 -p1 # Remove files that should be generated by the build # (This is after patching, so that we can use patches directly from upstream) @@ -2340,6 +2347,10 @@ fi # ====================================================== %changelog +* Thu Aug 06 2026 RHEL Packaging Agent - 3.6.8-78 +- Security fix for CVE-2026-11940 +Resolves: RHEL-227194 + * Fri Jul 10 2026 Lumír Balhar - 3.6.8-77 - Security fix for CVE-2026-15308 Resolves: RHEL-193772