mirror of
https://git.yoctoproject.org/poky
synced 2026-06-27 20:13:41 +02:00
python3: Fix CVE-2025-13462
Apply the upstream v3.12 fix [1], aligned with the original v3.13 fix [2], to address incorrect tarfile handling where GNU long name follow-up headers could be normalized as directories, as referenced in [3]. [1]d10950739a[2]ae99fe3a33[3] https://security-tracker.debian.org/tracker/CVE-2025-13462 Reference: https://nvd.nist.gov/vuln/detail/CVE-2025-13462 (From OE-Core rev: 0b990a354ef858d903d4bed937b1233537c2c478) Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.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
7731db5592
commit
e61bf028a6
142
meta/recipes-devtools/python/python3/CVE-2025-13462.patch
Normal file
142
meta/recipes-devtools/python/python3/CVE-2025-13462.patch
Normal file
@@ -0,0 +1,142 @@
|
||||
From 14d7d2e8f51a17c23c98f13f33743253a0b7a18a Mon Sep 17 00:00:00 2001
|
||||
From: "Miss Islington (bot)"
|
||||
<31488909+miss-islington@users.noreply.github.com>
|
||||
Date: Mon, 18 May 2026 19:43:51 +0200
|
||||
Subject: [PATCH] [3.12] gh-141707: Skip TarInfo DIRTYPE normalization during
|
||||
GNU long name handling (#145817)
|
||||
|
||||
gh-141707: Skip TarInfo DIRTYPE normalization during GNU long name handling
|
||||
|
||||
CVE: CVE-2025-13462
|
||||
Upstream-Status: Backport [https://github.com/python/cpython/commit/d10950739a78f54d0718d88fb5a868374603c084]
|
||||
|
||||
Backport Changes:
|
||||
- This file is not present in the current version and is therefore omitted
|
||||
Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst
|
||||
|
||||
(cherry picked from commit 42d754e34c06e57ad6b8e7f92f32af679912d8ab)
|
||||
|
||||
Co-authored-by: Seth Michael Larson <seth@python.org>
|
||||
Co-authored-by: Eashwar Ranganathan <eashwar@eashwar.com>
|
||||
(cherry picked from commit d10950739a78f54d0718d88fb5a868374603c084)
|
||||
Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
|
||||
---
|
||||
Lib/tarfile.py | 29 +++++++++++++++++++++++++----
|
||||
Lib/test/test_tarfile.py | 19 +++++++++++++++++++
|
||||
Misc/ACKS | 1 +
|
||||
3 files changed, 45 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
|
||||
index 99451aa765..70fdbe85b0 100755
|
||||
--- a/Lib/tarfile.py
|
||||
+++ b/Lib/tarfile.py
|
||||
@@ -1246,6 +1246,20 @@ class TarInfo(object):
|
||||
@classmethod
|
||||
def frombuf(cls, buf, encoding, errors):
|
||||
"""Construct a TarInfo object from a 512 byte bytes object.
|
||||
+
|
||||
+ To support the old v7 tar format AREGTYPE headers are
|
||||
+ transformed to DIRTYPE headers if their name ends in '/'.
|
||||
+ """
|
||||
+ return cls._frombuf(buf, encoding, errors)
|
||||
+
|
||||
+ @classmethod
|
||||
+ def _frombuf(cls, buf, encoding, errors, *, dircheck=True):
|
||||
+ """Construct a TarInfo object from a 512 byte bytes object.
|
||||
+
|
||||
+ If ``dircheck`` is set to ``True`` then ``AREGTYPE`` headers will
|
||||
+ be normalized to ``DIRTYPE`` if the name ends in a trailing slash.
|
||||
+ ``dircheck`` must be set to ``False`` if this function is called
|
||||
+ on a follow-up header such as ``GNUTYPE_LONGNAME``.
|
||||
"""
|
||||
if len(buf) == 0:
|
||||
raise EmptyHeaderError("empty header")
|
||||
@@ -1276,7 +1290,7 @@ class TarInfo(object):
|
||||
|
||||
# Old V7 tar format represents a directory as a regular
|
||||
# file with a trailing slash.
|
||||
- if obj.type == AREGTYPE and obj.name.endswith("/"):
|
||||
+ if dircheck and obj.type == AREGTYPE and obj.name.endswith("/"):
|
||||
obj.type = DIRTYPE
|
||||
|
||||
# The old GNU sparse format occupies some of the unused
|
||||
@@ -1311,8 +1325,15 @@ class TarInfo(object):
|
||||
"""Return the next TarInfo object from TarFile object
|
||||
tarfile.
|
||||
"""
|
||||
+ return cls._fromtarfile(tarfile)
|
||||
+
|
||||
+ @classmethod
|
||||
+ def _fromtarfile(cls, tarfile, *, dircheck=True):
|
||||
+ """
|
||||
+ See dircheck documentation in _frombuf().
|
||||
+ """
|
||||
buf = tarfile.fileobj.read(BLOCKSIZE)
|
||||
- obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors)
|
||||
+ obj = cls._frombuf(buf, tarfile.encoding, tarfile.errors, dircheck=dircheck)
|
||||
obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
|
||||
return obj._proc_member(tarfile)
|
||||
|
||||
@@ -1370,7 +1391,7 @@ class TarInfo(object):
|
||||
|
||||
# Fetch the next header and process it.
|
||||
try:
|
||||
- next = self.fromtarfile(tarfile)
|
||||
+ next = self._fromtarfile(tarfile, dircheck=False)
|
||||
except HeaderError as e:
|
||||
raise SubsequentHeaderError(str(e)) from None
|
||||
|
||||
@@ -1505,7 +1526,7 @@ class TarInfo(object):
|
||||
|
||||
# Fetch the next header.
|
||||
try:
|
||||
- next = self.fromtarfile(tarfile)
|
||||
+ next = self._fromtarfile(tarfile, dircheck=False)
|
||||
except HeaderError as e:
|
||||
raise SubsequentHeaderError(str(e)) from None
|
||||
|
||||
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
|
||||
index 759fa03ead..82637841ed 100644
|
||||
--- a/Lib/test/test_tarfile.py
|
||||
+++ b/Lib/test/test_tarfile.py
|
||||
@@ -1134,6 +1134,25 @@ class LongnameTest:
|
||||
self.assertIsNotNone(tar.getmember(longdir))
|
||||
self.assertIsNotNone(tar.getmember(longdir.removesuffix('/')))
|
||||
|
||||
+ def test_longname_file_not_directory(self):
|
||||
+ # Test reading a longname file and ensure it is not handled as a directory
|
||||
+ # Issue #141707
|
||||
+ buf = io.BytesIO()
|
||||
+ with tarfile.open(mode='w', fileobj=buf, format=self.format) as tar:
|
||||
+ ti = tarfile.TarInfo()
|
||||
+ ti.type = tarfile.AREGTYPE
|
||||
+ ti.name = ('a' * 99) + '/' + ('b' * 3)
|
||||
+ tar.addfile(ti)
|
||||
+
|
||||
+ expected = {t.name: t.type for t in tar.getmembers()}
|
||||
+
|
||||
+ buf.seek(0)
|
||||
+ with tarfile.open(mode='r', fileobj=buf) as tar:
|
||||
+ actual = {t.name: t.type for t in tar.getmembers()}
|
||||
+
|
||||
+ self.assertEqual(expected, actual)
|
||||
+
|
||||
+
|
||||
class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase):
|
||||
|
||||
subdir = "gnu"
|
||||
diff --git a/Misc/ACKS b/Misc/ACKS
|
||||
index a6e63a991f..30d5f99ebb 100644
|
||||
--- a/Misc/ACKS
|
||||
+++ b/Misc/ACKS
|
||||
@@ -1492,6 +1492,7 @@ Dhushyanth Ramasamy
|
||||
Ashwin Ramaswami
|
||||
Jeff Ramnani
|
||||
Bayard Randel
|
||||
+Eashwar Ranganathan
|
||||
Varpu Rantala
|
||||
Brodie Rao
|
||||
Rémi Rampin
|
||||
--
|
||||
2.35.6
|
||||
|
||||
Reference in New Issue
Block a user