From f3146351e445165521707f217f0f3fb30834e946 Mon Sep 17 00:00:00 2001 From: Toshaan Bharvani Date: Fri, 18 Oct 2024 12:45:14 +0200 Subject: [PATCH] initial package creation Signed-off-by: Toshaan Bharvani --- SOURCES/CVE-2024-6345.patch | 163 ++++++++++ ...ove-optional-or-unpackaged-test-deps.patch | 45 +++ SPECS/python3.11-setuptools.spec | 279 ++++++++++++++++++ 3 files changed, 487 insertions(+) create mode 100644 SOURCES/CVE-2024-6345.patch create mode 100644 SOURCES/Remove-optional-or-unpackaged-test-deps.patch create mode 100644 SPECS/python3.11-setuptools.spec diff --git a/SOURCES/CVE-2024-6345.patch b/SOURCES/CVE-2024-6345.patch new file mode 100644 index 0000000..9a4406b --- /dev/null +++ b/SOURCES/CVE-2024-6345.patch @@ -0,0 +1,163 @@ +From 064c5a14690725a71565da63ccb688c0a63a6f57 Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Wed, 24 Jul 2024 14:15:57 +0200 +Subject: [PATCH] CVE-2024-6345 + +--- + setuptools/package_index.py | 29 +++++++++------------------ + setuptools/tests/test_packageindex.py | 28 +++++++++++++------------- + 2 files changed, 23 insertions(+), 34 deletions(-) + +diff --git a/setuptools/package_index.py b/setuptools/package_index.py +index 362e26f..dfc591b 100644 +--- a/setuptools/package_index.py ++++ b/setuptools/package_index.py +@@ -1,5 +1,6 @@ + """PyPI and direct package downloading.""" + ++import subprocess + import sys + import os + import re +@@ -874,7 +875,7 @@ class PackageIndex(Environment): + def _download_svn(self, url, filename): + warnings.warn("SVN download support is deprecated", UserWarning) + url = url.split('#', 1)[0] # remove any fragment for svn's sake +- creds = '' ++ creds = [] + if url.lower().startswith('svn:') and '@' in url: + scheme, netloc, path, p, q, f = urllib.parse.urlparse(url) + if not netloc and path.startswith('//') and '/' in path[2:]: +@@ -883,14 +884,14 @@ class PackageIndex(Environment): + if auth: + if ':' in auth: + user, pw = auth.split(':', 1) +- creds = " --username=%s --password=%s" % (user, pw) ++ creds = [f"--username={user}", f"--password={pw}"] + else: +- creds = " --username=" + auth ++ creds = [f"--username={auth}"] + netloc = host + parts = scheme, netloc, url, p, q, f + url = urllib.parse.urlunparse(parts) + self.info("Doing subversion checkout from %s to %s", url, filename) +- os.system("svn checkout%s -q %s %s" % (creds, url, filename)) ++ subprocess.check_call(["svn", "checkout"] + creds + ["-q", url, filename]) + return filename + + @staticmethod +@@ -916,17 +917,11 @@ class PackageIndex(Environment): + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + + self.info("Doing git clone from %s to %s", url, filename) +- os.system("git clone --quiet %s %s" % (url, filename)) ++ subprocess.check_call(["git", "clone", "--quiet", url, filename]) + + if rev is not None: + self.info("Checking out %s", rev) +- os.system( +- "git -C %s checkout --quiet %s" +- % ( +- filename, +- rev, +- ) +- ) ++ subprocess.check_call(["git", "-C", filename, "checkout", "--quiet", rev]) + + return filename + +@@ -935,17 +930,11 @@ class PackageIndex(Environment): + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + + self.info("Doing hg clone from %s to %s", url, filename) +- os.system("hg clone --quiet %s %s" % (url, filename)) ++ subprocess.check_call(["hg", "clone", "--quiet", url, filename]) + + if rev is not None: + self.info("Updating to %s", rev) +- os.system( +- "hg --cwd %s up -C -r %s -q" +- % ( +- filename, +- rev, +- ) +- ) ++ subprocess.check_call(["hg", "--cwd", filename, "up", "-C", "-r", rev, "-q"]) + + return filename + +diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py +index 7b0bf11..cf24def 100644 +--- a/setuptools/tests/test_packageindex.py ++++ b/setuptools/tests/test_packageindex.py +@@ -190,53 +190,53 @@ class TestPackageIndex: + url = 'git+https://github.example/group/project@master#egg=foo' + index = setuptools.package_index.PackageIndex() + +- with mock.patch("os.system") as os_system_mock: ++ with mock.patch("subprocess.check_call") as subprocess_check_call_mock: + result = index.download(url, str(tmpdir)) + +- os_system_mock.assert_called() ++ subprocess_check_call_mock.assert_called() + + expected_dir = str(tmpdir / 'project@master') + expected = ( + 'git clone --quiet ' 'https://github.example/group/project {expected_dir}' +- ).format(**locals()) +- first_call_args = os_system_mock.call_args_list[0][0] ++ ).format(**locals()).split() ++ first_call_args = subprocess_check_call_mock.call_args_list[0][0] + assert first_call_args == (expected,) + + tmpl = 'git -C {expected_dir} checkout --quiet master' +- expected = tmpl.format(**locals()) +- assert os_system_mock.call_args_list[1][0] == (expected,) ++ expected = tmpl.format(**locals()).split() ++ assert subprocess_check_call_mock.call_args_list[1][0] == (expected,) + assert result == expected_dir + + def test_download_git_no_rev(self, tmpdir): + url = 'git+https://github.example/group/project#egg=foo' + index = setuptools.package_index.PackageIndex() + +- with mock.patch("os.system") as os_system_mock: ++ with mock.patch("subprocess.check_call") as subprocess_check_call_mock: + result = index.download(url, str(tmpdir)) + +- os_system_mock.assert_called() ++ subprocess_check_call_mock.assert_called() + + expected_dir = str(tmpdir / 'project') + expected = ( + 'git clone --quiet ' 'https://github.example/group/project {expected_dir}' +- ).format(**locals()) +- os_system_mock.assert_called_once_with(expected) ++ ).format(**locals()).split() ++ subprocess_check_call_mock.assert_called_once_with(expected) + + def test_download_svn(self, tmpdir): + url = 'svn+https://svn.example/project#egg=foo' + index = setuptools.package_index.PackageIndex() + + with pytest.warns(UserWarning): +- with mock.patch("os.system") as os_system_mock: ++ with mock.patch("subprocess.check_call") as subprocess_check_call_mock: + result = index.download(url, str(tmpdir)) + +- os_system_mock.assert_called() ++ subprocess_check_call_mock.assert_called() + + expected_dir = str(tmpdir / 'project') + expected = ( + 'svn checkout -q ' 'svn+https://svn.example/project {expected_dir}' +- ).format(**locals()) +- os_system_mock.assert_called_once_with(expected) ++ ).format(**locals()).split() ++ subprocess_check_call_mock.assert_called_once_with(expected) + + + class TestContentCheckers: +-- +2.45.2 + diff --git a/SOURCES/Remove-optional-or-unpackaged-test-deps.patch b/SOURCES/Remove-optional-or-unpackaged-test-deps.patch new file mode 100644 index 0000000..247a193 --- /dev/null +++ b/SOURCES/Remove-optional-or-unpackaged-test-deps.patch @@ -0,0 +1,45 @@ +From 87a18ba242ac7f02d41b877ffc796dde42e6a93e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= +Date: Wed, 10 Aug 2022 16:08:41 +0200 +Subject: [PATCH] Remove optional or unpackaged test deps + +--- + setup.cfg | 14 -------------- + 1 file changed, 14 deletions(-) + +diff --git a/setup.cfg b/setup.cfg +index b4ee876..094f621 100644 +--- a/setup.cfg ++++ b/setup.cfg +@@ -39,19 +39,7 @@ exclude = + [options.extras_require] + testing = + pytest >= 6 +- pytest-checkdocs >= 2.4 +- pytest-flake8 +- flake8 < 5 +- pytest-black >= 0.3.7; \ +- python_implementation != "PyPy" +- pytest-cov; \ +- python_implementation != "PyPy" +- pytest-mypy >= 0.9.1; \ +- python_implementation != "PyPy" +- pytest-enabler >= 1.3 +- pytest-perf + +- flake8-2020 + virtualenv>=13.0.0 + wheel + pip>=19.1 # For proper file:// URLs support. +@@ -59,8 +47,6 @@ testing = + pytest-xdist + jaraco.path>=3.2.0 + build[virtualenv] +- filelock>=3.4.0 +- pip_run>=8.8 + ini2toml[lite]>=0.9 + tomli-w>=1.0.0 + pytest-timeout +-- +2.37.3 + diff --git a/SPECS/python3.11-setuptools.spec b/SPECS/python3.11-setuptools.spec new file mode 100644 index 0000000..a3f8c5d --- /dev/null +++ b/SPECS/python3.11-setuptools.spec @@ -0,0 +1,279 @@ +%global __python3 /usr/bin/python3.11 +%global python3_pkgversion 3.11 + +%global srcname setuptools + +# Some dependencies are missing on RHEL +%bcond_with tests + +# WARNING When bootstrapping, disable tests as well, +# because tests need pip. +%bcond_with bootstrap +# Similar to what we have in pythonX.Y.spec files. +# If enabled, provides unversioned executables and other stuff. + + +%if %{without bootstrap} +%global python_wheel_name %{srcname}-%{version}-py3-none-any.whl +%global python3_record %{python3_sitelib}/%{srcname}-%{version}.dist-info/RECORD +%endif + +Name: python%{python3_pkgversion}-setuptools +# When updating, update the bundled libraries versions bellow! +Version: 65.5.1 +Release: 2%{?dist}.1 +Summary: Easily build and distribute Python packages +# setuptools is MIT +# appdirs is MIT +# more-itertools is MIT +# ordered-set is MIT +# packaging is BSD or ASL 2.0 +# pyparsing is MIT +# importlib-metadata is ASL 2.0 +# importlib-resources is ASL 2.0 +# jaraco.text is MIT +# typing-extensions is Python +# zipp is MIT +# nspektr is MIT +# tomli is MIT +# the setuptools logo is MIT +License: MIT and ASL 2.0 and (BSD or ASL 2.0) and Python +URL: https://pypi.python.org/pypi/%{srcname} +Source0: %{pypi_source %{srcname} %{version}} + +# Some test deps are optional and either not desired or not available in Fedora, thus this patch removes them. +Patch0: Remove-optional-or-unpackaged-test-deps.patch + +# Security fix for CVE-2024-6345 +# Remote code execution via download functions in the package_index module +# Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=2297771 +# Upstream solution: https://github.com/pypa/setuptools/pull/4332 +# Patch simplified because upstream doesn't support SVN anymore. +Patch1: CVE-2024-6345.patch + +BuildArch: noarch + +BuildRequires: python%{python3_pkgversion}-devel +BuildRequires: python%{python3_pkgversion}-rpm-macros +%if %{with tests} +BuildRequires: gcc +BuildRequires: python%{python3_pkgversion}-pip +BuildRequires: python%{python3_pkgversion}-pytest +BuildRequires: python%{python3_pkgversion}-pytest-xdist +BuildRequires: python%{python3_pkgversion}-pytest-virtualenv +BuildRequires: python%{python3_pkgversion}-jaraco-envs +BuildRequires: python%{python3_pkgversion}-jaraco-path +BuildRequires: python%{python3_pkgversion}-virtualenv +BuildRequires: python%{python3_pkgversion}-wheel +BuildRequires: python%{python3_pkgversion}-build +BuildRequires: python%{python3_pkgversion}-ini2toml +BuildRequires: python%{python3_pkgversion}-tomli-w +%endif # with tests +%if %{without bootstrap} +# Not to use the pre-generated egg-info, we use setuptools from previous build to generate it +BuildRequires: python%{python3_pkgversion}-pip +BuildRequires: python%{python3_pkgversion}-wheel +BuildRequires: python%{python3_pkgversion}-setuptools +# python3 bootstrap: this is built before the final build of python3, which +# adds the dependency on python3-rpm-generators, so we require it manually +BuildRequires: python3-rpm-generators +%endif # without bootstrap + +# Virtual provides for the packages bundled by setuptools. +# Bundled packages are defined in two files: +# - pkg_resources/_vendor/vendored.txt, and +# - setuptools/_vendor/vendored.txt +# Merge them to one and then generate the list with: +# %%{_rpmconfigdir}/pythonbundles.py --namespace 'python%%{python3_pkgversion}dist' allvendor.txt +%global bundled %{expand: +Provides: bundled(python%{python3_pkgversion}dist(appdirs)) = 1.4.3 +Provides: bundled(python%{python3_pkgversion}dist(importlib-metadata)) = 4.11.1 +Provides: bundled(python%{python3_pkgversion}dist(importlib-resources)) = 5.4 +Provides: bundled(python%{python3_pkgversion}dist(jaraco-text)) = 3.7 +Provides: bundled(python%{python3_pkgversion}dist(more-itertools)) = 8.8 +Provides: bundled(python%{python3_pkgversion}dist(ordered-set)) = 3.1.1 +Provides: bundled(python%{python3_pkgversion}dist(packaging)) = 21.3 +Provides: bundled(python%{python3_pkgversion}dist(pyparsing)) = 3.0.9 +Provides: bundled(python%{python3_pkgversion}dist(typing-extensions)) = 4.0.1 +Provides: bundled(python%{python3_pkgversion}dist(zipp)) = 3.7 +Provides: bundled(python%{python3_pkgversion}dist(tomli)) = 2.0.1 +} + +%{bundled} + +# For users who might see ModuleNotFoundError: No module named 'pkg_resources' +# NB: Those are two different provides: one contains underscore, the other hyphen +%py_provides python%{python3_pkgversion}-pkg_resources +%py_provides python%{python3_pkgversion}-pkg-resources + +%description +Setuptools is a collection of enhancements to the Python 3 distutils that allow +you to more easily build and distribute Python 3 packages, especially ones that +have dependencies on other packages. + +This package also contains the runtime components of setuptools, necessary to +execute the software that requires pkg_resources. + +%if %{without bootstrap} +%package -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +Summary: The setuptools wheel +%{bundled} + +%description -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +A Python wheel of setuptools to use with venv. +%endif + + +%prep +%autosetup -p1 -n %{srcname}-%{version} +%if %{without bootstrap} +# If we don't have setuptools installed yet, we use the pre-generated .egg-info +# See https://github.com/pypa/setuptools/pull/2543 +# And https://github.com/pypa/setuptools/issues/2550 +# WARNING: We cannot remove this folder since Python 3.11.1, +# see https://github.com/pypa/setuptools/issues/3761 +#rm -r %%{srcname}.egg-info +%endif + +# Strip shbang +find setuptools pkg_resources -name \*.py | xargs sed -i -e '1 {/^#!\//d}' +# Remove bundled exes +rm -f setuptools/*.exe +# Don't ship these +rm -r docs/conf.py + + +%build +%if %{without bootstrap} +%py3_build_wheel +%else +%py3_build +%endif + + +%install +%if %{without bootstrap} +%py3_install_wheel %{python_wheel_name} +%else +%py3_install +%endif + +# https://github.com/pypa/setuptools/issues/2709 +rm -rf %{buildroot}%{python3_sitelib}/pkg_resources/tests/ + +%if %{without bootstrap} +sed -i '/^setuptools\/tests\//d' %{buildroot}%{python3_record} +%endif + +find %{buildroot}%{python3_sitelib} -name '*.exe' | xargs rm -f + +%if %{without bootstrap} +mkdir -p %{buildroot}%{python_wheel_dir} +install -p dist/%{python_wheel_name} -t %{buildroot}%{python_wheel_dir} +%endif + +%check + +# Regression tests + +#%%if 0%{?rhel} >= 9 +# The test cannot run on RHEL8 due to the test script missing from RPM. +# Verify bundled provides are up to date +# Disable the test for now as it requires python3-setuptools which is not included in the +# minimal set of packages. +#cat pkg_resources/_vendor/vendored.txt setuptools/_vendor/vendored.txt > allvendor.txt +#%%{_rpmconfigdir}/pythonbundles.py allvendor.txt --namespace 'python%{python3_pkgversion}dist' --compare-with '%%{bundled}' +#%%endif + +%if %{without bootstrap} +# Regression test, the wheel should not be larger than 900 kB +# https://bugzilla.redhat.com/show_bug.cgi?id=1914481#c3 +test $(stat --format %%s dist/%{python_wheel_name}) -lt 900000 +%endif + +# Regression test, the tests are not supposed to be installed +test ! -d %{buildroot}%{python3_sitelib}/pkg_resources/tests +test ! -d %{buildroot}%{python3_sitelib}/setuptools/tests + +# https://github.com/pypa/setuptools/discussions/2607 +rm pyproject.toml + +# Upstream test suite + +%if %{with tests} +# Upstream tests +# --ignore=setuptools/tests/test_integration.py +# --ignore=setuptools/tests/integration/ +# --ignore=setuptools/tests/config/test_apply_pyprojecttoml.py +# -k "not test_pip_upgrade_from_source" +# the tests require internet connection +# --ignore=setuptools/tests/test_editable_install.py +# the tests require pip-run which we don't have in Fedora +PRE_BUILT_SETUPTOOLS_WHEEL=dist/%{python_wheel_name} \ +PYTHONPATH=$(pwd) %pytest \ + --ignore=setuptools/tests/test_integration.py \ + --ignore=setuptools/tests/integration/ \ + --ignore=setuptools/tests/test_editable_install.py \ + --ignore=setuptools/tests/config/test_apply_pyprojecttoml.py \ + -k "not test_pip_upgrade_from_source" +%endif # with tests + + +%files -n python%{python3_pkgversion}-setuptools +%license LICENSE +%doc docs/* CHANGES.rst README.rst +%{python3_sitelib}/distutils-precedence.pth +%{python3_sitelib}/pkg_resources/ +%{python3_sitelib}/setuptools*/ +%{python3_sitelib}/_distutils_hack/ + +%if %{without bootstrap} +%files -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +%license LICENSE +# we own the dir for simplicity +%dir %{python_wheel_dir}/ +%{python_wheel_dir}/%{python_wheel_name} +%endif + + +%changelog +* Wed Jul 24 2024 Lumír Balhar - 65.5.1-2.1 +- Security fix for CVE-2024-6345 +Resolves: RHEL-50490 + +* Mon Jan 30 2023 Charalampos Stratakis - 65.5.1-2 +- Disable bootstrap + +* Wed Oct 12 2022 Charalampos Stratakis - 65.5.1-1 +- Initial package +- Fedora contributions by: + Bill Nottingham + Charalampos Stratakis + David Malcolm + Dennis Gilmore + dmalcolm + Haikel Guemar + Ignacio Vazquez-Abrams + Jesse Keating + Karolina Surma + Kevin Fenzi + Konstantin Ryabitsev + Lumir Balhar + Matej Stuchlik + Michal Cyprian + Miro Hrončok + Nils Philippsen + Orion Poplawski + Petr Viktorin + Pierre-Yves Chibon + Ralph Bean + Randy Barlow + Robert Kuska + Thomas Spura + Tomáš Hrnčiar + Tomas Orsava + Tomas Radej + tomspur + Toshio Kuratomi + Troy Dawson + Ville Skyttä