Files
poky/meta/recipes-devtools/python/python3-pip/CVE-2026-8643-regression_p2.patch
Hetvi Thakar b24d56a0b3 python3-pip: Fix CVE-2026-8643
Apply the primary upstream fix referenced in [4] with commit [1]. Then
apply the two follow-up regression-fix commits [2] and [3].

The primary fix rejects entry-point names that escape the configured
scripts directory. The follow-up fixes handle doubled-slash roots and
reuse the existing directory-containment helper.

[1] https://github.com/pypa/pip/commit/8eb178480bd1a2b223f509fc430796b265158dfb
[2] https://github.com/pypa/pip/commit/7ff8bdd81ec5edca2bebf78ad8506dda710d6af5
[3] https://github.com/pypa/pip/commit/fa7854f6b37113a2c4698cdde902e1fcc9bebdd5
[4] https://github.com/advisories/GHSA-wf93-45jw-7689

(From OE-Core rev: 2c276677d619bc6205872eb2b5a9948a4605d8ea)

Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
2026-09-21 08:53:17 +01:00

70 lines
3.1 KiB
Diff

From b77d10eee5805aea3055e434e08ad1f105bd330c Mon Sep 17 00:00:00 2001
From: Damian <damian.peter.shaw@gmail.com>
Date: Sun, 24 May 2026 14:54:47 -0400
Subject: [PATCH] Use is_within_directory for entry point check
CVE: CVE-2026-8643
Upstream-Status: Backport [https://github.com/pypa/pip/commit/fa7854f6b37113a2c4698cdde902e1fcc9bebdd5]
Backport Changes:
- Omit tests/unit/test_wheel.py because the pip 24.0 PyPI sdist used by this
recipe does not ship the upstream tests directory.
(cherry picked from commit fa7854f6b37113a2c4698cdde902e1fcc9bebdd5)
Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
---
src/pip/_internal/operations/install/wheel.py | 18 ++----
src/pip/_internal/utils/unpacking.py | 1 +
2 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/src/pip/_internal/operations/install/wheel.py b/src/pip/_internal/operations/install/wheel.py
index 8a36a66ae..ce3e8efe6 100644
--- a/src/pip/_internal/operations/install/wheel.py
+++ b/src/pip/_internal/operations/install/wheel.py
@@ -409,17 +409,6 @@ class MissingCallableSuffix(InstallationError):
)
-def _script_within_dir(name: str, scripts_dir: str) -> bool:
- """Return whether script ``name`` resolves to a path inside the ``scripts_dir``.
-
- distlib joins the entry point name onto the scripts directory, so a name
- with path separators or ``..`` components can resolve elsewhere.
- """
- root = os.path.normpath(scripts_dir)
- dest = os.path.normpath(os.path.join(scripts_dir, name))
- return dest.startswith(root + os.sep)
-
-
def _raise_for_invalid_entrypoint(specification: str, scripts_dir: str) -> None:
entry = get_export_entry(specification)
if entry is None:
@@ -428,7 +417,12 @@ def _raise_for_invalid_entrypoint(specification: str, scripts_dir: str) -> None:
if entry.suffix is None:
raise MissingCallableSuffix(str(entry))
- if not _script_within_dir(entry.name, scripts_dir):
+ # distlib joins the entry point name onto the scripts directory, so a name
+ # with path separators or ``..`` components can resolve elsewhere. The script
+ # must resolve to a path strictly inside the scripts directory.
+ dest = os.path.join(scripts_dir, entry.name)
+ resolves_to_scripts_dir = os.path.abspath(dest) == os.path.abspath(scripts_dir)
+ if resolves_to_scripts_dir or not is_within_directory(scripts_dir, dest):
raise InstallationError(
f"Invalid script entry point name {entry.name!r}: the script "
f"would be installed outside the scripts directory ({scripts_dir})."
diff --git a/src/pip/_internal/utils/unpacking.py b/src/pip/_internal/utils/unpacking.py
index 188f27e67..14b7e846a 100644
--- a/src/pip/_internal/utils/unpacking.py
+++ b/src/pip/_internal/utils/unpacking.py
@@ -77,6 +77,7 @@ def has_leading_dir(paths: Iterable[str]) -> bool:
def is_within_directory(directory: str, target: str) -> bool:
"""
Return true if the absolute path of target is within the directory
+ (including when target is equal to the directory).
"""
abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)
--
2.35.6