Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions SPECS/python-virtualenv/CVE-2025-50181.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
From f05b1329126d5be6de501f9d1e3e36738bc08857 Mon Sep 17 00:00:00 2001
From: Illia Volochii <illia.volochii@gmail.com>
Date: Wed, 18 Jun 2025 16:25:01 +0300
Subject: [PATCH] Merge commit from fork

* Apply Quentin's suggestion

Co-authored-by: Quentin Pradet <quentin.pradet@gmail.com>

* Add tests for disabled redirects in the pool manager

* Add a possible fix for the issue with not raised `MaxRetryError`

* Make urllib3 handle redirects instead of JS when JSPI is used

* Fix info in the new comment

* State that redirects with XHR are not controlled by urllib3

* Remove excessive params from new test requests

* Add tests reaching max non-0 redirects

* Test redirects with Emscripten

* Fix `test_merge_pool_kwargs`

* Add a changelog entry

* Parametrize tests

* Drop a fix for Emscripten

* Apply Seth's suggestion to docs

Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>

* Use a minor release instead of the patch one

---------

Co-authored-by: Quentin Pradet <quentin.pradet@gmail.com>
Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
Upstream Patch Reference: https://github.com/urllib3/urllib3/commit/f05b1329126d5be6de501f9d1e3e36738bc08857.patch
---
pip/_vendor/urllib3/poolmanager.py | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/pip/_vendor/urllib3/poolmanager.py b/pip/_vendor/urllib3/poolmanager.py
index fb51bf7..a8de7c6 100644
--- a/pip/_vendor/urllib3/poolmanager.py
+++ b/pip/_vendor/urllib3/poolmanager.py
@@ -170,6 +170,22 @@ class PoolManager(RequestMethods):

def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
RequestMethods.__init__(self, headers)
+ if "retries" in connection_pool_kw:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch looks good w.r.t upstream

+ retries = connection_pool_kw["retries"]
+ if not isinstance(retries, Retry):
+ # When Retry is initialized, raise_on_redirect is based
+ # on a redirect boolean value.
+ # But requests made via a pool manager always set
+ # redirect to False, and raise_on_redirect always ends
+ # up being False consequently.
+ # Here we fix the issue by setting raise_on_redirect to
+ # a value needed by the pool manager without considering
+ # the redirect boolean.
+ raise_on_redirect = retries is not False
+ retries = Retry.from_int(retries, redirect=False)
+ retries.raise_on_redirect = raise_on_redirect
+ connection_pool_kw = connection_pool_kw.copy()
+ connection_pool_kw["retries"] = retries
self.connection_pool_kw = connection_pool_kw
self.pools = RecentlyUsedContainer(num_pools)

@@ -389,7 +405,7 @@ class PoolManager(RequestMethods):
kw["body"] = None
kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()

- retries = kw.get("retries")
+ retries = kw.get("retries", response.retries)
if not isinstance(retries, Retry):
retries = Retry.from_int(retries, redirect=redirect)

--
2.45.4

35 changes: 35 additions & 0 deletions SPECS/python-virtualenv/CVE-2026-1703v0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 4c651b70d60ed91b13663bcda9b3ed41748d0124 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
Date: Fri, 30 Jan 2026 09:49:11 -0600
Subject: [PATCH] Use os.path.commonpath() instead of commonprefix()

Upstream Patch Reference: https://github.com/pypa/pip/commit/8e227a9be4faa9594e05d02ca05a413a2a4e7735.patch
---
news/+1ee322a1.bugfix.rst | 1 +
pip/_internal/utils/unpacking.py | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 news/+1ee322a1.bugfix.rst

diff --git a/news/+1ee322a1.bugfix.rst b/news/+1ee322a1.bugfix.rst
new file mode 100644
index 0000000..edb1b32
--- /dev/null
+++ b/news/+1ee322a1.bugfix.rst
@@ -0,0 +1 @@
+Use a path-segment prefix comparison, not char-by-char.
diff --git a/pip/_internal/utils/unpacking.py b/pip/_internal/utils/unpacking.py
index 87a6d19..b5c736d 100644
--- a/pip/_internal/utils/unpacking.py
+++ b/pip/_internal/utils/unpacking.py
@@ -82,7 +82,7 @@ def is_within_directory(directory: str, target: str) -> bool:
abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)

