mirror of
https://git.yoctoproject.org/poky
synced 2026-07-29 22:17:46 +02:00
python3: fix CVE-2026-11940
tarfile.extractall() with the 'data' or 'tar' filter could be bypassed by a crafted archive where a hardlink references a symlink stored at a deeper name than the hardlink itself. (From OE-Core rev: a76513212f1830fbda2dc6a243943a3c1a011239) Signed-off-by: Benjamin Robin (Schneider Electric) <benjamin.robin@bootlin.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
committed by
Paul Barker
parent
f55e6c80f1
commit
ca405952dc
66
meta/recipes-devtools/python/python3/CVE-2026-11940.patch
Normal file
66
meta/recipes-devtools/python/python3/CVE-2026-11940.patch
Normal file
@@ -0,0 +1,66 @@
|
||||
From 91a9bd79cdbab8f8518c4a5e669b3f19680a2f31 Mon Sep 17 00:00:00 2001
|
||||
From: Stan Ulbrych <stan@python.org>
|
||||
Date: Tue, 23 Jun 2026 14:31:38 +0100
|
||||
Subject: [PATCH] gh-151558: Fix symlink escape via `tarfile`
|
||||
hardlink-extraction fallback (GH-151559)
|
||||
|
||||
CVE: CVE-2026-11940
|
||||
Upstream-Status: Backport [https://github.com/python/cpython/commit/27dd970bf6b17ebca7c8ed486a40ab043ed7af8f]
|
||||
|
||||
Signed-off-by: Benjamin Robin <benjamin.robin@bootlin.com>
|
||||
---
|
||||
Lib/tarfile.py | 3 +++
|
||||
Lib/test/test_tarfile.py | 24 ++++++++++++++++++++++++
|
||||
2 files changed, 27 insertions(+)
|
||||
|
||||
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
|
||||
index 59d3f6e5cce1..83226e907e4b 100755
|
||||
--- a/Lib/tarfile.py
|
||||
+++ b/Lib/tarfile.py
|
||||
@@ -2650,6 +2650,9 @@ def makelink_with_filter(self, tarinfo, targetpath,
|
||||
"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 759fa03ead70..29719d95b6c1 100644
|
||||
--- a/Lib/test/test_tarfile.py
|
||||
+++ b/Lib/test/test_tarfile.py
|
||||
@@ -4080,6 +4080,30 @@ def test_sneaky_hardlink_fallback(self):
|
||||
self.expect_file("boom", symlink_to='../../link_here')
|
||||
self.expect_file("c", symlink_to='b')
|
||||
|
||||
+ @symlink_test
|
||||
+ 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 os_helper.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'))
|
||||
+
|
||||
@symlink_test
|
||||
def test_exfiltration_via_symlink(self):
|
||||
# (CVE-2025-4138)
|
||||
--
|
||||
2.54.0
|
||||
@@ -44,6 +44,7 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
|
||||
file://CVE-2026-6019_p2.patch \
|
||||
file://CVE-2025-13462.patch \
|
||||
file://CVE-2026-4224.patch \
|
||||
file://CVE-2026-11940.patch \
|
||||
"
|
||||
|
||||
SRC_URI:append:class-native = " \
|
||||
|
||||
Reference in New Issue
Block a user