From 1f79cb1794fb122635d2102c1523ce74f8852426 Mon Sep 17 00:00:00 2001 From: PengLAI Code Date: Sat, 29 Aug 2026 14:11:46 +0800 Subject: [PATCH 1/2] [CVE] [Upstream] add patch to fix CVE-2026-3219 to #IK222U Upstream: https://github.com/pypa/pip/pull/13870 project: TC2024080204 Assisted-by: PengLAI Code --- CVE-2026-3219.patch | 82 +++++++++++++++++++++++++++++++++++++++++++++ python-pip.spec | 11 +++++- 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 CVE-2026-3219.patch diff --git a/CVE-2026-3219.patch b/CVE-2026-3219.patch new file mode 100644 index 0000000..8f5ffa6 --- /dev/null +++ b/CVE-2026-3219.patch @@ -0,0 +1,82 @@ +From 9b08c2b910fc9ec45a0c1b6cc041a934dfecd1b7 Mon Sep 17 00:00:00 2001 +From: Dmitrii Sutiagin +Date: Thu, 26 Mar 2026 09:37:36 -0700 +Subject: [PATCH 1/8] Refactor unpacking logic for archive files + +Make unpacking logic resilient against ambiguous signature check, and order logic by check confidence instead of by file format. +Adapted-by: PengLAI Code +--- + src/pip/_internal/utils/unpacking.py | 63 ++++++++++++++++++++++++++++++---------------------- + 1 file changed, 41 insertions(+), 22 deletions(-) + +diff --git a/src/pip/_internal/utils/unpacking.py b/src/pip/_internal/utils/unpacking.py +--- a/src/pip/_internal/utils/unpacking.py ++++ b/src/pip/_internal/utils/unpacking.py +@@ -245,26 +245,45 @@ + content_type: Optional[str] = None, + ) -> None: ++ """Unpack ``filename`` into ``location``. ++ ++ Archive format is chosen in order of decreasing reliability: ++ ``content_type``, then filename extension, then magic signature ++ (unambiguous matches only). ++ """ + filename = os.path.realpath(filename) +- if ( +- content_type == "application/zip" +- or filename.lower().endswith(ZIP_EXTENSIONS) +- or zipfile.is_zipfile(filename) +- ): +- unzip_file(filename, location, flatten=not filename.endswith(".whl")) +- elif ( +- content_type == "application/x-gzip" +- or tarfile.is_tarfile(filename) +- or filename.lower().endswith(TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS) +- ): ++ zip_flatten = not filename.endswith(".whl") ++ ++ def _unzip() -> None: ++ unzip_file(filename, location, flatten=zip_flatten) ++ ++ def _untar() -> None: + untar_file(filename, location) +- else: +- # FIXME: handle? +- # FIXME: magic signatures? +- logger.critical( +- "Cannot unpack file %s (downloaded from %s, content-type: %s); " +- "cannot detect archive format", +- filename, +- location, +- content_type, +- ) +- raise InstallationError(f"Cannot determine archive format of {location}") ++ ++ if content_type == "application/zip": ++ return _unzip() ++ if content_type == "application/x-gzip": ++ return _untar() ++ ++ if filename.lower().endswith(ZIP_EXTENSIONS): ++ return _unzip() ++ if filename.lower().endswith(TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS): ++ return _untar() ++ ++ # avoid ambiguous case where both signature checks return True ++ is_zipfile = zipfile.is_zipfile(filename) ++ is_tarfile = tarfile.is_tarfile(filename) ++ if is_zipfile and not is_tarfile: ++ return _unzip() ++ if is_tarfile and not is_zipfile: ++ return _untar() ++ if is_zipfile and is_tarfile: ++ logger.error("Ambiguous file signature in %s.", filename) ++ ++ logger.critical( ++ "Cannot unpack file %s (downloaded from %s, content-type: %s); " ++ "cannot detect archive format", ++ filename, ++ location, ++ content_type, ++ ) ++ raise InstallationError(f"Cannot determine archive format of {location}") diff --git a/python-pip.spec b/python-pip.spec index 19186d2..ac6b928 100644 --- a/python-pip.spec +++ b/python-pip.spec @@ -1,4 +1,4 @@ -%define anolis_release 11 +%define anolis_release 12 %bcond_with tests %bcond_with doc @@ -53,6 +53,10 @@ Patch1003: 0001-Fix-TypeError-when-reading-HTTPResponse-with-amt-Non.patch # Source: upstream # Reference: https://github.com/pypa/pip/pull/14110 Patch1004: CVE-2026-13346.patch +# CVE-2026-3219 +# Source: upstream +# Reference: https://github.com/pypa/pip/pull/13870 +Patch1005: CVE-2026-3219.patch %global bundled() %{expand: Provides: bundled(python%{1}dist(cachecontrol)) = 0.13.1 @@ -256,6 +260,11 @@ pytest_k='not completion' %endif %changelog +* Sat Aug 29 2026 PengLAI Code - 23.3.1-12 +- Fix CVE-2026-3219 +- Upstream patch: https://github.com/pypa/pip/pull/13870 +- Adapted by PengLAI Code + * Thu Aug 27 2026 PengLAI Code - 23.3.1-11 - Fix CVE-2026-13346 - Upstream patch: https://github.com/pypa/pip/pull/14110 -- Gitee From aee25bbc8566bbfbf43532d4d91ad0fd3e89deee Mon Sep 17 00:00:00 2001 From: PengLAI Code Date: Sat, 29 Aug 2026 14:13:14 +0800 Subject: [PATCH 2/2] Correct attribution header of CVE-2026-3219 patch The auto-generated header credited a single intermediate commit of upstream PR 13870, while the patch is the squashed net effect of all eight commits in that PR. Describe it as such so the provenance and the 23.3.1 adaptation are auditable. Assisted-by: PengLAI Code --- CVE-2026-3219.patch | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/CVE-2026-3219.patch b/CVE-2026-3219.patch index 8f5ffa6..1bedf18 100644 --- a/CVE-2026-3219.patch +++ b/CVE-2026-3219.patch @@ -1,12 +1,26 @@ -From 9b08c2b910fc9ec45a0c1b6cc041a934dfecd1b7 Mon Sep 17 00:00:00 2001 -From: Dmitrii Sutiagin -Date: Thu, 26 Mar 2026 09:37:36 -0700 -Subject: [PATCH 1/8] Refactor unpacking logic for archive files +From: Damian Shaw +Date: Fri, 17 Apr 2026 23:12:10 -0400 +Subject: [PATCH] add patch to fix CVE-2026-3219 + +unpack_file() decided the archive format by evaluating every zip check +first (content-type, filename extension and zipfile.is_zipfile) before +any tar check. zipfile.is_zipfile only scans for an end-of-central- +directory record, so a crafted .tar.gz carrying a trailing EOCD record +satisfies both is_zipfile and is_tarfile and gets handed to the zip +unpacker, so the archive is processed by the wrong extractor. + +Order the detection by decreasing reliability instead: explicit +content_type, then filename extension, then the magic signature check, +and only trust the signature when exactly one of is_zipfile/is_tarfile +matches. Files matching both are refused. + +Squashed backport of upstream https://github.com/pypa/pip/pull/13870 +(commits 9b08c2b..b6e2826), adapted to 23.3.1 which uses Optional[str] +rather than PEP 604 unions. -Make unpacking logic resilient against ambiguous signature check, and order logic by check confidence instead of by file format. Adapted-by: PengLAI Code --- - src/pip/_internal/utils/unpacking.py | 63 ++++++++++++++++++++++++++++++---------------------- + src/pip/_internal/utils/unpacking.py | 63 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/pip/_internal/utils/unpacking.py b/src/pip/_internal/utils/unpacking.py -- Gitee