- prefix = os.path.commonprefix([abs_directory, abs_target])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch looks good w.r.t upstream

+ prefix = os.path.commonpath([abs_directory, abs_target])
return prefix == abs_directory


--
2.45.4

27 changes: 27 additions & 0 deletions SPECS/python-virtualenv/CVE-2026-1703v1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
From 4c651b70d60ed91b13663bcda9b3ed41748d0124 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
Date: Fri, 30 Jan 2026 09:49:11 -0600
Subject: [PATCH] Use os.path.commonpath() instead of commonprefix()

Upstream Patch Reference: https://github.com/pypa/pip/commit/8e227a9be4faa9594e05d02ca05a413a2a4e7735.patch

---
pip/_internal/utils/unpacking.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pip/_internal/utils/unpacking.py b/pip/_internal/utils/unpacking.py
index bc950ac..b3f52e8 100644
--- a/pip/_internal/utils/unpacking.py
+++ b/pip/_internal/utils/unpacking.py
@@ -83,7 +83,7 @@ def is_within_directory(directory: str, target: str) -> bool:
abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)

- prefix = os.path.commonprefix([abs_directory, abs_target])
+ prefix = os.path.commonpath([abs_directory, abs_target])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch looks good w.r.t upstream

return prefix == abs_directory


--
2.45.4

35 changes: 35 additions & 0 deletions SPECS/python-virtualenv/CVE-2026-24049v0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 7a7d2de96b22a9adf9208afcc9547e1001569fef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= <alex.gronholm@nextday.fi>
Date: Thu, 22 Jan 2026 01:41:14 +0200
Subject: [PATCH] Fixed security issue around wheel unpack (#675)

A maliciously crafted wheel could cause the permissions of a file outside the unpack tree to be altered.

Fixes CVE-2026-24049.
Upstream Patch Reference: https://github.com/pypa/wheel/commit/7a7d2de96b22a9adf9208afcc9547e1001569fef.patch
---
setuptools/_vendor/wheel/cli/unpack.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/setuptools/_vendor/wheel/cli/unpack.py b/setuptools/_vendor/wheel/cli/unpack.py
index d48840e..83dc742 100644
--- a/setuptools/_vendor/wheel/cli/unpack.py
+++ b/setuptools/_vendor/wheel/cli/unpack.py
@@ -19,12 +19,12 @@ def unpack(path: str, dest: str = ".") -> None:
destination = Path(dest) / namever
print(f"Unpacking to: {destination}...", end="", flush=True)
for zinfo in wf.filelist:
- wf.extract(zinfo, destination)
+ target_path = Path(wf.extract(zinfo, destination))

# Set permissions to the same values as they were set in the archive
# We have to do this manually due to
# https://github.com/python/cpython/issues/59999
permissions = zinfo.external_attr >> 16 & 0o777
- destination.joinpath(zinfo.filename).chmod(permissions)
+ target_path.chmod(permissions)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch looks good w.r.t upstream


print("OK")
--
2.45.4

35 changes: 35 additions & 0 deletions SPECS/python-virtualenv/CVE-2026-24049v1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 7a7d2de96b22a9adf9208afcc9547e1001569fef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= <alex.gronholm@nextday.fi>
Date: Thu, 22 Jan 2026 01:41:14 +0200
Subject: [PATCH] Fixed security issue around wheel unpack (#675)

A maliciously crafted wheel could cause the permissions of a file outside the unpack tree to be altered.

Fixes CVE-2026-24049.
Upstream Patch Reference: https://github.com/pypa/wheel/commit/7a7d2de96b22a9adf9208afcc9547e1001569fef.patch
---
wheel/cli/unpack.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/wheel/cli/unpack.py b/wheel/cli/unpack.py
index d48840e..83dc742 100644
--- a/wheel/cli/unpack.py
+++ b/wheel/cli/unpack.py
@@ -19,12 +19,12 @@ def unpack(path: str, dest: str = ".") -> None:
destination = Path(dest) / namever
print(f"Unpacking to: {destination}...", end="", flush=True)
for zinfo in wf.filelist:
- wf.extract(zinfo, destination)
+ target_path = Path(wf.extract(zinfo, destination))

# Set permissions to the same values as they were set in the archive
# We have to do this manually due to
# https://github.com/python/cpython/issues/59999
permissions = zinfo.external_attr >> 16 & 0o777
- destination.joinpath(zinfo.filename).chmod(permissions)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch looks good w.r.t upstream

+ target_path.chmod(permissions)

print("OK")
--
2.45.4

83 changes: 81 additions & 2 deletions SPECS/python-virtualenv/python-virtualenv.spec
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
Summary: Virtual Python Environment builder
Name: python-virtualenv
Version: 20.36.1
Release: 1%{?dist}
Release: 2%{?dist}
License: MIT
Vendor: Microsoft Corporation
Distribution: Azure Linux
Group: Development/Languages/Python
URL: https://pypi.python.org/pypi/virtualenv
Source0: https://files.pythonhosted.org/packages/aa/a3/4d310fa5f00863544e1d0f4de93bddec248499ccf97d4791bc3122c9d4f3/virtualenv-20.36.1.tar.gz
Patch0: 0001-replace-to-flit.patch
Patch1000: CVE-2025-50181.patch
Patch1001: CVE-2026-1703v0.patch
Patch1002: CVE-2026-1703v1.patch
Patch1003: CVE-2026-24049v0.patch
Patch1004: CVE-2026-24049v1.patch
BuildArch: noarch

%description
Expand All @@ -20,6 +25,7 @@ BuildRequires: python3-devel
BuildRequires: python3-setuptools_scm
BuildRequires: python3-xml
BuildRequires: python3-wheel
BuildRequires: zip

%if 0%{?with_check}
BuildRequires: python3-pip
Expand All @@ -37,7 +43,77 @@ Provides: %{name}-doc = %{version}-%{release}
virtualenv is a tool to create isolated Python environment.

%prep
%autosetup -p1 -n virtualenv-%{version}
# Adding -N to enable manual patching, needed for CVE-2025-50181
%autosetup -p1 -n virtualenv-%{version} -N
%patch -P 0 -p1

# Manual patching for CVE-2025-50181 and CVE-2026-1703v0
# For CVE-2025-50181, poolmanager.py file is located in 2 different places and each is of different version so the same patch cannot be applied to all of them.
# For CVE-2026-1703, unpacking.py file is located in 2 different places and each is of different version so the same patch cannot be applied to all of them.
# Affected files are under src and archived inside a .whl file, so we need to unpack it, apply the patch, and then re-zip it.

echo "Manually Patching virtualenv-20.36.1/src/virtualenv/seed/wheels/embed/pip-25.0.1-py3-none-any.whl/pip/_vendor/urllib3/poolmanager.py"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please add a note above each of this to clarify what patch. Also a comment so that we can justify why we are duplicating code, as the two parts alsmost are similar.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Affected code is present in archive(.whl) files in source tarball and even though patch is same for diffrent archives, same patch is not applicable for affected archives due to different versions. So same procedure is repeated for different archives.

mkdir -p unpacked_pip-25.0.1-py3-none-any
unzip src/virtualenv/seed/wheels/embed/pip-25.0.1-py3-none-any.whl -d unpacked_pip-25.0.1-py3-none-any
patch -p1 -d unpacked_pip-25.0.1-py3-none-any < %{PATCH1000}
echo "Manually Patching virtualenv-20.36.1/src/virtualenv/seed/wheels/embed/pip-25.0.1-py3-none-any.whl/pip/_internal/utils/unpacking.py"
patch -p1 -d unpacked_pip-25.0.1-py3-none-any < %{PATCH1001}
# Remove the original file
rm -f src/virtualenv/seed/wheels/embed/pip-25.0.1-py3-none-any.whl
# After patching, re-zip the contents back into a .whl
pushd unpacked_pip-25.0.1-py3-none-any
zip -r ../src/virtualenv/seed/wheels/embed/pip-25.0.1-py3-none-any.whl *
popd
rm -rf unpacked_pip-25.0.1-py3-none-any

# Manual patching for CVE-2025-50181 and CVE-2026-1703v1
echo "Manually Patching virtualenv-20.36.1/src/virtualenv/seed/wheels/embed/pip-25.3-py3-none-any.whl/pip/_vendor/urllib3/poolmanager.py"
mkdir -p unpacked_pip-25.3-py3-none-any
unzip src/virtualenv/seed/wheels/embed/pip-25.3-py3-none-any.whl -d unpacked_pip-25.3-py3-none-any
patch -p1 -d unpacked_pip-25.3-py3-none-any < %{PATCH1000}
echo "Manually Patching virtualenv-20.36.1/src/virtualenv/seed/wheels/embed/pip-25.3-py3-none-any.whl/pip/_internal/utils/unpacking.py"
patch -p1 -d unpacked_pip-25.3-py3-none-any < %{PATCH1002}
rm -f src/virtualenv/seed/wheels/embed/pip-25.3-py3-none-any.whl
pushd unpacked_pip-25.3-py3-none-any
zip -r ../src/virtualenv/seed/wheels/embed/pip-25.3-py3-none-any.whl *
popd
rm -rf unpacked_pip-25.3-py3-none-any

# Manual patching for CVE-2026-24049v0
# For CVE-2026-24049, unpack.py file is located in 3 different places and each is of different version so the same patch cannot be applied to all of them.
# Affected files are under src and archived inside a .whl file, so we need to unpack it, apply the patch, and then re-zip it.
echo "Manually Patching virtualenv-20.36.1/src/virtualenv/seed/wheels/embed/setuptools-75.3.2-py3-none-any.whl/setuptools/_vendor/wheel/cli/unpack.py"
mkdir -p unpacked_setuptools-75.3.2-py3-none-any
unzip src/virtualenv/seed/wheels/embed/setuptools-75.3.2-py3-none-any.whl -d unpacked_setuptools-75.3.2-py3-none-any
patch -p1 -d unpacked_setuptools-75.3.2-py3-none-any < %{PATCH1003}
rm -f src/virtualenv/seed/wheels/embed/setuptools-75.3.2-py3-none-any.whl
pushd unpacked_setuptools-75.3.2-py3-none-any
zip -r ../src/virtualenv/seed/wheels/embed/setuptools-75.3.2-py3-none-any.whl *
popd
rm -rf unpacked_setuptools-75.3.2-py3-none-any

# Manual patching for CVE-2026-24049v0
echo "Manually Patching virtualenv-20.36.1/src/virtualenv/seed/wheels/embed/setuptools-80.9.0-py3-none-any.whl/setuptools/_vendor/wheel/cli/unpack.py"
mkdir -p unpacked_setuptools-80.9.0-py3-none-any
unzip src/virtualenv/seed/wheels/embed/setuptools-80.9.0-py3-none-any.whl -d unpacked_setuptools-80.9.0-py3-none-any
patch -p1 -d unpacked_setuptools-80.9.0-py3-none-any < %{PATCH1003}
rm -f src/virtualenv/seed/wheels/embed/setuptools-80.9.0-py3-none-any.whl
pushd unpacked_setuptools-80.9.0-py3-none-any
zip -r ../src/virtualenv/seed/wheels/embed/setuptools-80.9.0-py3-none-any.whl *
popd
rm -rf unpacked_setuptools-80.9.0-py3-none-any

# Manual patching for CVE-2026-24049v1
echo "Manually Patching virtualenv-20.36.1/src/virtualenv/seed/wheels/embed/unpacked_wheel-0.45.1-py3-none-any.whl/wheel/cli/unpack.py"
mkdir -p unpacked_wheel-0.45.1-py3-none-any
unzip src/virtualenv/seed/wheels/embed/wheel-0.45.1-py3-none-any.whl -d unpacked_wheel-0.45.1-py3-none-any
patch -p1 -d unpacked_wheel-0.45.1-py3-none-any < %{PATCH1004}
rm -f src/virtualenv/seed/wheels/embed/wheel-0.45.1-py3-none-any.whl
pushd unpacked_wheel-0.45.1-py3-none-any
zip -r ../src/virtualenv/seed/wheels/embed/unpacked_wheel-0.45.1-py3-none-any.whl *
popd
rm -rf unpacked_wheel-0.45.1-py3-none-any


%generate_buildrequires

Expand All @@ -60,6 +136,9 @@ tox -e py
%{_bindir}/virtualenv

%changelog
* Mon Feb 23 2026 BinduSri Adabala <v-badabala@microsoft.com> - 20.36.1-2
- Patch for CVE-2025-50181, CVE-2026-24049 and CVE-2026-1703

* Wed Jan 14 2026 Archana Shettigar <v-shettigara@microsoft.com> - 20.36.1-1
- Upgrade to 20.36.1 for CVE-2026-22702

Expand Down
Loading