From 22a088e59347d7f5560557917e2d50fa826ffbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 8 Jun 2021 16:13:56 +0200 Subject: [PATCH 01/89] Fedora CI: This is not the main Python now --- tests/tests.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/tests.yml b/tests/tests.yml index c2d5a6f..8f5bf4b 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -19,18 +19,9 @@ - smoke: dir: python/smoke run: VERSION=3.9 ./venv.sh - - debugsmoke: - dir: python/smoke - run: PYTHON=python3-debug TOX=false VERSION=3.9 ./venv.sh - selftest: dir: python/selftest run: VERSION=3.9 X="-x test_wsgiref" ./parallel.sh - - debugtest: - dir: python/selftest - run: VERSION=3.9 PYTHON=python3-debug X="-x test_wsgiref" ./parallel.sh - - debugflags: - dir: python/flags - run: python3-debug ./assertflags.py -O0 - marshalparser: dir: python/marshalparser run: VERSION=3.9 SAMPLE=10 test_marshalparser_compatibility.sh @@ -38,10 +29,6 @@ - gcc # for extension building in venv and selftest - gdb # for test_gdb - python3.9 # the test subject - - python3-debug # for leak testing - - python3-devel # for extension building in venv and selftest - - python3-tkinter # for selftest - - python3-test # for selftest - python3-tox # for venv tests - glibc-all-langpacks # for locale tests - marshalparser # for testing compatibility (magic numbers) with marshalparser From a83376a2bd813393d16ccd75c05fc5459d67afab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 9 Jun 2021 15:02:07 +0200 Subject: [PATCH 02/89] Fedora CI: Add rpm -qa output for debugging --- tests/tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/tests.yml b/tests/tests.yml index 8f5bf4b..027091f 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -16,6 +16,8 @@ - repo: "https://src.fedoraproject.org/tests/python.git" dest: "python" tests: + - rpm_qa: + run: rpm -qa - smoke: dir: python/smoke run: VERSION=3.9 ./venv.sh @@ -32,3 +34,4 @@ - python3-tox # for venv tests - glibc-all-langpacks # for locale tests - marshalparser # for testing compatibility (magic numbers) with marshalparser + - rpm # for debugging From b5d38aa8d9e95bd03b01cd5cad25366324c7084c Mon Sep 17 00:00:00 2001 From: Tomas Hrnciar Date: Tue, 29 Jun 2021 08:07:05 +0200 Subject: [PATCH 03/89] Update to 3.9.6 --- 00111-no-static-lib.patch | 2 +- 00189-use-rpm-wheels.patch | 4 ++-- 00353-architecture-names-upstream-downstream.patch | 2 +- python3.9.spec | 11 +++++++---- sources | 4 ++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index b44dbc9..4693bbe 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 0c3981c132..5587422ec7 100644 +index 2b68571031..c57fc9693a 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -589,7 +589,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 608d265..87358d9 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 57e576d1a3..5bd16a6c59 100644 +index 14a39037e0..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -36,7 +36,7 @@ index 57e576d1a3..5bd16a6c59 100644 -_SETUPTOOLS_VERSION = "56.0.0" +_wheels = {} --_PIP_VERSION = "21.1.1" +-_PIP_VERSION = "21.1.3" +def _get_most_recent_wheel_version(pkg): + prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) + _wheels[pkg] = {} diff --git a/00353-architecture-names-upstream-downstream.patch b/00353-architecture-names-upstream-downstream.patch index 5e98140..578e786 100644 --- a/00353-architecture-names-upstream-downstream.patch +++ b/00353-architecture-names-upstream-downstream.patch @@ -34,7 +34,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py -index 7c4157369d..c3b95638a6 100644 +index fe31f437da..b5b70757f0 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1636,7 +1636,7 @@ def _get_supported_file_loaders(): diff --git a/python3.9.spec b/python3.9.spec index 9abe196..4551dc8 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.5 +%global general_version %{pybasever}.6 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # 4cb983ce1c5ef32068ca9349203a6f1ef9667451 +# 00189 # 4242864a6a12f1f4cf9fd63a6699a73f35261aa3 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,7 +317,7 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.1.1 +%global pip_version 21.1.3 %global setuptools_version 56.0.0 # 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 @@ -1778,6 +1778,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Jun 29 2021 Tomas Hrnciar - 3.9.6-1 +- Update to 3.9.6 + * Tue Jun 01 2021 Python Maint - 3.9.5-3 - Rebuilt for Python 3.10 diff --git a/sources b/sources index 373c745..ca8aa55 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.5.tar.xz) = 7b581af1b3e73695f124ff6a3a960e22104153a5d920ca930c046f42ea313b1e7ec77e39876db2bf5d5da6d7412cb072ff8ae7814dda12c14f9da6c570fb0995 -SHA512 (Python-3.9.5.tar.xz.asc) = cfee8c161447544d6f18c3490b96ce12c8df5e9b143fca09734066f3606abe767cd7b4d05315c691f41c0e565d9585456774c10770ffe2ef7983a911bbcfdb83 +SHA512 (Python-3.9.6.tar.xz) = 01c529e3207738d8771caeb5ed6217e10745c21aa39832fe3185e1c87fdb6aedead97ce38dbb11e02d873654028bd8071c3f345c18452769520723284efe9dc1 +SHA512 (Python-3.9.6.tar.xz.asc) = 0673c8833f302c829bfde97453c52744f6aa99b4a72520f4cc384d4aa9d6ffd28a1407ceafb0a1ec4462b3aa74b656bf39c67872c4e6a131429ea58c47ad0ecc From 2b5ef05f9d2bbfcfa929d212c17843b488586213 Mon Sep 17 00:00:00 2001 From: Tomas Hrnciar Date: Tue, 29 Jun 2021 08:07:05 +0200 Subject: [PATCH 04/89] Update to 3.9.6 --- 00111-no-static-lib.patch | 2 +- 00189-use-rpm-wheels.patch | 4 ++-- 00353-architecture-names-upstream-downstream.patch | 2 +- python3.9.spec | 11 +++++++---- sources | 4 ++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index b44dbc9..4693bbe 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 0c3981c132..5587422ec7 100644 +index 2b68571031..c57fc9693a 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -589,7 +589,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 608d265..87358d9 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 57e576d1a3..5bd16a6c59 100644 +index 14a39037e0..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -36,7 +36,7 @@ index 57e576d1a3..5bd16a6c59 100644 -_SETUPTOOLS_VERSION = "56.0.0" +_wheels = {} --_PIP_VERSION = "21.1.1" +-_PIP_VERSION = "21.1.3" +def _get_most_recent_wheel_version(pkg): + prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) + _wheels[pkg] = {} diff --git a/00353-architecture-names-upstream-downstream.patch b/00353-architecture-names-upstream-downstream.patch index 5e98140..578e786 100644 --- a/00353-architecture-names-upstream-downstream.patch +++ b/00353-architecture-names-upstream-downstream.patch @@ -34,7 +34,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py -index 7c4157369d..c3b95638a6 100644 +index fe31f437da..b5b70757f0 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1636,7 +1636,7 @@ def _get_supported_file_loaders(): diff --git a/python3.9.spec b/python3.9.spec index 9abe196..4551dc8 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.5 +%global general_version %{pybasever}.6 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # 4cb983ce1c5ef32068ca9349203a6f1ef9667451 +# 00189 # 4242864a6a12f1f4cf9fd63a6699a73f35261aa3 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,7 +317,7 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.1.1 +%global pip_version 21.1.3 %global setuptools_version 56.0.0 # 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 @@ -1778,6 +1778,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Jun 29 2021 Tomas Hrnciar - 3.9.6-1 +- Update to 3.9.6 + * Tue Jun 01 2021 Python Maint - 3.9.5-3 - Rebuilt for Python 3.10 diff --git a/sources b/sources index 373c745..ca8aa55 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.5.tar.xz) = 7b581af1b3e73695f124ff6a3a960e22104153a5d920ca930c046f42ea313b1e7ec77e39876db2bf5d5da6d7412cb072ff8ae7814dda12c14f9da6c570fb0995 -SHA512 (Python-3.9.5.tar.xz.asc) = cfee8c161447544d6f18c3490b96ce12c8df5e9b143fca09734066f3606abe767cd7b4d05315c691f41c0e565d9585456774c10770ffe2ef7983a911bbcfdb83 +SHA512 (Python-3.9.6.tar.xz) = 01c529e3207738d8771caeb5ed6217e10745c21aa39832fe3185e1c87fdb6aedead97ce38dbb11e02d873654028bd8071c3f345c18452769520723284efe9dc1 +SHA512 (Python-3.9.6.tar.xz.asc) = 0673c8833f302c829bfde97453c52744f6aa99b4a72520f4cc384d4aa9d6ffd28a1407ceafb0a1ec4462b3aa74b656bf39c67872c4e6a131429ea58c47ad0ecc From aa536db3278d6e5d931e640216099fd4848dafbb Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 30 Jun 2021 12:50:32 +0200 Subject: [PATCH 05/89] Provide python3-turtle from python3-tkinter Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1952565 --- python3.9.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 4551dc8..6d2756e 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -633,6 +633,10 @@ configuration, browsers, and other dialogs. Summary: A GUI toolkit for Python Requires: %{pkgname} = %{version}-%{release} +# The importable module "turtle" is here, so provide python3-turtle. +# (We don't provide python3-turtledemo, that's not too useful when imported.) +%py_provides %{pkgname}-turtle + %description -n %{pkgname}-tkinter The Tkinter (Tk interface) library is a graphical user interface toolkit for the Python programming language. @@ -1778,6 +1782,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 16 2021 Petr Viktorin - 3.9.6-2 +- Provide python3-turtle from python3-tkinter + * Tue Jun 29 2021 Tomas Hrnciar - 3.9.6-1 - Update to 3.9.6 From 54ef9bd8ddf3686f7b0f821978a2448d389b3502 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 15 Jul 2021 10:58:21 +0200 Subject: [PATCH 06/89] Require pyproject-rpm-macros from python3-devel Part of the new Python packaging guidelines change: - https://fedoraproject.org/wiki/Changes/PythonPackagingGuidelines202x - https://bugzilla.redhat.com/show_bug.cgi?id=1977883 --- python3.9.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python3.9.spec b/python3.9.spec index 6d2756e..74aba3e 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -563,6 +563,7 @@ Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} # But we want them when packages BuildRequire python3-devel Requires: (python-rpm-macros if rpm-build) Requires: (python3-rpm-macros if rpm-build) +Requires: (pyproject-rpm-macros if rpm-build) %if %{without bootstrap} # This is not "API" (packages that need setuptools should still BuildRequire it) @@ -1784,6 +1785,7 @@ CheckPython optimized %changelog * Fri Jul 16 2021 Petr Viktorin - 3.9.6-2 - Provide python3-turtle from python3-tkinter +- Require pyproject-rpm-macros from python3-devel * Tue Jun 29 2021 Tomas Hrnciar - 3.9.6-1 - Update to 3.9.6 From f4a64b51fdb45014f81536c69281b86242ebd06c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 30 Jun 2021 12:50:32 +0200 Subject: [PATCH 07/89] Provide python3-turtle from python3-tkinter Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1952565 --- python3.9.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 4551dc8..6d2756e 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -633,6 +633,10 @@ configuration, browsers, and other dialogs. Summary: A GUI toolkit for Python Requires: %{pkgname} = %{version}-%{release} +# The importable module "turtle" is here, so provide python3-turtle. +# (We don't provide python3-turtledemo, that's not too useful when imported.) +%py_provides %{pkgname}-turtle + %description -n %{pkgname}-tkinter The Tkinter (Tk interface) library is a graphical user interface toolkit for the Python programming language. @@ -1778,6 +1782,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 16 2021 Petr Viktorin - 3.9.6-2 +- Provide python3-turtle from python3-tkinter + * Tue Jun 29 2021 Tomas Hrnciar - 3.9.6-1 - Update to 3.9.6 From c3420255b1fe63ea26ce4794cc6637fc47b0d31a Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 15 Jul 2021 10:58:21 +0200 Subject: [PATCH 08/89] Require pyproject-rpm-macros from python3-devel Part of the new Python packaging guidelines change: - https://fedoraproject.org/wiki/Changes/PythonPackagingGuidelines202x - https://bugzilla.redhat.com/show_bug.cgi?id=1977883 --- python3.9.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python3.9.spec b/python3.9.spec index 6d2756e..74aba3e 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -563,6 +563,7 @@ Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} # But we want them when packages BuildRequire python3-devel Requires: (python-rpm-macros if rpm-build) Requires: (python3-rpm-macros if rpm-build) +Requires: (pyproject-rpm-macros if rpm-build) %if %{without bootstrap} # This is not "API" (packages that need setuptools should still BuildRequire it) @@ -1784,6 +1785,7 @@ CheckPython optimized %changelog * Fri Jul 16 2021 Petr Viktorin - 3.9.6-2 - Provide python3-turtle from python3-tkinter +- Require pyproject-rpm-macros from python3-devel * Tue Jun 29 2021 Tomas Hrnciar - 3.9.6-1 - Update to 3.9.6 From f60bd18051d76a51c13bd5722d1a1b4f04735df3 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 23 Jul 2021 10:32:23 +0000 Subject: [PATCH 09/89] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 74aba3e..ab0548b 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 23 2021 Fedora Release Engineering - 3.9.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Fri Jul 16 2021 Petr Viktorin - 3.9.6-2 - Provide python3-turtle from python3-tkinter - Require pyproject-rpm-macros from python3-devel From a43ee056fa4084e007e2fb206e4cf97b1373aff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 13 Aug 2021 01:12:28 +0200 Subject: [PATCH 10/89] Update description of the flat python3.9 package -- it is now older, not newer --- python3.9.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index ab0548b..0f88811 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -731,10 +731,10 @@ Requires: tzdata %description Python %{pybasever} package for developers. -This package exists to allow developers to test their code against a newer +This package exists to allow developers to test their code against an older version of Python. This is not a full Python stack and if you wish to run -your applications with Python %{pybasever}, update your Fedora to a newer -version once Python %{pybasever} is stable. +your applications with Python %{pybasever}, see other distributions +that support it, such as CentOS or RHEL or older Fedora releases. %endif # with flatpackage From 9d73093ec328195ccc8261e72b5e73180c838755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 31 Aug 2021 01:30:12 +0200 Subject: [PATCH 11/89] Update to 3.9.7 --- 00111-no-static-lib.patch | 2 +- 00189-use-rpm-wheels.patch | 6 +++--- python3.9.spec | 13 ++++++++----- sources | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 4693bbe..29a0a3d 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 2b68571031..c57fc9693a 100644 +index 6ce7a614dc..2cf3cb184e 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -589,7 +589,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 87358d9..665b5e3 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 14a39037e0..5bd16a6c59 100644 +index 7b03970c93..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -33,10 +33,10 @@ index 14a39037e0..5bd16a6c59 100644 +_WHEEL_DIR = "/usr/share/python-wheels/" --_SETUPTOOLS_VERSION = "56.0.0" +-_SETUPTOOLS_VERSION = "57.4.0" +_wheels = {} --_PIP_VERSION = "21.1.3" +-_PIP_VERSION = "21.2.3" +def _get_most_recent_wheel_version(pkg): + prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) + _wheels[pkg] = {} diff --git a/python3.9.spec b/python3.9.spec index 0f88811..adeb9f0 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.6 +%global general_version %{pybasever}.7 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # 4242864a6a12f1f4cf9fd63a6699a73f35261aa3 +# 00189 # ab9a031e2a429afce5c3e1777633d5305b956ea6 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,8 +317,8 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.1.3 -%global setuptools_version 56.0.0 +%global pip_version 21.2.3 +%global setuptools_version 57.4.0 # 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 # Change user install location @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Aug 30 2021 Miro Hrončok - 3.9.7-1 +- Update to 3.9.7 + * Fri Jul 23 2021 Fedora Release Engineering - 3.9.6-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild diff --git a/sources b/sources index ca8aa55..c0e8376 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.6.tar.xz) = 01c529e3207738d8771caeb5ed6217e10745c21aa39832fe3185e1c87fdb6aedead97ce38dbb11e02d873654028bd8071c3f345c18452769520723284efe9dc1 -SHA512 (Python-3.9.6.tar.xz.asc) = 0673c8833f302c829bfde97453c52744f6aa99b4a72520f4cc384d4aa9d6ffd28a1407ceafb0a1ec4462b3aa74b656bf39c67872c4e6a131429ea58c47ad0ecc +SHA512 (Python-3.9.7.tar.xz) = 55139776ab58a40f9e1e70613d7071d559ef9e51e32a77791422aac134322c21a49f0348c42813214b69789c589367eae43e16d4ae838a73daf37617e966b735 +SHA512 (Python-3.9.7.tar.xz.asc) = 7ff9f845f520efab3b4a0e95da3ffe055ee5777a4173a5b2cc1fd2419dc2b4faf30d1e711e372df36e34bc971ecfcde88a7cd815cfe2d8080ccb575a1ae8e101 From 115911c72ebb77fab4a1acd8f8f794d9c4ad150b Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 23 Jul 2021 10:32:23 +0000 Subject: [PATCH 12/89] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 74aba3e..ab0548b 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 23 2021 Fedora Release Engineering - 3.9.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Fri Jul 16 2021 Petr Viktorin - 3.9.6-2 - Provide python3-turtle from python3-tkinter - Require pyproject-rpm-macros from python3-devel From 21411c50a9009953c69bc3286c990ea6d6e3c877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 13 Aug 2021 01:12:28 +0200 Subject: [PATCH 13/89] Update description of the flat python3.9 package -- it is now older, not newer --- python3.9.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index ab0548b..0f88811 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -731,10 +731,10 @@ Requires: tzdata %description Python %{pybasever} package for developers. -This package exists to allow developers to test their code against a newer +This package exists to allow developers to test their code against an older version of Python. This is not a full Python stack and if you wish to run -your applications with Python %{pybasever}, update your Fedora to a newer -version once Python %{pybasever} is stable. +your applications with Python %{pybasever}, see other distributions +that support it, such as CentOS or RHEL or older Fedora releases. %endif # with flatpackage From 8020ec5862ff83f0c7de8eda12c7de463f5a9747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 31 Aug 2021 01:30:12 +0200 Subject: [PATCH 14/89] Update to 3.9.7 --- 00111-no-static-lib.patch | 2 +- 00189-use-rpm-wheels.patch | 6 +++--- python3.9.spec | 13 ++++++++----- sources | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 4693bbe..29a0a3d 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 2b68571031..c57fc9693a 100644 +index 6ce7a614dc..2cf3cb184e 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -589,7 +589,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 87358d9..665b5e3 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 14a39037e0..5bd16a6c59 100644 +index 7b03970c93..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -33,10 +33,10 @@ index 14a39037e0..5bd16a6c59 100644 +_WHEEL_DIR = "/usr/share/python-wheels/" --_SETUPTOOLS_VERSION = "56.0.0" +-_SETUPTOOLS_VERSION = "57.4.0" +_wheels = {} --_PIP_VERSION = "21.1.3" +-_PIP_VERSION = "21.2.3" +def _get_most_recent_wheel_version(pkg): + prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) + _wheels[pkg] = {} diff --git a/python3.9.spec b/python3.9.spec index 0f88811..adeb9f0 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.6 +%global general_version %{pybasever}.7 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # 4242864a6a12f1f4cf9fd63a6699a73f35261aa3 +# 00189 # ab9a031e2a429afce5c3e1777633d5305b956ea6 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,8 +317,8 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.1.3 -%global setuptools_version 56.0.0 +%global pip_version 21.2.3 +%global setuptools_version 57.4.0 # 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 # Change user install location @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Aug 30 2021 Miro Hrončok - 3.9.7-1 +- Update to 3.9.7 + * Fri Jul 23 2021 Fedora Release Engineering - 3.9.6-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild diff --git a/sources b/sources index ca8aa55..c0e8376 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.6.tar.xz) = 01c529e3207738d8771caeb5ed6217e10745c21aa39832fe3185e1c87fdb6aedead97ce38dbb11e02d873654028bd8071c3f345c18452769520723284efe9dc1 -SHA512 (Python-3.9.6.tar.xz.asc) = 0673c8833f302c829bfde97453c52744f6aa99b4a72520f4cc384d4aa9d6ffd28a1407ceafb0a1ec4462b3aa74b656bf39c67872c4e6a131429ea58c47ad0ecc +SHA512 (Python-3.9.7.tar.xz) = 55139776ab58a40f9e1e70613d7071d559ef9e51e32a77791422aac134322c21a49f0348c42813214b69789c589367eae43e16d4ae838a73daf37617e966b735 +SHA512 (Python-3.9.7.tar.xz.asc) = 7ff9f845f520efab3b4a0e95da3ffe055ee5777a4173a5b2cc1fd2419dc2b4faf30d1e711e372df36e34bc971ecfcde88a7cd815cfe2d8080ccb575a1ae8e101 From 010c643aae216e8abfd7f5306f0d39fb4aa7966e Mon Sep 17 00:00:00 2001 From: Sahana Prasad Date: Tue, 14 Sep 2021 19:12:46 +0200 Subject: [PATCH 15/89] Rebuilt with OpenSSL 3.0.0 --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index adeb9f0..cbf9cc3 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Sep 14 2021 Sahana Prasad - 3.9.7-2 +- Rebuilt with OpenSSL 3.0.0 + * Mon Aug 30 2021 Miro Hrončok - 3.9.7-1 - Update to 3.9.7 From dc16576a773369008d1792361f3e56ac755a55ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Mon, 8 Nov 2021 08:56:26 +0100 Subject: [PATCH 16/89] Update to 3.9.8 --- 00001-rpath.patch | 2 +- 00111-no-static-lib.patch | 10 +++++----- 00189-use-rpm-wheels.patch | 23 ++++++++++++----------- python3.9.spec | 13 ++++++++----- sources | 4 ++-- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/00001-rpath.patch b/00001-rpath.patch index 170908e..778c077 100644 --- a/00001-rpath.patch +++ b/00001-rpath.patch @@ -9,7 +9,7 @@ Subject: [PATCH] 00001: Fixup distutils/unixccompiler.py to remove standard 1 file changed, 9 insertions(+) diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py -index f0792de74a..4d837936c6 100644 +index d00c48981e..0283a28c19 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -82,6 +82,15 @@ class UnixCCompiler(CCompiler): diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 29a0a3d..390eed2 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,10 +21,10 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 6ce7a614dc..2cf3cb184e 100644 +index 11230fa563..dc763e7197 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in -@@ -589,7 +589,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c +@@ -588,7 +588,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) # Build the interpreter @@ -33,7 +33,7 @@ index 6ce7a614dc..2cf3cb184e 100644 $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) platform: $(BUILDPYTHON) pybuilddir.txt -@@ -637,12 +637,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o +@@ -636,12 +636,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build @@ -46,7 +46,7 @@ index 6ce7a614dc..2cf3cb184e 100644 libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACE_OBJS) if test $(INSTSONAME) != $(LDLIBRARY); then \ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM); \ -@@ -724,7 +718,7 @@ Makefile Modules/config.c: Makefile.pre \ +@@ -723,7 +717,7 @@ Makefile Modules/config.c: Makefile.pre \ @echo "The Makefile was updated, you may need to re-run make." @@ -55,7 +55,7 @@ index 6ce7a614dc..2cf3cb184e 100644 $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) ############################################################################ -@@ -1652,17 +1646,6 @@ libainstall: @DEF_MAKE_RULE@ python-config +@@ -1651,17 +1645,6 @@ libainstall: @DEF_MAKE_RULE@ python-config else true; \ fi; \ done diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 665b5e3..e5cf8f7 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -8,11 +8,11 @@ We keep them in /usr/share/python-wheels Downstream only: upstream bundles We might eventually pursuit upstream support, but it's low prio --- - Lib/ensurepip/__init__.py | 33 ++++++++++++++++++++++----------- - 1 file changed, 22 insertions(+), 11 deletions(-) + Lib/ensurepip/__init__.py | 37 ++++++++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 7b03970c93..5bd16a6c59 100644 +index 2a140a2624..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -21,7 +21,7 @@ index 7b03970c93..5bd16a6c59 100644 import os import os.path import sys -@@ -6,16 +8,28 @@ import tempfile +@@ -6,13 +8,29 @@ import tempfile import subprocess from importlib import resources @@ -30,13 +30,13 @@ index 7b03970c93..5bd16a6c59 100644 __all__ = ["version", "bootstrap"] - +-_SETUPTOOLS_VERSION = "58.1.0" +-_PIP_VERSION = "21.2.4" ++ +_WHEEL_DIR = "/usr/share/python-wheels/" - --_SETUPTOOLS_VERSION = "57.4.0" ++ +_wheels = {} - --_PIP_VERSION = "21.2.3" ++ +def _get_most_recent_wheel_version(pkg): + prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) + _wheels[pkg] = {} @@ -51,10 +51,11 @@ index 7b03970c93..5bd16a6c59 100644 +_SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools") + +_PIP_VERSION = _get_most_recent_wheel_version("pip") - ++ _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), -@@ -105,13 +119,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False, + ("pip", _PIP_VERSION, "py3"), +@@ -101,13 +119,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False, # additional paths that need added to sys.path additional_paths = [] for project, version, py_tag in _PROJECTS: diff --git a/python3.9.spec b/python3.9.spec index cbf9cc3..514e8a2 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.7 +%global general_version %{pybasever}.8 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # ab9a031e2a429afce5c3e1777633d5305b956ea6 +# 00189 # d06cf137c00fd3907b436fdb92a8f007a7f2fb50 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,8 +317,8 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.2.3 -%global setuptools_version 57.4.0 +%global pip_version 21.2.4 +%global setuptools_version 58.1.0 # 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 # Change user install location @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Nov 08 2021 Tomáš Hrnčiar - 3.9.8-1 +- Update to 3.9.8 + * Tue Sep 14 2021 Sahana Prasad - 3.9.7-2 - Rebuilt with OpenSSL 3.0.0 diff --git a/sources b/sources index c0e8376..59eae6d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.7.tar.xz) = 55139776ab58a40f9e1e70613d7071d559ef9e51e32a77791422aac134322c21a49f0348c42813214b69789c589367eae43e16d4ae838a73daf37617e966b735 -SHA512 (Python-3.9.7.tar.xz.asc) = 7ff9f845f520efab3b4a0e95da3ffe055ee5777a4173a5b2cc1fd2419dc2b4faf30d1e711e372df36e34bc971ecfcde88a7cd815cfe2d8080ccb575a1ae8e101 +SHA512 (Python-3.9.8.tar.xz) = 5d5b46a242525b2e6a7f9c69c63c6d7cd985e1443a7d9b716107e75f14fef7b5c9c2e5e8a90adbbbf5f7a8b90a483d01e18c1732470e6e54b611b5aba9f99fe1 +SHA512 (Python-3.9.8.tar.xz.asc) = 1329a8e114feb010bb3618472cddd9fdea59fc38e9583002eb457e1c0cf1716bd7c0d51887e91b9eef09c3977879aa4be9909e5997be7dfdcca08ca04794bfaf From 1e3497ed347335b88209808216689c3f3e3d4d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Mon, 8 Nov 2021 07:56:26 +0000 Subject: [PATCH 17/89] Update to 3.9.8 --- 00001-rpath.patch | 2 +- 00111-no-static-lib.patch | 10 +++++----- 00189-use-rpm-wheels.patch | 23 ++++++++++++----------- python3.9.spec | 5 ++++- sources | 4 ++-- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/00001-rpath.patch b/00001-rpath.patch index 170908e..778c077 100644 --- a/00001-rpath.patch +++ b/00001-rpath.patch @@ -9,7 +9,7 @@ Subject: [PATCH] 00001: Fixup distutils/unixccompiler.py to remove standard 1 file changed, 9 insertions(+) diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py -index f0792de74a..4d837936c6 100644 +index d00c48981e..0283a28c19 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -82,6 +82,15 @@ class UnixCCompiler(CCompiler): diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 29a0a3d..390eed2 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,10 +21,10 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 6ce7a614dc..2cf3cb184e 100644 +index 11230fa563..dc763e7197 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in -@@ -589,7 +589,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c +@@ -588,7 +588,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) # Build the interpreter @@ -33,7 +33,7 @@ index 6ce7a614dc..2cf3cb184e 100644 $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) platform: $(BUILDPYTHON) pybuilddir.txt -@@ -637,12 +637,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o +@@ -636,12 +636,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build @@ -46,7 +46,7 @@ index 6ce7a614dc..2cf3cb184e 100644 libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACE_OBJS) if test $(INSTSONAME) != $(LDLIBRARY); then \ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM); \ -@@ -724,7 +718,7 @@ Makefile Modules/config.c: Makefile.pre \ +@@ -723,7 +717,7 @@ Makefile Modules/config.c: Makefile.pre \ @echo "The Makefile was updated, you may need to re-run make." @@ -55,7 +55,7 @@ index 6ce7a614dc..2cf3cb184e 100644 $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) ############################################################################ -@@ -1652,17 +1646,6 @@ libainstall: @DEF_MAKE_RULE@ python-config +@@ -1651,17 +1645,6 @@ libainstall: @DEF_MAKE_RULE@ python-config else true; \ fi; \ done diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 665b5e3..e5cf8f7 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -8,11 +8,11 @@ We keep them in /usr/share/python-wheels Downstream only: upstream bundles We might eventually pursuit upstream support, but it's low prio --- - Lib/ensurepip/__init__.py | 33 ++++++++++++++++++++++----------- - 1 file changed, 22 insertions(+), 11 deletions(-) + Lib/ensurepip/__init__.py | 37 ++++++++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 7b03970c93..5bd16a6c59 100644 +index 2a140a2624..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -21,7 +21,7 @@ index 7b03970c93..5bd16a6c59 100644 import os import os.path import sys -@@ -6,16 +8,28 @@ import tempfile +@@ -6,13 +8,29 @@ import tempfile import subprocess from importlib import resources @@ -30,13 +30,13 @@ index 7b03970c93..5bd16a6c59 100644 __all__ = ["version", "bootstrap"] - +-_SETUPTOOLS_VERSION = "58.1.0" +-_PIP_VERSION = "21.2.4" ++ +_WHEEL_DIR = "/usr/share/python-wheels/" - --_SETUPTOOLS_VERSION = "57.4.0" ++ +_wheels = {} - --_PIP_VERSION = "21.2.3" ++ +def _get_most_recent_wheel_version(pkg): + prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) + _wheels[pkg] = {} @@ -51,10 +51,11 @@ index 7b03970c93..5bd16a6c59 100644 +_SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools") + +_PIP_VERSION = _get_most_recent_wheel_version("pip") - ++ _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), -@@ -105,13 +119,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False, + ("pip", _PIP_VERSION, "py3"), +@@ -101,13 +119,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False, # additional paths that need added to sys.path additional_paths = [] for project, version, py_tag in _PROJECTS: diff --git a/python3.9.spec b/python3.9.spec index adeb9f0..4c7e24f 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.7 +%global general_version %{pybasever}.8 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Nov 08 2021 Tomáš Hrnčiar - 3.9.8-1 +- Update to 3.9.8 + * Mon Aug 30 2021 Miro Hrončok - 3.9.7-1 - Update to 3.9.7 diff --git a/sources b/sources index c0e8376..59eae6d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.7.tar.xz) = 55139776ab58a40f9e1e70613d7071d559ef9e51e32a77791422aac134322c21a49f0348c42813214b69789c589367eae43e16d4ae838a73daf37617e966b735 -SHA512 (Python-3.9.7.tar.xz.asc) = 7ff9f845f520efab3b4a0e95da3ffe055ee5777a4173a5b2cc1fd2419dc2b4faf30d1e711e372df36e34bc971ecfcde88a7cd815cfe2d8080ccb575a1ae8e101 +SHA512 (Python-3.9.8.tar.xz) = 5d5b46a242525b2e6a7f9c69c63c6d7cd985e1443a7d9b716107e75f14fef7b5c9c2e5e8a90adbbbf5f7a8b90a483d01e18c1732470e6e54b611b5aba9f99fe1 +SHA512 (Python-3.9.8.tar.xz.asc) = 1329a8e114feb010bb3618472cddd9fdea59fc38e9583002eb457e1c0cf1716bd7c0d51887e91b9eef09c3977879aa4be9909e5997be7dfdcca08ca04794bfaf From 59f1238794eeddc5d984774225b505b7ac426b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Fri, 12 Nov 2021 22:26:58 +0100 Subject: [PATCH 18/89] Rebuild(libnsl2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 514e8a2..0cecaf9 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Nov 12 2021 Björn Esser - 3.9.8-2 +- Rebuild(libnsl2) + * Mon Nov 08 2021 Tomáš Hrnčiar - 3.9.8-1 - Update to 3.9.8 From 913221b8e27012ad263767ba6cc39ea4259d454d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Tue, 16 Nov 2021 14:01:30 +0100 Subject: [PATCH 19/89] Update to 3.9.9 --- python3.9.spec | 7 +++++-- sources | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 0cecaf9..a9b93fe 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.8 +%global general_version %{pybasever}.9 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Nov 16 2021 Tomáš Hrnčiar - 3.9.9-1 +- Update to 3.9.9 + * Fri Nov 12 2021 Björn Esser - 3.9.8-2 - Rebuild(libnsl2) diff --git a/sources b/sources index 59eae6d..d7b5371 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.8.tar.xz) = 5d5b46a242525b2e6a7f9c69c63c6d7cd985e1443a7d9b716107e75f14fef7b5c9c2e5e8a90adbbbf5f7a8b90a483d01e18c1732470e6e54b611b5aba9f99fe1 -SHA512 (Python-3.9.8.tar.xz.asc) = 1329a8e114feb010bb3618472cddd9fdea59fc38e9583002eb457e1c0cf1716bd7c0d51887e91b9eef09c3977879aa4be9909e5997be7dfdcca08ca04794bfaf +SHA512 (Python-3.9.9.tar.xz) = 0ab29fb9a7ecb808bd08d84d28908d5a934e0f021853da0f7a9c94670eb30c8dbbc233d461afdb3995b0de59275ef7e1de43e82d7f848802cbd6e6e50b7b25a6 +SHA512 (Python-3.9.9.tar.xz.asc) = 84fb739c60216ab9a7a487a0ec4039a7e85c7684ef1f71d8b3bc415ff2ae284f79474103ae05385502bc2510401f8cfb33d84dccf5d0ea9a0dd62528519d935f From ad3f146b58ae657c6b0b323ce98ebfbb983e979d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Thu, 18 Nov 2021 11:20:47 +0100 Subject: [PATCH 20/89] Update pip and setuptools to the latest bundled versions In previous commit, patch 00189 was updated to the latest bundled versions of pip and setuptools, but it was forgotten to update also versions in spec file. --- python3.9.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 4c7e24f..9d240f2 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # ab9a031e2a429afce5c3e1777633d5305b956ea6 +# 00189 # d06cf137c00fd3907b436fdb92a8f007a7f2fb50 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,8 +317,8 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.2.3 -%global setuptools_version 57.4.0 +%global pip_version 21.2.4 +%global setuptools_version 58.1.0 # 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 # Change user install location From 23a285e10f90a29fb0d97e60e91e4cfca5287c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Fri, 19 Nov 2021 08:41:46 +0100 Subject: [PATCH 21/89] Update to 3.9.9 --- python3.9.spec | 5 ++++- sources | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 9d240f2..365ca9d 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.8 +%global general_version %{pybasever}.9 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1783,6 +1783,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Nov 16 2021 Tomáš Hrnčiar - 3.9.9-1 +- Update to 3.9.9 + * Mon Nov 08 2021 Tomáš Hrnčiar - 3.9.8-1 - Update to 3.9.8 diff --git a/sources b/sources index 59eae6d..d7b5371 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.8.tar.xz) = 5d5b46a242525b2e6a7f9c69c63c6d7cd985e1443a7d9b716107e75f14fef7b5c9c2e5e8a90adbbbf5f7a8b90a483d01e18c1732470e6e54b611b5aba9f99fe1 -SHA512 (Python-3.9.8.tar.xz.asc) = 1329a8e114feb010bb3618472cddd9fdea59fc38e9583002eb457e1c0cf1716bd7c0d51887e91b9eef09c3977879aa4be9909e5997be7dfdcca08ca04794bfaf +SHA512 (Python-3.9.9.tar.xz) = 0ab29fb9a7ecb808bd08d84d28908d5a934e0f021853da0f7a9c94670eb30c8dbbc233d461afdb3995b0de59275ef7e1de43e82d7f848802cbd6e6e50b7b25a6 +SHA512 (Python-3.9.9.tar.xz.asc) = 84fb739c60216ab9a7a487a0ec4039a7e85c7684ef1f71d8b3bc415ff2ae284f79474103ae05385502bc2510401f8cfb33d84dccf5d0ea9a0dd62528519d935f From 3216989552a02fe62f794ff0e08bfbdb9861002e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Fri, 19 Nov 2021 14:12:25 +0100 Subject: [PATCH 22/89] Add patch to revert "bpo-1596321: Fix threading._shutdown() for the main thread" https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 https://github.com/GrahamDumpleton/mod_wsgi/issues/730 --- ...or-the-main-thread-gh-28549-gh-28589.patch | 103 ++++++++++++++++++ python3.9.spec | 16 ++- 2 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch new file mode 100644 index 0000000..015cb48 --- /dev/null +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= +Date: Fri, 19 Nov 2021 13:37:16 +0100 +Subject: [PATCH] 00371: Revert "bpo-1596321: Fix threading._shutdown() for the + main thread (GH-28549) (GH-28589)" + +This reverts commit 94d19f606fa18a1c4d2faca1caf2f470a8ce6d46. It +introduced regression causing FreeIPA's tests to fail. + +For more info see: +https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 +https://github.com/GrahamDumpleton/mod_wsgi/issues/730 +--- + Lib/test/test_threading.py | 33 --------------------------------- + Lib/threading.py | 25 ++++++++----------------- + 2 files changed, 8 insertions(+), 50 deletions(-) + +diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py +index af480b9014..a57085b75d 100644 +--- a/Lib/test/test_threading.py ++++ b/Lib/test/test_threading.py +@@ -814,39 +814,6 @@ class ThreadTests(BaseTestCase): + threading.Thread(target=noop).start() + # Thread.join() is not called + +- def test_import_from_another_thread(self): +- # bpo-1596321: If the threading module is first import from a thread +- # different than the main thread, threading._shutdown() must handle +- # this case without logging an error at Python exit. +- code = textwrap.dedent(''' +- import _thread +- import sys +- +- event = _thread.allocate_lock() +- event.acquire() +- +- def import_threading(): +- import threading +- event.release() +- +- if 'threading' in sys.modules: +- raise Exception('threading is already imported') +- +- _thread.start_new_thread(import_threading, ()) +- +- # wait until the threading module is imported +- event.acquire() +- event.release() +- +- if 'threading' not in sys.modules: +- raise Exception('threading is not imported') +- +- # don't wait until the thread completes +- ''') +- rc, out, err = assert_python_ok("-c", code) +- self.assertEqual(out, b'') +- self.assertEqual(err, b'') +- + + class ThreadJoinOnShutdown(BaseTestCase): + +diff --git a/Lib/threading.py b/Lib/threading.py +index a3cb245ab9..ca1d6f08c4 100644 +--- a/Lib/threading.py ++++ b/Lib/threading.py +@@ -1433,29 +1433,20 @@ def _shutdown(): + + global _SHUTTING_DOWN + _SHUTTING_DOWN = True ++ # Main thread ++ tlock = _main_thread._tstate_lock ++ # The main thread isn't finished yet, so its thread state lock can't have ++ # been released. ++ assert tlock is not None ++ assert tlock.locked() ++ tlock.release() ++ _main_thread._stop() + + # Call registered threading atexit functions before threads are joined. + # Order is reversed, similar to atexit. + for atexit_call in reversed(_threading_atexits): + atexit_call() + +- # Main thread +- if _main_thread.ident == get_ident(): +- tlock = _main_thread._tstate_lock +- # The main thread isn't finished yet, so its thread state lock can't +- # have been released. +- assert tlock is not None +- assert tlock.locked() +- tlock.release() +- _main_thread._stop() +- else: +- # bpo-1596321: _shutdown() must be called in the main thread. +- # If the threading module was not imported by the main thread, +- # _main_thread is the thread which imported the threading module. +- # In this case, ignore _main_thread, similar behavior than for threads +- # spawned by C libraries or using _thread.start_new_thread(). +- pass +- + # Join all non-deamon threads + while True: + with _shutdown_locks_lock: diff --git a/python3.9.spec b/python3.9.spec index a9b93fe..98ffa30 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -370,6 +370,17 @@ Patch328: 00328-pyc-timestamp-invalidation-mode.patch # a nightmare because it's basically a binary file. Patch353: 00353-architecture-names-upstream-downstream.patch +# 00371 # 1fc313929648e9b543542de09f59c55e175ac45a +# Revert "bpo-1596321: Fix threading._shutdown() for the main thread (GH-28549) (GH-28589)" +# +# This reverts commit 94d19f606fa18a1c4d2faca1caf2f470a8ce6d46. It +# introduced regression causing FreeIPA's tests to fail. +# +# For more info see: +# https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 +# https://github.com/GrahamDumpleton/mod_wsgi/issues/730 +Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1783,6 +1794,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Nov 19 2021 Tomáš Hrnčiar - 3.9.9-2 +- Add patch to revert "bpo-1596321: Fix threading._shutdown() for the main thread" + * Tue Nov 16 2021 Tomáš Hrnčiar - 3.9.9-1 - Update to 3.9.9 From 26e7b720df673023a7d630d634e1052aec79ff5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Fri, 19 Nov 2021 14:12:25 +0100 Subject: [PATCH 23/89] Add patch to revert "bpo-1596321: Fix threading._shutdown() for the main thread" https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 https://github.com/GrahamDumpleton/mod_wsgi/issues/730 --- ...or-the-main-thread-gh-28549-gh-28589.patch | 103 ++++++++++++++++++ python3.9.spec | 16 ++- 2 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch new file mode 100644 index 0000000..015cb48 --- /dev/null +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= +Date: Fri, 19 Nov 2021 13:37:16 +0100 +Subject: [PATCH] 00371: Revert "bpo-1596321: Fix threading._shutdown() for the + main thread (GH-28549) (GH-28589)" + +This reverts commit 94d19f606fa18a1c4d2faca1caf2f470a8ce6d46. It +introduced regression causing FreeIPA's tests to fail. + +For more info see: +https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 +https://github.com/GrahamDumpleton/mod_wsgi/issues/730 +--- + Lib/test/test_threading.py | 33 --------------------------------- + Lib/threading.py | 25 ++++++++----------------- + 2 files changed, 8 insertions(+), 50 deletions(-) + +diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py +index af480b9014..a57085b75d 100644 +--- a/Lib/test/test_threading.py ++++ b/Lib/test/test_threading.py +@@ -814,39 +814,6 @@ class ThreadTests(BaseTestCase): + threading.Thread(target=noop).start() + # Thread.join() is not called + +- def test_import_from_another_thread(self): +- # bpo-1596321: If the threading module is first import from a thread +- # different than the main thread, threading._shutdown() must handle +- # this case without logging an error at Python exit. +- code = textwrap.dedent(''' +- import _thread +- import sys +- +- event = _thread.allocate_lock() +- event.acquire() +- +- def import_threading(): +- import threading +- event.release() +- +- if 'threading' in sys.modules: +- raise Exception('threading is already imported') +- +- _thread.start_new_thread(import_threading, ()) +- +- # wait until the threading module is imported +- event.acquire() +- event.release() +- +- if 'threading' not in sys.modules: +- raise Exception('threading is not imported') +- +- # don't wait until the thread completes +- ''') +- rc, out, err = assert_python_ok("-c", code) +- self.assertEqual(out, b'') +- self.assertEqual(err, b'') +- + + class ThreadJoinOnShutdown(BaseTestCase): + +diff --git a/Lib/threading.py b/Lib/threading.py +index a3cb245ab9..ca1d6f08c4 100644 +--- a/Lib/threading.py ++++ b/Lib/threading.py +@@ -1433,29 +1433,20 @@ def _shutdown(): + + global _SHUTTING_DOWN + _SHUTTING_DOWN = True ++ # Main thread ++ tlock = _main_thread._tstate_lock ++ # The main thread isn't finished yet, so its thread state lock can't have ++ # been released. ++ assert tlock is not None ++ assert tlock.locked() ++ tlock.release() ++ _main_thread._stop() + + # Call registered threading atexit functions before threads are joined. + # Order is reversed, similar to atexit. + for atexit_call in reversed(_threading_atexits): + atexit_call() + +- # Main thread +- if _main_thread.ident == get_ident(): +- tlock = _main_thread._tstate_lock +- # The main thread isn't finished yet, so its thread state lock can't +- # have been released. +- assert tlock is not None +- assert tlock.locked() +- tlock.release() +- _main_thread._stop() +- else: +- # bpo-1596321: _shutdown() must be called in the main thread. +- # If the threading module was not imported by the main thread, +- # _main_thread is the thread which imported the threading module. +- # In this case, ignore _main_thread, similar behavior than for threads +- # spawned by C libraries or using _thread.start_new_thread(). +- pass +- + # Join all non-deamon threads + while True: + with _shutdown_locks_lock: diff --git a/python3.9.spec b/python3.9.spec index 365ca9d..57297c2 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -370,6 +370,17 @@ Patch328: 00328-pyc-timestamp-invalidation-mode.patch # a nightmare because it's basically a binary file. Patch353: 00353-architecture-names-upstream-downstream.patch +# 00371 # 1fc313929648e9b543542de09f59c55e175ac45a +# Revert "bpo-1596321: Fix threading._shutdown() for the main thread (GH-28549) (GH-28589)" +# +# This reverts commit 94d19f606fa18a1c4d2faca1caf2f470a8ce6d46. It +# introduced regression causing FreeIPA's tests to fail. +# +# For more info see: +# https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 +# https://github.com/GrahamDumpleton/mod_wsgi/issues/730 +Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1783,6 +1794,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Nov 19 2021 Tomáš Hrnčiar - 3.9.9-2 +- Add patch to revert "bpo-1596321: Fix threading._shutdown() for the main thread" + * Tue Nov 16 2021 Tomáš Hrnčiar - 3.9.9-1 - Update to 3.9.9 From e1fa6a9599ed3206f7304047cfe66fa6f4b17888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Sat, 8 Jan 2022 11:12:38 +0100 Subject: [PATCH 24/89] Rebuilt for https://fedoraproject.org/wiki/Changes/LIBFFI34 --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 98ffa30..de2e115 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1794,6 +1794,9 @@ CheckPython optimized # ====================================================== %changelog +* Sat Jan 08 2022 Miro Hrončok - 3.9.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Changes/LIBFFI34 + * Fri Nov 19 2021 Tomáš Hrnčiar - 3.9.9-2 - Add patch to revert "bpo-1596321: Fix threading._shutdown() for the main thread" From 250d7d5d30d8a0f46ac58c7f16611350f68a7ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 4 Jan 2022 12:55:59 +0100 Subject: [PATCH 25/89] Sync patch 251 with Python 3.10+ on Fedora < 36 Instruct pip to use distutils ----------------------------- The current version of pip uses distutils on Python < 3.10, so this should change nothing, but future versions of pip may theoretically change that. Instruct pypa/distutils to add /local/ addition to prefix --------------------------------------------------------- Needed for setuptools 60+ installed/upgraded by pip or when we update it in rawhide. Setuptools 60+ uses bundled pypa/distutils instead of the standard library distutils. --- 00251-change-user-install-location.patch | 84 +++++++++++++++++++----- python3.9.spec | 16 ++++- 2 files changed, 79 insertions(+), 21 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 57b71bf..074e59d 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -2,41 +2,61 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Michal Cyprian Date: Mon, 26 Jun 2017 16:32:56 +0200 Subject: [PATCH] 00251: Change user install location +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Set values of prefix and exec_prefix in distutils install command to /usr/local if executable is /usr/bin/python* and RPM build is not detected to make pip and distutils install into separate location. Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe -Downstream only: Awaiting resources to work on upstream PEP +Downstream only: Reworked in Fedora 36+/Python 3.10+ to follow https://bugs.python.org/issue43976 + +pypa/distutils integration: https://github.com/pypa/distutils/pull/70 + +Also set sysconfig._PIP_USE_SYSCONFIG = False, to force pip-upgraded-pip +to respect this patched distutils install command. +See https://bugzilla.redhat.com/show_bug.cgi?id=2014513 + +Co-authored-by: Miro Hrončok --- - Lib/distutils/command/install.py | 15 +++++++++++++-- + Lib/distutils/command/install.py | 9 +++++++-- Lib/site.py | 9 ++++++++- - 2 files changed, 21 insertions(+), 3 deletions(-) + Lib/sysconfig.py | 17 +++++++++++++++++ + 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py -index aaa300efa9..f8d453912a 100644 +index aaa300efa9..18f01f10d4 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py -@@ -419,8 +419,19 @@ class install(Command): +@@ -3,6 +3,7 @@ + Implements the Distutils 'install' command.""" + + import sys ++import sysconfig + import os + + from distutils import log +@@ -142,6 +143,8 @@ class install(Command): + + negative_opt = {'no-compile' : 'compile'} + ++ # Allow Fedora to add components to the prefix ++ _prefix_addition = getattr(sysconfig, '_prefix_addition', '') + + def initialize_options(self): + """Initializes options.""" +@@ -419,8 +422,10 @@ class install(Command): raise DistutilsOptionError( "must not supply exec-prefix without prefix") - self.prefix = os.path.normpath(sys.prefix) - self.exec_prefix = os.path.normpath(sys.exec_prefix) -+ # self.prefix is set to sys.prefix + /local/ -+ # if neither RPM build nor virtual environment is -+ # detected to make pip and distutils install packages -+ # into the separate location. -+ if (not (hasattr(sys, 'real_prefix') or -+ sys.prefix != sys.base_prefix) and -+ 'RPM_BUILD_ROOT' not in os.environ): -+ addition = "/local" -+ else: -+ addition = "" -+ -+ self.prefix = os.path.normpath(sys.prefix) + addition -+ self.exec_prefix = os.path.normpath(sys.exec_prefix) + addition ++ self.prefix = ( ++ os.path.normpath(sys.prefix) + self._prefix_addition) ++ self.exec_prefix = ( ++ os.path.normpath(sys.exec_prefix) + self._prefix_addition) else: if self.exec_prefix is None: @@ -60,3 +80,31 @@ index 9e617afb00..db14f715f9 100644 for sitedir in getsitepackages(prefixes): if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) +diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py +index e3f79bfde5..e124104876 100644 +--- a/Lib/sysconfig.py ++++ b/Lib/sysconfig.py +@@ -86,6 +86,23 @@ _INSTALL_SCHEMES = { + }, + } + ++# Force pip to use distutils paths instead of sysconfig ++# https://github.com/pypa/pip/issues/10647 ++_PIP_USE_SYSCONFIG = False ++ ++# This is used by distutils.command.install in the stdlib ++# as well as pypa/distutils (e.g. bundled in setuptools). ++# The self.prefix value is set to sys.prefix + /local/ ++# if neither RPM build nor virtual environment is ++# detected to make distutils install packages ++# into the separate location. ++# https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe ++if (not (hasattr(sys, 'real_prefix') or ++ sys.prefix != sys.base_prefix) and ++ 'RPM_BUILD_ROOT' not in os.environ): ++ _prefix_addition = "/local" ++ ++ + _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', + 'scripts', 'data') + diff --git a/python3.9.spec b/python3.9.spec index de2e115..1b5186a 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 4%{?dist} License: Python @@ -320,7 +320,7 @@ Patch189: 00189-use-rpm-wheels.patch %global pip_version 21.2.4 %global setuptools_version 58.1.0 -# 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 +# 00251 # 1b1047c14ff98eae6d355b4aac4df3e388813f62 # Change user install location # # Set values of prefix and exec_prefix in distutils install command @@ -328,7 +328,13 @@ Patch189: 00189-use-rpm-wheels.patch # is not detected to make pip and distutils install into separate location. # # Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe -# Downstream only: Awaiting resources to work on upstream PEP +# Downstream only: Reworked in Fedora 36+/Python 3.10+ to follow https://bugs.python.org/issue43976 +# +# pypa/distutils integration: https://github.com/pypa/distutils/pull/70 +# +# Also set sysconfig._PIP_USE_SYSCONFIG = False, to force pip-upgraded-pip +# to respect this patched distutils install command. +# See https://bugzilla.redhat.com/show_bug.cgi?id=2014513 Patch251: 00251-change-user-install-location.patch # 00328 # 367fdcb5a075f083aea83ac174999272a8faf75c @@ -1794,6 +1800,10 @@ CheckPython optimized # ====================================================== %changelog +* Sat Jan 08 2022 Miro Hrončok - 3.9.9-4 +- Instruct pip to use distutils +- Instruct pypa/distutils to add /local/ addition to prefix + * Sat Jan 08 2022 Miro Hrončok - 3.9.9-3 - Rebuilt for https://fedoraproject.org/wiki/Changes/LIBFFI34 From f804705bc380ac2583231661272f903d35f3a755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 12 Jan 2022 14:41:25 +0000 Subject: [PATCH 26/89] Sync patch 251 with Python 3.10+ on Fedora < 36 Instruct pip to use distutils ----------------------------- The current version of pip uses distutils on Python < 3.10, so this should change nothing, but future versions of pip may theoretically change that. Instruct pypa/distutils to add /local/ addition to prefix --------------------------------------------------------- Needed for setuptools 60+ installed/upgraded by pip or when we update it in rawhide. Setuptools 60+ uses bundled pypa/distutils instead of the standard library distutils. --- 00251-change-user-install-location.patch | 84 +++++++++++++++++++----- python3.9.spec | 16 ++++- 2 files changed, 79 insertions(+), 21 deletions(-) diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 57b71bf..074e59d 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -2,41 +2,61 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Michal Cyprian Date: Mon, 26 Jun 2017 16:32:56 +0200 Subject: [PATCH] 00251: Change user install location +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Set values of prefix and exec_prefix in distutils install command to /usr/local if executable is /usr/bin/python* and RPM build is not detected to make pip and distutils install into separate location. Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe -Downstream only: Awaiting resources to work on upstream PEP +Downstream only: Reworked in Fedora 36+/Python 3.10+ to follow https://bugs.python.org/issue43976 + +pypa/distutils integration: https://github.com/pypa/distutils/pull/70 + +Also set sysconfig._PIP_USE_SYSCONFIG = False, to force pip-upgraded-pip +to respect this patched distutils install command. +See https://bugzilla.redhat.com/show_bug.cgi?id=2014513 + +Co-authored-by: Miro Hrončok --- - Lib/distutils/command/install.py | 15 +++++++++++++-- + Lib/distutils/command/install.py | 9 +++++++-- Lib/site.py | 9 ++++++++- - 2 files changed, 21 insertions(+), 3 deletions(-) + Lib/sysconfig.py | 17 +++++++++++++++++ + 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py -index aaa300efa9..f8d453912a 100644 +index aaa300efa9..18f01f10d4 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py -@@ -419,8 +419,19 @@ class install(Command): +@@ -3,6 +3,7 @@ + Implements the Distutils 'install' command.""" + + import sys ++import sysconfig + import os + + from distutils import log +@@ -142,6 +143,8 @@ class install(Command): + + negative_opt = {'no-compile' : 'compile'} + ++ # Allow Fedora to add components to the prefix ++ _prefix_addition = getattr(sysconfig, '_prefix_addition', '') + + def initialize_options(self): + """Initializes options.""" +@@ -419,8 +422,10 @@ class install(Command): raise DistutilsOptionError( "must not supply exec-prefix without prefix") - self.prefix = os.path.normpath(sys.prefix) - self.exec_prefix = os.path.normpath(sys.exec_prefix) -+ # self.prefix is set to sys.prefix + /local/ -+ # if neither RPM build nor virtual environment is -+ # detected to make pip and distutils install packages -+ # into the separate location. -+ if (not (hasattr(sys, 'real_prefix') or -+ sys.prefix != sys.base_prefix) and -+ 'RPM_BUILD_ROOT' not in os.environ): -+ addition = "/local" -+ else: -+ addition = "" -+ -+ self.prefix = os.path.normpath(sys.prefix) + addition -+ self.exec_prefix = os.path.normpath(sys.exec_prefix) + addition ++ self.prefix = ( ++ os.path.normpath(sys.prefix) + self._prefix_addition) ++ self.exec_prefix = ( ++ os.path.normpath(sys.exec_prefix) + self._prefix_addition) else: if self.exec_prefix is None: @@ -60,3 +80,31 @@ index 9e617afb00..db14f715f9 100644 for sitedir in getsitepackages(prefixes): if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) +diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py +index e3f79bfde5..e124104876 100644 +--- a/Lib/sysconfig.py ++++ b/Lib/sysconfig.py +@@ -86,6 +86,23 @@ _INSTALL_SCHEMES = { + }, + } + ++# Force pip to use distutils paths instead of sysconfig ++# https://github.com/pypa/pip/issues/10647 ++_PIP_USE_SYSCONFIG = False ++ ++# This is used by distutils.command.install in the stdlib ++# as well as pypa/distutils (e.g. bundled in setuptools). ++# The self.prefix value is set to sys.prefix + /local/ ++# if neither RPM build nor virtual environment is ++# detected to make distutils install packages ++# into the separate location. ++# https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe ++if (not (hasattr(sys, 'real_prefix') or ++ sys.prefix != sys.base_prefix) and ++ 'RPM_BUILD_ROOT' not in os.environ): ++ _prefix_addition = "/local" ++ ++ + _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', + 'scripts', 'data') + diff --git a/python3.9.spec b/python3.9.spec index 57297c2..3ef256d 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 4%{?dist} License: Python @@ -320,7 +320,7 @@ Patch189: 00189-use-rpm-wheels.patch %global pip_version 21.2.4 %global setuptools_version 58.1.0 -# 00251 # 2eabd04356402d488060bc8fe316ad13fc8a3356 +# 00251 # 1b1047c14ff98eae6d355b4aac4df3e388813f62 # Change user install location # # Set values of prefix and exec_prefix in distutils install command @@ -328,7 +328,13 @@ Patch189: 00189-use-rpm-wheels.patch # is not detected to make pip and distutils install into separate location. # # Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe -# Downstream only: Awaiting resources to work on upstream PEP +# Downstream only: Reworked in Fedora 36+/Python 3.10+ to follow https://bugs.python.org/issue43976 +# +# pypa/distutils integration: https://github.com/pypa/distutils/pull/70 +# +# Also set sysconfig._PIP_USE_SYSCONFIG = False, to force pip-upgraded-pip +# to respect this patched distutils install command. +# See https://bugzilla.redhat.com/show_bug.cgi?id=2014513 Patch251: 00251-change-user-install-location.patch # 00328 # 367fdcb5a075f083aea83ac174999272a8faf75c @@ -1794,6 +1800,10 @@ CheckPython optimized # ====================================================== %changelog +* Sat Jan 08 2022 Miro Hrončok - 3.9.9-4 +- Instruct pip to use distutils +- Instruct pypa/distutils to add /local/ addition to prefix + * Fri Nov 19 2021 Tomáš Hrnčiar - 3.9.9-2 - Add patch to revert "bpo-1596321: Fix threading._shutdown() for the main thread" From ee9e037e7b7e018e0b266db1d1688bd89d75711e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Mon, 17 Jan 2022 09:45:27 +0100 Subject: [PATCH 27/89] Update to 3.9.10 --- 00111-no-static-lib.patch | 2 +- python3.9.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 390eed2..51e0e36 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 11230fa563..dc763e7197 100644 +index 42b1ec622a..c1cf1585df 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -588,7 +588,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c diff --git a/python3.9.spec b/python3.9.spec index 1b5186a..cea8fb2 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.9 +%global general_version %{pybasever}.10 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 4%{?dist} +Release: 1%{?dist} License: Python @@ -1800,6 +1800,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Jan 17 2022 Tomáš Hrnčiar - 3.9.10-1 +- Update to 3.9.10 + * Sat Jan 08 2022 Miro Hrončok - 3.9.9-4 - Instruct pip to use distutils - Instruct pypa/distutils to add /local/ addition to prefix diff --git a/sources b/sources index d7b5371..ae1b630 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.9.tar.xz) = 0ab29fb9a7ecb808bd08d84d28908d5a934e0f021853da0f7a9c94670eb30c8dbbc233d461afdb3995b0de59275ef7e1de43e82d7f848802cbd6e6e50b7b25a6 -SHA512 (Python-3.9.9.tar.xz.asc) = 84fb739c60216ab9a7a487a0ec4039a7e85c7684ef1f71d8b3bc415ff2ae284f79474103ae05385502bc2510401f8cfb33d84dccf5d0ea9a0dd62528519d935f +SHA512 (Python-3.9.10.tar.xz) = 09cb942f84bf362df88999ffa6faf89b4ad12302e67cda4a11547828ebe410c7c93a3dc96cd66fd9c5c7d9a1abe5b8e259e7ec47c10273b42d212270aca5ecba +SHA512 (Python-3.9.10.tar.xz.asc) = d9fed5b39100b81835085d712453516d309b0dddc1524d578cb63c95cd1e2392882702111dd3cb0ebf58c98b94ec04838c89c57f4a7a649c585f7ba5eef70e5e From da801669d74fa595457d0382ebbb0d5406739412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Mon, 17 Jan 2022 09:45:27 +0100 Subject: [PATCH 28/89] Update to 3.9.10 --- 00111-no-static-lib.patch | 2 +- python3.9.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 390eed2..51e0e36 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 11230fa563..dc763e7197 100644 +index 42b1ec622a..c1cf1585df 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -588,7 +588,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c diff --git a/python3.9.spec b/python3.9.spec index 3ef256d..109bbe5 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.9 +%global general_version %{pybasever}.10 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 4%{?dist} +Release: 1%{?dist} License: Python @@ -1800,6 +1800,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Jan 17 2022 Tomáš Hrnčiar - 3.9.10-1 +- Update to 3.9.10 + * Sat Jan 08 2022 Miro Hrončok - 3.9.9-4 - Instruct pip to use distutils - Instruct pypa/distutils to add /local/ addition to prefix diff --git a/sources b/sources index d7b5371..ae1b630 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.9.tar.xz) = 0ab29fb9a7ecb808bd08d84d28908d5a934e0f021853da0f7a9c94670eb30c8dbbc233d461afdb3995b0de59275ef7e1de43e82d7f848802cbd6e6e50b7b25a6 -SHA512 (Python-3.9.9.tar.xz.asc) = 84fb739c60216ab9a7a487a0ec4039a7e85c7684ef1f71d8b3bc415ff2ae284f79474103ae05385502bc2510401f8cfb33d84dccf5d0ea9a0dd62528519d935f +SHA512 (Python-3.9.10.tar.xz) = 09cb942f84bf362df88999ffa6faf89b4ad12302e67cda4a11547828ebe410c7c93a3dc96cd66fd9c5c7d9a1abe5b8e259e7ec47c10273b42d212270aca5ecba +SHA512 (Python-3.9.10.tar.xz.asc) = d9fed5b39100b81835085d712453516d309b0dddc1524d578cb63c95cd1e2392882702111dd3cb0ebf58c98b94ec04838c89c57f4a7a649c585f7ba5eef70e5e From c12e3e49f26e68a5dcee895a613da04311c58b70 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 21 Jan 2022 16:49:31 +0000 Subject: [PATCH 29/89] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index cea8fb2..583605b 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -1800,6 +1800,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jan 21 2022 Fedora Release Engineering - 3.9.10-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Mon Jan 17 2022 Tomáš Hrnčiar - 3.9.10-1 - Update to 3.9.10 From 519e7eee12063c1aeb4688fff9ad487448aa3aaa Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Wed, 16 Mar 2022 16:34:49 +0100 Subject: [PATCH 30/89] Explicitly declare the usage of distutils from Python stdlib for tests setuptools 60+ bundles distutils which then have an impact on the test environment, causing test_with_pip to fail. Resolves: https://bugzilla.redhat.com/2064734 --- python3.9.spec | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 583605b..3ceb277 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1198,6 +1198,11 @@ done %check +# setuptools 60+ uses its own copy of distutils by default +# this setting must be overriden with the environment variable for +# Python tests to use the standard library's distutils +export SETUPTOOLS_USE_DISTUTILS=stdlib + # first of all, check timestamps of bytecode files find %{buildroot} -type f -a -name "*.py" -print0 | \ LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ @@ -1800,6 +1805,10 @@ CheckPython optimized # ====================================================== %changelog +* Wed Mar 16 2022 Karolina Surma - 3.9.10-3 +- Fix the test suite support for setuptools >= 60 +Resolves: rhbz#2064734 + * Fri Jan 21 2022 Fedora Release Engineering - 3.9.10-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild From d899219223874aa1cabcfb257d0d891aefb3d2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Thu, 17 Mar 2022 15:55:45 +0100 Subject: [PATCH 31/89] Update to 3.9.11 --- 00189-use-rpm-wheels.patch | 4 ++-- 00353-architecture-names-upstream-downstream.patch | 8 ++++---- python3.9.spec | 11 +++++++---- sources | 4 ++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index e5cf8f7..0fed4aa 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 2a140a2624..5bd16a6c59 100644 +index e510cc7fb2..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -31,7 +31,7 @@ index 2a140a2624..5bd16a6c59 100644 __all__ = ["version", "bootstrap"] -_SETUPTOOLS_VERSION = "58.1.0" --_PIP_VERSION = "21.2.4" +-_PIP_VERSION = "22.0.4" + +_WHEEL_DIR = "/usr/share/python-wheels/" + diff --git a/00353-architecture-names-upstream-downstream.patch b/00353-architecture-names-upstream-downstream.patch index 578e786..b0b955c 100644 --- a/00353-architecture-names-upstream-downstream.patch +++ b/00353-architecture-names-upstream-downstream.patch @@ -34,10 +34,10 @@ Co-authored-by: Miro Hrončok 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py -index fe31f437da..b5b70757f0 100644 +index f3828b10e1..f0c9f8e383 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py -@@ -1636,7 +1636,7 @@ def _get_supported_file_loaders(): +@@ -1645,7 +1645,7 @@ def _get_supported_file_loaders(): Each item is a tuple (loader, suffixes). """ @@ -46,7 +46,7 @@ index fe31f437da..b5b70757f0 100644 source = SourceFileLoader, SOURCE_SUFFIXES bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES return [extensions, source, bytecode] -@@ -1692,7 +1692,7 @@ def _setup(_bootstrap_module): +@@ -1701,7 +1701,7 @@ def _setup(_bootstrap_module): # Constants setattr(self_module, '_relax_case', _make_relax_case()) @@ -55,7 +55,7 @@ index fe31f437da..b5b70757f0 100644 if builtin_os == 'nt': SOURCE_SUFFIXES.append('.pyw') if '_d.pyd' in EXTENSION_SUFFIXES: -@@ -1705,3 +1705,39 @@ def _install(_bootstrap_module): +@@ -1714,3 +1714,39 @@ def _install(_bootstrap_module): supported_loaders = _get_supported_file_loaders() sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) sys.meta_path.append(PathFinder) diff --git a/python3.9.spec b/python3.9.spec index 3ceb277..807dd80 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.10 +%global general_version %{pybasever}.11 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # d06cf137c00fd3907b436fdb92a8f007a7f2fb50 +# 00189 # a79a85be3f0ad45792d998aed1104c2c2a0ef729 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,7 +317,7 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.2.4 +%global pip_version 22.0.4 %global setuptools_version 58.1.0 # 00251 # 1b1047c14ff98eae6d355b4aac4df3e388813f62 @@ -1805,6 +1805,9 @@ CheckPython optimized # ====================================================== %changelog +* Thu Mar 17 2022 Tomáš Hrnčiar - 3.9.11-1 +- Update to 3.9.11 + * Wed Mar 16 2022 Karolina Surma - 3.9.10-3 - Fix the test suite support for setuptools >= 60 Resolves: rhbz#2064734 diff --git a/sources b/sources index ae1b630..f277fe4 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.10.tar.xz) = 09cb942f84bf362df88999ffa6faf89b4ad12302e67cda4a11547828ebe410c7c93a3dc96cd66fd9c5c7d9a1abe5b8e259e7ec47c10273b42d212270aca5ecba -SHA512 (Python-3.9.10.tar.xz.asc) = d9fed5b39100b81835085d712453516d309b0dddc1524d578cb63c95cd1e2392882702111dd3cb0ebf58c98b94ec04838c89c57f4a7a649c585f7ba5eef70e5e +SHA512 (Python-3.9.11.tar.xz) = 804e6e6b31922378f07f290023f6efc870c6fd3010204c499c2b375880f6e6ec0f72ce96a8fff81956f6fa3bea2123df2138ef0fda23a3d5d3cf757174a930c3 +SHA512 (Python-3.9.11.tar.xz.asc) = a84bbfa68ec1c0e45bbd64af4481be7d68885021287731c69346a3cb25c9bf607be84dd72af2d3a6fbeabbde64975f37c4bb4f61274e72b92b4277fa48543e52 From 2cc996de16d3e2b9fe4ea54c3f6f259bef968086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Thu, 17 Mar 2022 15:55:45 +0100 Subject: [PATCH 32/89] Update to 3.9.11 --- 00189-use-rpm-wheels.patch | 4 ++-- 00353-architecture-names-upstream-downstream.patch | 8 ++++---- python3.9.spec | 9 ++++++--- sources | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index e5cf8f7..0fed4aa 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 2a140a2624..5bd16a6c59 100644 +index e510cc7fb2..5bd16a6c59 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -31,7 +31,7 @@ index 2a140a2624..5bd16a6c59 100644 __all__ = ["version", "bootstrap"] -_SETUPTOOLS_VERSION = "58.1.0" --_PIP_VERSION = "21.2.4" +-_PIP_VERSION = "22.0.4" + +_WHEEL_DIR = "/usr/share/python-wheels/" + diff --git a/00353-architecture-names-upstream-downstream.patch b/00353-architecture-names-upstream-downstream.patch index 578e786..b0b955c 100644 --- a/00353-architecture-names-upstream-downstream.patch +++ b/00353-architecture-names-upstream-downstream.patch @@ -34,10 +34,10 @@ Co-authored-by: Miro Hrončok 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py -index fe31f437da..b5b70757f0 100644 +index f3828b10e1..f0c9f8e383 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py -@@ -1636,7 +1636,7 @@ def _get_supported_file_loaders(): +@@ -1645,7 +1645,7 @@ def _get_supported_file_loaders(): Each item is a tuple (loader, suffixes). """ @@ -46,7 +46,7 @@ index fe31f437da..b5b70757f0 100644 source = SourceFileLoader, SOURCE_SUFFIXES bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES return [extensions, source, bytecode] -@@ -1692,7 +1692,7 @@ def _setup(_bootstrap_module): +@@ -1701,7 +1701,7 @@ def _setup(_bootstrap_module): # Constants setattr(self_module, '_relax_case', _make_relax_case()) @@ -55,7 +55,7 @@ index fe31f437da..b5b70757f0 100644 if builtin_os == 'nt': SOURCE_SUFFIXES.append('.pyw') if '_d.pyd' in EXTENSION_SUFFIXES: -@@ -1705,3 +1705,39 @@ def _install(_bootstrap_module): +@@ -1714,3 +1714,39 @@ def _install(_bootstrap_module): supported_loaders = _get_supported_file_loaders() sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) sys.meta_path.append(PathFinder) diff --git a/python3.9.spec b/python3.9.spec index 109bbe5..db36838 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.10 +%global general_version %{pybasever}.11 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -305,7 +305,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # d06cf137c00fd3907b436fdb92a8f007a7f2fb50 +# 00189 # a79a85be3f0ad45792d998aed1104c2c2a0ef729 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -317,7 +317,7 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 21.2.4 +%global pip_version 22.0.4 %global setuptools_version 58.1.0 # 00251 # 1b1047c14ff98eae6d355b4aac4df3e388813f62 @@ -1800,6 +1800,9 @@ CheckPython optimized # ====================================================== %changelog +* Thu Mar 17 2022 Tomáš Hrnčiar - 3.9.11-1 +- Update to 3.9.11 + * Mon Jan 17 2022 Tomáš Hrnčiar - 3.9.10-1 - Update to 3.9.10 diff --git a/sources b/sources index ae1b630..f277fe4 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.10.tar.xz) = 09cb942f84bf362df88999ffa6faf89b4ad12302e67cda4a11547828ebe410c7c93a3dc96cd66fd9c5c7d9a1abe5b8e259e7ec47c10273b42d212270aca5ecba -SHA512 (Python-3.9.10.tar.xz.asc) = d9fed5b39100b81835085d712453516d309b0dddc1524d578cb63c95cd1e2392882702111dd3cb0ebf58c98b94ec04838c89c57f4a7a649c585f7ba5eef70e5e +SHA512 (Python-3.9.11.tar.xz) = 804e6e6b31922378f07f290023f6efc870c6fd3010204c499c2b375880f6e6ec0f72ce96a8fff81956f6fa3bea2123df2138ef0fda23a3d5d3cf757174a930c3 +SHA512 (Python-3.9.11.tar.xz.asc) = a84bbfa68ec1c0e45bbd64af4481be7d68885021287731c69346a3cb25c9bf607be84dd72af2d3a6fbeabbde64975f37c4bb4f61274e72b92b4277fa48543e52 From fefc6815e502651c34d71ba02b0b67fade07e601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Fri, 25 Mar 2022 07:53:12 +0100 Subject: [PATCH 33/89] Update to 3.9.12 --- python3.9.spec | 5 ++++- sources | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 807dd80..59780dc 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.11 +%global general_version %{pybasever}.12 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1805,6 +1805,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Mar 25 2022 Tomáš Hrnčiar - 3.9.12-1 +- Update to 3.9.12 + * Thu Mar 17 2022 Tomáš Hrnčiar - 3.9.11-1 - Update to 3.9.11 diff --git a/sources b/sources index f277fe4..efd8058 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.11.tar.xz) = 804e6e6b31922378f07f290023f6efc870c6fd3010204c499c2b375880f6e6ec0f72ce96a8fff81956f6fa3bea2123df2138ef0fda23a3d5d3cf757174a930c3 -SHA512 (Python-3.9.11.tar.xz.asc) = a84bbfa68ec1c0e45bbd64af4481be7d68885021287731c69346a3cb25c9bf607be84dd72af2d3a6fbeabbde64975f37c4bb4f61274e72b92b4277fa48543e52 +SHA512 (Python-3.9.12.tar.xz) = 081981901e14149748fd35228db0b3b1d96fef227ae7404f07b8bad0fda4b02649bf31c348c94aefdaf3327565d78f9489437c2c02f647b15d41376a27a23e97 +SHA512 (Python-3.9.12.tar.xz.asc) = dddaa27f8a29034f458edb6739398a5455c87fe37b6349e161865a9deedca118ffe9cb82663cc75bbe60b3b556399c0c6855f5262aac1fe90d36a3694fca65b2 From 163aad681361da52b6b6e27f09bc43ff219819da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Fri, 25 Mar 2022 07:57:51 +0100 Subject: [PATCH 34/89] Update to 3.9.12 --- python3.9.spec | 5 ++++- sources | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index db36838..3fbf56d 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.11 +%global general_version %{pybasever}.12 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1800,6 +1800,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Mar 25 2022 Tomáš Hrnčiar - 3.9.12-1 +- Update to 3.9.12 + * Thu Mar 17 2022 Tomáš Hrnčiar - 3.9.11-1 - Update to 3.9.11 diff --git a/sources b/sources index f277fe4..efd8058 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.11.tar.xz) = 804e6e6b31922378f07f290023f6efc870c6fd3010204c499c2b375880f6e6ec0f72ce96a8fff81956f6fa3bea2123df2138ef0fda23a3d5d3cf757174a930c3 -SHA512 (Python-3.9.11.tar.xz.asc) = a84bbfa68ec1c0e45bbd64af4481be7d68885021287731c69346a3cb25c9bf607be84dd72af2d3a6fbeabbde64975f37c4bb4f61274e72b92b4277fa48543e52 +SHA512 (Python-3.9.12.tar.xz) = 081981901e14149748fd35228db0b3b1d96fef227ae7404f07b8bad0fda4b02649bf31c348c94aefdaf3327565d78f9489437c2c02f647b15d41376a27a23e97 +SHA512 (Python-3.9.12.tar.xz.asc) = dddaa27f8a29034f458edb6739398a5455c87fe37b6349e161865a9deedca118ffe9cb82663cc75bbe60b3b556399c0c6855f5262aac1fe90d36a3694fca65b2 From 65cf3d711cfa745a5da9425d5ed1842d07c2a8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 18 May 2022 16:05:55 +0200 Subject: [PATCH 35/89] Update to 3.9.13 --- ...ing-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch | 4 ++-- python3.9.spec | 5 ++++- sources | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch index 015cb48..c089771 100644 --- a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -60,10 +60,10 @@ index af480b9014..a57085b75d 100644 class ThreadJoinOnShutdown(BaseTestCase): diff --git a/Lib/threading.py b/Lib/threading.py -index a3cb245ab9..ca1d6f08c4 100644 +index 565f868e92..f0ef109a6e 100644 --- a/Lib/threading.py +++ b/Lib/threading.py -@@ -1433,29 +1433,20 @@ def _shutdown(): +@@ -1440,29 +1440,20 @@ def _shutdown(): global _SHUTTING_DOWN _SHUTTING_DOWN = True diff --git a/python3.9.spec b/python3.9.spec index 59780dc..ce2986f 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.12 +%global general_version %{pybasever}.13 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1805,6 +1805,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed May 18 2022 Tomáš Hrnčiar - 3.9.13-1 +- Update to 3.9.13 + * Fri Mar 25 2022 Tomáš Hrnčiar - 3.9.12-1 - Update to 3.9.12 diff --git a/sources b/sources index efd8058..faf7226 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.12.tar.xz) = 081981901e14149748fd35228db0b3b1d96fef227ae7404f07b8bad0fda4b02649bf31c348c94aefdaf3327565d78f9489437c2c02f647b15d41376a27a23e97 -SHA512 (Python-3.9.12.tar.xz.asc) = dddaa27f8a29034f458edb6739398a5455c87fe37b6349e161865a9deedca118ffe9cb82663cc75bbe60b3b556399c0c6855f5262aac1fe90d36a3694fca65b2 +SHA512 (Python-3.9.13.tar.xz) = e9664e7f908092df11236b22465d217531d6f0378e88d889108d19fe77f28f46ffb629b8733f84b41409e255367321893a2b1bd64518930d9d8cae5d1b774d23 +SHA512 (Python-3.9.13.tar.xz.asc) = 9367afe8ec32195adbb64fa32eb9e3881cfdbbb38efcb5e0804a15486232aecbc81ed20a8ffed652f06a881744f3efd2c2df3cc652d70671c94d6668a17a391e From 31789ee6f348cce5d78843efd47d5a85df759cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 18 May 2022 16:05:55 +0200 Subject: [PATCH 36/89] Update to 3.9.13 --- ...ing-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch | 4 ++-- python3.9.spec | 5 ++++- sources | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch index 015cb48..c089771 100644 --- a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -60,10 +60,10 @@ index af480b9014..a57085b75d 100644 class ThreadJoinOnShutdown(BaseTestCase): diff --git a/Lib/threading.py b/Lib/threading.py -index a3cb245ab9..ca1d6f08c4 100644 +index 565f868e92..f0ef109a6e 100644 --- a/Lib/threading.py +++ b/Lib/threading.py -@@ -1433,29 +1433,20 @@ def _shutdown(): +@@ -1440,29 +1440,20 @@ def _shutdown(): global _SHUTTING_DOWN _SHUTTING_DOWN = True diff --git a/python3.9.spec b/python3.9.spec index 3fbf56d..4e2f83e 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.12 +%global general_version %{pybasever}.13 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1800,6 +1800,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed May 18 2022 Tomáš Hrnčiar - 3.9.13-1 +- Update to 3.9.13 + * Fri Mar 25 2022 Tomáš Hrnčiar - 3.9.12-1 - Update to 3.9.12 diff --git a/sources b/sources index efd8058..faf7226 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.12.tar.xz) = 081981901e14149748fd35228db0b3b1d96fef227ae7404f07b8bad0fda4b02649bf31c348c94aefdaf3327565d78f9489437c2c02f647b15d41376a27a23e97 -SHA512 (Python-3.9.12.tar.xz.asc) = dddaa27f8a29034f458edb6739398a5455c87fe37b6349e161865a9deedca118ffe9cb82663cc75bbe60b3b556399c0c6855f5262aac1fe90d36a3694fca65b2 +SHA512 (Python-3.9.13.tar.xz) = e9664e7f908092df11236b22465d217531d6f0378e88d889108d19fe77f28f46ffb629b8733f84b41409e255367321893a2b1bd64518930d9d8cae5d1b774d23 +SHA512 (Python-3.9.13.tar.xz.asc) = 9367afe8ec32195adbb64fa32eb9e3881cfdbbb38efcb5e0804a15486232aecbc81ed20a8ffed652f06a881744f3efd2c2df3cc652d70671c94d6668a17a391e From face7cd60ef16e0de688928110b53be4ca608725 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Fri, 10 Jun 2022 01:10:38 +0200 Subject: [PATCH 37/89] Security fix for CVE-2015-20107 Resolves: rhbz#2075390 --- 00382-cve-2015-20107.patch | 150 +++++++++++++++++++++++++++++++++++++ python3.9.spec | 16 +++- 2 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 00382-cve-2015-20107.patch diff --git a/00382-cve-2015-20107.patch b/00382-cve-2015-20107.patch new file mode 100644 index 0000000..619f636 --- /dev/null +++ b/00382-cve-2015-20107.patch @@ -0,0 +1,150 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Petr Viktorin +Date: Fri, 3 Jun 2022 11:43:35 +0200 +Subject: [PATCH] 00382: CVE-2015-20107 + +Make mailcap refuse to match unsafe filenames/types/params (GH-91993) + +Upstream: https://github.com/python/cpython/issues/68966 + +Tracker bug: https://bugzilla.redhat.com/show_bug.cgi?id=2075390 +--- + Doc/library/mailcap.rst | 12 +++++++++ + Lib/mailcap.py | 26 +++++++++++++++++-- + Lib/test/test_mailcap.py | 8 ++++-- + ...2-04-27-18-25-30.gh-issue-68966.gjS8zs.rst | 4 +++ + 4 files changed, 46 insertions(+), 4 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst + +diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst +index a22b5b9c9e..7aa3380fec 100644 +--- a/Doc/library/mailcap.rst ++++ b/Doc/library/mailcap.rst +@@ -60,6 +60,18 @@ standard. However, mailcap files are supported on most Unix systems. + use) to determine whether or not the mailcap line applies. :func:`findmatch` + will automatically check such conditions and skip the entry if the check fails. + ++ .. versionchanged:: 3.11 ++ ++ To prevent security issues with shell metacharacters (symbols that have ++ special effects in a shell command line), ``findmatch`` will refuse ++ to inject ASCII characters other than alphanumerics and ``@+=:,./-_`` ++ into the returned command line. ++ ++ If a disallowed character appears in *filename*, ``findmatch`` will always ++ return ``(None, None)`` as if no entry was found. ++ If such a character appears elsewhere (a value in *plist* or in *MIMEtype*), ++ ``findmatch`` will ignore all mailcap entries which use that value. ++ A :mod:`warning ` will be raised in either case. + + .. function:: getcaps() + +diff --git a/Lib/mailcap.py b/Lib/mailcap.py +index ae416a8e9f..444c6408b5 100644 +--- a/Lib/mailcap.py ++++ b/Lib/mailcap.py +@@ -2,6 +2,7 @@ + + import os + import warnings ++import re + + __all__ = ["getcaps","findmatch"] + +@@ -13,6 +14,11 @@ def lineno_sort_key(entry): + else: + return 1, 0 + ++_find_unsafe = re.compile(r'[^\xa1-\U0010FFFF\w@+=:,./-]').search ++ ++class UnsafeMailcapInput(Warning): ++ """Warning raised when refusing unsafe input""" ++ + + # Part 1: top-level interface. + +@@ -165,15 +171,22 @@ def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]): + entry to use. + + """ ++ if _find_unsafe(filename): ++ msg = "Refusing to use mailcap with filename %r. Use a safe temporary filename." % (filename,) ++ warnings.warn(msg, UnsafeMailcapInput) ++ return None, None + entries = lookup(caps, MIMEtype, key) + # XXX This code should somehow check for the needsterminal flag. + for e in entries: + if 'test' in e: + test = subst(e['test'], filename, plist) ++ if test is None: ++ continue + if test and os.system(test) != 0: + continue + command = subst(e[key], MIMEtype, filename, plist) +- return command, e ++ if command is not None: ++ return command, e + return None, None + + def lookup(caps, MIMEtype, key=None): +@@ -206,6 +219,10 @@ def subst(field, MIMEtype, filename, plist=[]): + elif c == 's': + res = res + filename + elif c == 't': ++ if _find_unsafe(MIMEtype): ++ msg = "Refusing to substitute MIME type %r into a shell command." % (MIMEtype,) ++ warnings.warn(msg, UnsafeMailcapInput) ++ return None + res = res + MIMEtype + elif c == '{': + start = i +@@ -213,7 +230,12 @@ def subst(field, MIMEtype, filename, plist=[]): + i = i+1 + name = field[start:i] + i = i+1 +- res = res + findparam(name, plist) ++ param = findparam(name, plist) ++ if _find_unsafe(param): ++ msg = "Refusing to substitute parameter %r (%s) into a shell command" % (param, name) ++ warnings.warn(msg, UnsafeMailcapInput) ++ return None ++ res = res + param + # XXX To do: + # %n == number of parts if type is multipart/* + # %F == list of alternating type and filename for parts +diff --git a/Lib/test/test_mailcap.py b/Lib/test/test_mailcap.py +index c08423c670..920283d9a2 100644 +--- a/Lib/test/test_mailcap.py ++++ b/Lib/test/test_mailcap.py +@@ -121,7 +121,8 @@ class HelperFunctionTest(unittest.TestCase): + (["", "audio/*", "foo.txt"], ""), + (["echo foo", "audio/*", "foo.txt"], "echo foo"), + (["echo %s", "audio/*", "foo.txt"], "echo foo.txt"), +- (["echo %t", "audio/*", "foo.txt"], "echo audio/*"), ++ (["echo %t", "audio/*", "foo.txt"], None), ++ (["echo %t", "audio/wav", "foo.txt"], "echo audio/wav"), + (["echo \\%t", "audio/*", "foo.txt"], "echo %t"), + (["echo foo", "audio/*", "foo.txt", plist], "echo foo"), + (["echo %{total}", "audio/*", "foo.txt", plist], "echo 3") +@@ -205,7 +206,10 @@ class FindmatchTest(unittest.TestCase): + ('"An audio fragment"', audio_basic_entry)), + ([c, "audio/*"], + {"filename": fname}, +- ("/usr/local/bin/showaudio audio/*", audio_entry)), ++ (None, None)), ++ ([c, "audio/wav"], ++ {"filename": fname}, ++ ("/usr/local/bin/showaudio audio/wav", audio_entry)), + ([c, "message/external-body"], + {"plist": plist}, + ("showexternal /dev/null default john python.org /tmp foo bar", message_entry)) +diff --git a/Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst b/Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst +new file mode 100644 +index 0000000000..da81a1f699 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst +@@ -0,0 +1,4 @@ ++The deprecated mailcap module now refuses to inject unsafe text (filenames, ++MIME types, parameters) into shell commands. Instead of using such text, it ++will warn and act as if a match was not found (or for test commands, as if ++the test failed). diff --git a/python3.9.spec b/python3.9.spec index ce2986f..bbe529c 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -387,6 +387,16 @@ Patch353: 00353-architecture-names-upstream-downstream.patch # https://github.com/GrahamDumpleton/mod_wsgi/issues/730 Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +# 00382 # 9e275dcdf3934b827994ecc3247d583d5bab7985 +# CVE-2015-20107 +# +# Make mailcap refuse to match unsafe filenames/types/params (GH-91993) +# +# Upstream: https://github.com/python/cpython/issues/68966 +# +# Tracker bug: https://bugzilla.redhat.com/show_bug.cgi?id=2075390 +Patch382: 00382-cve-2015-20107.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1805,6 +1815,10 @@ CheckPython optimized # ====================================================== %changelog +* Thu Jun 09 2022 Charalampos Stratakis - 3.9.13-2 +- Security fix for CVE-2015-20107 +Resolves: rhbz#2075390 + * Wed May 18 2022 Tomáš Hrnčiar - 3.9.13-1 - Update to 3.9.13 From 009e4351fdc54dcf8fe49124a948beb4d2e61999 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 22 Jul 2022 23:47:33 +0000 Subject: [PATCH 38/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index bbe529c..6458f90 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1815,6 +1815,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 22 2022 Fedora Release Engineering - 3.9.13-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Thu Jun 09 2022 Charalampos Stratakis - 3.9.13-2 - Security fix for CVE-2015-20107 Resolves: rhbz#2075390 From 7636db24d127095f4b1f6c71d8ca9e81e46aee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 6 Sep 2022 11:37:28 +0200 Subject: [PATCH 39/89] Remove no longer needed %apply_patch workaround All supported Fedora releases have RPM 4.17+, so we can use %autopatch with a positional argument. --- python3.9.spec | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 6458f90..649ea74 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -777,10 +777,7 @@ that support it, such as CentOS or RHEL or older Fedora releases. %autopatch -M 188 %if %{with rpmwheels} -# Temporary workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1954999 -%{?!apply_patch:%define apply_patch(qp:m:) {%__apply_patch %**}} - -%apply_patch -q %{PATCH189} +%autopatch 189 rm Lib/ensurepip/_bundled/*.whl %endif From ab27283a29c3932a88b3950aa6001b03cc8afed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 7 Sep 2022 16:13:54 +0200 Subject: [PATCH 40/89] Update to 3.9.14, with security fix for CVE-2020-10735 --- 00111-no-static-lib.patch | 4 ++-- 00189-use-rpm-wheels.patch | 4 ++-- python3.9.spec | 8 ++++++-- sources | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 51e0e36..d6ac5d4 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 42b1ec622a..c1cf1585df 100644 +index c0272bfcdd..b64837c126 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -588,7 +588,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c @@ -55,7 +55,7 @@ index 42b1ec622a..c1cf1585df 100644 $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) ############################################################################ -@@ -1651,17 +1645,6 @@ libainstall: @DEF_MAKE_RULE@ python-config +@@ -1652,17 +1646,6 @@ libainstall: @DEF_MAKE_RULE@ python-config else true; \ fi; \ done diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 0fed4aa..4b0fe64 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index e510cc7fb2..5bd16a6c59 100644 +index 981534c4a0..77d7ec5a65 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -55,7 +55,7 @@ index e510cc7fb2..5bd16a6c59 100644 _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), -@@ -101,13 +119,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False, +@@ -106,13 +124,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False, # additional paths that need added to sys.path additional_paths = [] for project, version, py_tag in _PROJECTS: diff --git a/python3.9.spec b/python3.9.spec index 649ea74..d079a70 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.13 +%global general_version %{pybasever}.14 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -1812,6 +1812,10 @@ CheckPython optimized # ====================================================== %changelog +* Wed Sep 07 2022 Miro Hrončok - 3.9.14-1 +- Update to 3.9.14 +- Contains security fix for CVE-2020-10735 + * Fri Jul 22 2022 Fedora Release Engineering - 3.9.13-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild diff --git a/sources b/sources index faf7226..ee13827 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.13.tar.xz) = e9664e7f908092df11236b22465d217531d6f0378e88d889108d19fe77f28f46ffb629b8733f84b41409e255367321893a2b1bd64518930d9d8cae5d1b774d23 -SHA512 (Python-3.9.13.tar.xz.asc) = 9367afe8ec32195adbb64fa32eb9e3881cfdbbb38efcb5e0804a15486232aecbc81ed20a8ffed652f06a881744f3efd2c2df3cc652d70671c94d6668a17a391e +SHA512 (Python-3.9.14.tar.xz) = 691a7814cf6c7bee96d8dbb7c5c85cb11f2e999101e20491b99435cdec07c3bbd5ce43ad3d9c64f695383b79197884caa1965c4346e4525e23b09c686271e4ab +SHA512 (Python-3.9.14.tar.xz.asc) = 7cffff00ecc94d32a61e763b4ebd73caf83994e3a24b682d45453f34631e4feabcffbaae5e511952656ab6e64945bc2a3d1fb440f788352f262ffa00ec3d2203 From 4a5d76b5fe04c1c9613babbe8eb708b2d84074cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 12 Oct 2022 15:49:00 +0200 Subject: [PATCH 41/89] Update to 3.9.15 --- python3.9.spec | 5 ++++- sources | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index d079a70..d81a745 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.14 +%global general_version %{pybasever}.15 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1812,6 +1812,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Oct 12 2022 Miro Hrončok - 3.9.15-1 +- Update to 3.9.15 + * Wed Sep 07 2022 Miro Hrončok - 3.9.14-1 - Update to 3.9.14 - Contains security fix for CVE-2020-10735 diff --git a/sources b/sources index ee13827..8118ab8 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.14.tar.xz) = 691a7814cf6c7bee96d8dbb7c5c85cb11f2e999101e20491b99435cdec07c3bbd5ce43ad3d9c64f695383b79197884caa1965c4346e4525e23b09c686271e4ab -SHA512 (Python-3.9.14.tar.xz.asc) = 7cffff00ecc94d32a61e763b4ebd73caf83994e3a24b682d45453f34631e4feabcffbaae5e511952656ab6e64945bc2a3d1fb440f788352f262ffa00ec3d2203 +SHA512 (Python-3.9.15.tar.xz) = 9310d263bc7a7925f73a6f66fd254ae61f377f43011a6bc5c58e57c8b170c2da4f197a646927ab9d05f8912ed8be4369c09576063931a3f93c3b0228ccb33a39 +SHA512 (Python-3.9.15.tar.xz.asc) = 722625091731536757b9db447590c31620665133d45076367a3281f2ee3add23a781b10ce5cea582d65caabb18814583c1a347689d2b396214e36a6771182f38 From 3bae8212c1917e7236014cdc0ba0418aa454c254 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Wed, 9 Nov 2022 12:32:02 +0100 Subject: [PATCH 42/89] Fix for CVE-2022-42919 --- ...abstract-sockets-for-multiprocessing.patch | 64 +++++++++++++++++++ python3.9.spec | 23 ++++++- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch diff --git a/00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch b/00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch new file mode 100644 index 0000000..0214c3a --- /dev/null +++ b/00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Fri, 28 Oct 2022 03:08:30 -0700 +Subject: [PATCH] 00391: Don't use Linux abstract sockets for multiprocessing + +Linux abstract sockets are insecure as they lack any form of filesystem +permissions so their use allows anyone on the system to inject code into +the process. + +This removes the default preference for abstract sockets in +multiprocessing introduced in Python 3.9+ via +https://github.com/python/cpython/pull/18866 while fixing +https://github.com/python/cpython/issues/84031. + +Explicit use of an abstract socket by a user now generates a +RuntimeWarning. If we choose to keep this warning, it should be +backported to the 3.7 and 3.8 branches. +(cherry picked from commit 49f61068f49747164988ffc5a442d2a63874fc17) + +Co-authored-by: Gregory P. Smith +--- + Lib/multiprocessing/connection.py | 5 ----- + .../2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst | 15 +++++++++++++++ + 2 files changed, 15 insertions(+), 5 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst + +diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py +index 510e4b5aba..8e2facf92a 100644 +--- a/Lib/multiprocessing/connection.py ++++ b/Lib/multiprocessing/connection.py +@@ -73,11 +73,6 @@ def arbitrary_address(family): + if family == 'AF_INET': + return ('localhost', 0) + elif family == 'AF_UNIX': +- # Prefer abstract sockets if possible to avoid problems with the address +- # size. When coding portable applications, some implementations have +- # sun_path as short as 92 bytes in the sockaddr_un struct. +- if util.abstract_sockets_supported: +- return f"\0listener-{os.getpid()}-{next(_mmap_counter)}" + return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) + elif family == 'AF_PIPE': + return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % +diff --git a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst +new file mode 100644 +index 0000000000..02d95b5705 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst +@@ -0,0 +1,15 @@ ++On Linux the :mod:`multiprocessing` module returns to using filesystem backed ++unix domain sockets for communication with the *forkserver* process instead of ++the Linux abstract socket namespace. Only code that chooses to use the ++:ref:`"forkserver" start method ` is affected. ++ ++Abstract sockets have no permissions and could allow any user on the system in ++the same `network namespace ++`_ (often the ++whole system) to inject code into the multiprocessing *forkserver* process. ++This was a potential privilege escalation. Filesystem based socket permissions ++restrict this to the *forkserver* process user as was the default in Python 3.8 ++and earlier. ++ ++This prevents Linux `CVE-2022-42919 ++`_. diff --git a/python3.9.spec b/python3.9.spec index d81a745..969d7e4 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -397,6 +397,23 @@ Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-g # Tracker bug: https://bugzilla.redhat.com/show_bug.cgi?id=2075390 Patch382: 00382-cve-2015-20107.patch +# 00391 # e6d12d8fca6afad3a56dc076c220f213b723a28e +# Don't use Linux abstract sockets for multiprocessing +# +# Linux abstract sockets are insecure as they lack any form of filesystem +# permissions so their use allows anyone on the system to inject code into +# the process. +# +# This removes the default preference for abstract sockets in +# multiprocessing introduced in Python 3.9+ via +# https://github.com/python/cpython/pull/18866 while fixing +# https://github.com/python/cpython/issues/84031. +# +# Explicit use of an abstract socket by a user now generates a +# RuntimeWarning. If we choose to keep this warning, it should be +# backported to the 3.7 and 3.8 branches. +Patch391: 00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1812,6 +1829,10 @@ CheckPython optimized # ====================================================== %changelog +* Wed Nov 09 2022 Lumír Balhar - 3.9.15-2 +- Fix for CVE-2022-42919 +Resolves: rhbz#2138711 + * Wed Oct 12 2022 Miro Hrončok - 3.9.15-1 - Update to 3.9.15 From 66cc30cc449485a8900b0867dcc360e36e1bea17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 17 Nov 2022 14:47:28 +0100 Subject: [PATCH 43/89] Rebuilt for infrastructure problems --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 969d7e4..7e4d39f 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1829,6 +1829,9 @@ CheckPython optimized # ====================================================== %changelog +* Thu Nov 17 2022 Miro Hrončok - 3.9.15-3 +- Rebuilt for infrastructure problems + * Wed Nov 09 2022 Lumír Balhar - 3.9.15-2 - Fix for CVE-2022-42919 Resolves: rhbz#2138711 From 3afb6269685589fa3fcc9536c5054e22a3662a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 7 Dec 2022 10:00:16 +0100 Subject: [PATCH 44/89] Update to 3.9.16 --- 00382-cve-2015-20107.patch | 150 ------------------ ...abstract-sockets-for-multiprocessing.patch | 64 -------- python3.9.spec | 34 +--- sources | 4 +- 4 files changed, 7 insertions(+), 245 deletions(-) delete mode 100644 00382-cve-2015-20107.patch delete mode 100644 00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch diff --git a/00382-cve-2015-20107.patch b/00382-cve-2015-20107.patch deleted file mode 100644 index 619f636..0000000 --- a/00382-cve-2015-20107.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Petr Viktorin -Date: Fri, 3 Jun 2022 11:43:35 +0200 -Subject: [PATCH] 00382: CVE-2015-20107 - -Make mailcap refuse to match unsafe filenames/types/params (GH-91993) - -Upstream: https://github.com/python/cpython/issues/68966 - -Tracker bug: https://bugzilla.redhat.com/show_bug.cgi?id=2075390 ---- - Doc/library/mailcap.rst | 12 +++++++++ - Lib/mailcap.py | 26 +++++++++++++++++-- - Lib/test/test_mailcap.py | 8 ++++-- - ...2-04-27-18-25-30.gh-issue-68966.gjS8zs.rst | 4 +++ - 4 files changed, 46 insertions(+), 4 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst - -diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst -index a22b5b9c9e..7aa3380fec 100644 ---- a/Doc/library/mailcap.rst -+++ b/Doc/library/mailcap.rst -@@ -60,6 +60,18 @@ standard. However, mailcap files are supported on most Unix systems. - use) to determine whether or not the mailcap line applies. :func:`findmatch` - will automatically check such conditions and skip the entry if the check fails. - -+ .. versionchanged:: 3.11 -+ -+ To prevent security issues with shell metacharacters (symbols that have -+ special effects in a shell command line), ``findmatch`` will refuse -+ to inject ASCII characters other than alphanumerics and ``@+=:,./-_`` -+ into the returned command line. -+ -+ If a disallowed character appears in *filename*, ``findmatch`` will always -+ return ``(None, None)`` as if no entry was found. -+ If such a character appears elsewhere (a value in *plist* or in *MIMEtype*), -+ ``findmatch`` will ignore all mailcap entries which use that value. -+ A :mod:`warning ` will be raised in either case. - - .. function:: getcaps() - -diff --git a/Lib/mailcap.py b/Lib/mailcap.py -index ae416a8e9f..444c6408b5 100644 ---- a/Lib/mailcap.py -+++ b/Lib/mailcap.py -@@ -2,6 +2,7 @@ - - import os - import warnings -+import re - - __all__ = ["getcaps","findmatch"] - -@@ -13,6 +14,11 @@ def lineno_sort_key(entry): - else: - return 1, 0 - -+_find_unsafe = re.compile(r'[^\xa1-\U0010FFFF\w@+=:,./-]').search -+ -+class UnsafeMailcapInput(Warning): -+ """Warning raised when refusing unsafe input""" -+ - - # Part 1: top-level interface. - -@@ -165,15 +171,22 @@ def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]): - entry to use. - - """ -+ if _find_unsafe(filename): -+ msg = "Refusing to use mailcap with filename %r. Use a safe temporary filename." % (filename,) -+ warnings.warn(msg, UnsafeMailcapInput) -+ return None, None - entries = lookup(caps, MIMEtype, key) - # XXX This code should somehow check for the needsterminal flag. - for e in entries: - if 'test' in e: - test = subst(e['test'], filename, plist) -+ if test is None: -+ continue - if test and os.system(test) != 0: - continue - command = subst(e[key], MIMEtype, filename, plist) -- return command, e -+ if command is not None: -+ return command, e - return None, None - - def lookup(caps, MIMEtype, key=None): -@@ -206,6 +219,10 @@ def subst(field, MIMEtype, filename, plist=[]): - elif c == 's': - res = res + filename - elif c == 't': -+ if _find_unsafe(MIMEtype): -+ msg = "Refusing to substitute MIME type %r into a shell command." % (MIMEtype,) -+ warnings.warn(msg, UnsafeMailcapInput) -+ return None - res = res + MIMEtype - elif c == '{': - start = i -@@ -213,7 +230,12 @@ def subst(field, MIMEtype, filename, plist=[]): - i = i+1 - name = field[start:i] - i = i+1 -- res = res + findparam(name, plist) -+ param = findparam(name, plist) -+ if _find_unsafe(param): -+ msg = "Refusing to substitute parameter %r (%s) into a shell command" % (param, name) -+ warnings.warn(msg, UnsafeMailcapInput) -+ return None -+ res = res + param - # XXX To do: - # %n == number of parts if type is multipart/* - # %F == list of alternating type and filename for parts -diff --git a/Lib/test/test_mailcap.py b/Lib/test/test_mailcap.py -index c08423c670..920283d9a2 100644 ---- a/Lib/test/test_mailcap.py -+++ b/Lib/test/test_mailcap.py -@@ -121,7 +121,8 @@ class HelperFunctionTest(unittest.TestCase): - (["", "audio/*", "foo.txt"], ""), - (["echo foo", "audio/*", "foo.txt"], "echo foo"), - (["echo %s", "audio/*", "foo.txt"], "echo foo.txt"), -- (["echo %t", "audio/*", "foo.txt"], "echo audio/*"), -+ (["echo %t", "audio/*", "foo.txt"], None), -+ (["echo %t", "audio/wav", "foo.txt"], "echo audio/wav"), - (["echo \\%t", "audio/*", "foo.txt"], "echo %t"), - (["echo foo", "audio/*", "foo.txt", plist], "echo foo"), - (["echo %{total}", "audio/*", "foo.txt", plist], "echo 3") -@@ -205,7 +206,10 @@ class FindmatchTest(unittest.TestCase): - ('"An audio fragment"', audio_basic_entry)), - ([c, "audio/*"], - {"filename": fname}, -- ("/usr/local/bin/showaudio audio/*", audio_entry)), -+ (None, None)), -+ ([c, "audio/wav"], -+ {"filename": fname}, -+ ("/usr/local/bin/showaudio audio/wav", audio_entry)), - ([c, "message/external-body"], - {"plist": plist}, - ("showexternal /dev/null default john python.org /tmp foo bar", message_entry)) -diff --git a/Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst b/Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst -new file mode 100644 -index 0000000000..da81a1f699 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2022-04-27-18-25-30.gh-issue-68966.gjS8zs.rst -@@ -0,0 +1,4 @@ -+The deprecated mailcap module now refuses to inject unsafe text (filenames, -+MIME types, parameters) into shell commands. Instead of using such text, it -+will warn and act as if a match was not found (or for test commands, as if -+the test failed). diff --git a/00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch b/00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch deleted file mode 100644 index 0214c3a..0000000 --- a/00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Fri, 28 Oct 2022 03:08:30 -0700 -Subject: [PATCH] 00391: Don't use Linux abstract sockets for multiprocessing - -Linux abstract sockets are insecure as they lack any form of filesystem -permissions so their use allows anyone on the system to inject code into -the process. - -This removes the default preference for abstract sockets in -multiprocessing introduced in Python 3.9+ via -https://github.com/python/cpython/pull/18866 while fixing -https://github.com/python/cpython/issues/84031. - -Explicit use of an abstract socket by a user now generates a -RuntimeWarning. If we choose to keep this warning, it should be -backported to the 3.7 and 3.8 branches. -(cherry picked from commit 49f61068f49747164988ffc5a442d2a63874fc17) - -Co-authored-by: Gregory P. Smith ---- - Lib/multiprocessing/connection.py | 5 ----- - .../2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst | 15 +++++++++++++++ - 2 files changed, 15 insertions(+), 5 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst - -diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py -index 510e4b5aba..8e2facf92a 100644 ---- a/Lib/multiprocessing/connection.py -+++ b/Lib/multiprocessing/connection.py -@@ -73,11 +73,6 @@ def arbitrary_address(family): - if family == 'AF_INET': - return ('localhost', 0) - elif family == 'AF_UNIX': -- # Prefer abstract sockets if possible to avoid problems with the address -- # size. When coding portable applications, some implementations have -- # sun_path as short as 92 bytes in the sockaddr_un struct. -- if util.abstract_sockets_supported: -- return f"\0listener-{os.getpid()}-{next(_mmap_counter)}" - return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) - elif family == 'AF_PIPE': - return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % -diff --git a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst -new file mode 100644 -index 0000000000..02d95b5705 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst -@@ -0,0 +1,15 @@ -+On Linux the :mod:`multiprocessing` module returns to using filesystem backed -+unix domain sockets for communication with the *forkserver* process instead of -+the Linux abstract socket namespace. Only code that chooses to use the -+:ref:`"forkserver" start method ` is affected. -+ -+Abstract sockets have no permissions and could allow any user on the system in -+the same `network namespace -+`_ (often the -+whole system) to inject code into the multiprocessing *forkserver* process. -+This was a potential privilege escalation. Filesystem based socket permissions -+restrict this to the *forkserver* process user as was the default in Python 3.8 -+and earlier. -+ -+This prevents Linux `CVE-2022-42919 -+`_. diff --git a/python3.9.spec b/python3.9.spec index 7e4d39f..c27334d 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.15 +%global general_version %{pybasever}.16 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -387,33 +387,6 @@ Patch353: 00353-architecture-names-upstream-downstream.patch # https://github.com/GrahamDumpleton/mod_wsgi/issues/730 Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch -# 00382 # 9e275dcdf3934b827994ecc3247d583d5bab7985 -# CVE-2015-20107 -# -# Make mailcap refuse to match unsafe filenames/types/params (GH-91993) -# -# Upstream: https://github.com/python/cpython/issues/68966 -# -# Tracker bug: https://bugzilla.redhat.com/show_bug.cgi?id=2075390 -Patch382: 00382-cve-2015-20107.patch - -# 00391 # e6d12d8fca6afad3a56dc076c220f213b723a28e -# Don't use Linux abstract sockets for multiprocessing -# -# Linux abstract sockets are insecure as they lack any form of filesystem -# permissions so their use allows anyone on the system to inject code into -# the process. -# -# This removes the default preference for abstract sockets in -# multiprocessing introduced in Python 3.9+ via -# https://github.com/python/cpython/pull/18866 while fixing -# https://github.com/python/cpython/issues/84031. -# -# Explicit use of an abstract socket by a user now generates a -# RuntimeWarning. If we choose to keep this warning, it should be -# backported to the 3.7 and 3.8 branches. -Patch391: 00391-don-t-use-linux-abstract-sockets-for-multiprocessing.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1829,6 +1802,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Dec 07 2022 Tomáš Hrnčiar - 3.9.16-1 +- Update to 3.9.16 + * Thu Nov 17 2022 Miro Hrončok - 3.9.15-3 - Rebuilt for infrastructure problems diff --git a/sources b/sources index 8118ab8..3885014 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.15.tar.xz) = 9310d263bc7a7925f73a6f66fd254ae61f377f43011a6bc5c58e57c8b170c2da4f197a646927ab9d05f8912ed8be4369c09576063931a3f93c3b0228ccb33a39 -SHA512 (Python-3.9.15.tar.xz.asc) = 722625091731536757b9db447590c31620665133d45076367a3281f2ee3add23a781b10ce5cea582d65caabb18814583c1a347689d2b396214e36a6771182f38 +SHA512 (Python-3.9.16.tar.xz) = b5fd0afe131c82bbce6ddf887c59eef6945910d6a9a2bc87c0927f4e4a096bf9ca4d25bcb729c40f6ebb8a65fbe8bf7b0b97a7c4a8c9e551240eb4f34b878653 +SHA512 (Python-3.9.16.tar.xz.asc) = 468959c36a3ec6136f57a39475fff4745a25be0cb5d3d58cf3e5faf0b9ce2d2a8b89f1f9fea1479c4c6ad12ac49e97c1cfd4291c978bb3d30df5a582ec315210 From e8f06b736b1fb203e5825bd870c9704c1a05eb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 21 Dec 2022 11:41:55 +0000 Subject: [PATCH 45/89] No longer patch the default bytecode cache invalidation policy That is, drop patch 328. Fixes https://bugzilla.redhat.com/2133850 See also https://src.fedoraproject.org/rpms/python-rpm-macros/pull-request/154 This is part of https://fedoraproject.org/wiki/Changes/ReproducibleBuildsClampMtimes --- 00328-pyc-timestamp-invalidation-mode.patch | 54 --------------------- check-pyc-timestamps.py | 8 ++- python3.9.spec | 31 ++++++------ 3 files changed, 18 insertions(+), 75 deletions(-) delete mode 100644 00328-pyc-timestamp-invalidation-mode.patch diff --git a/00328-pyc-timestamp-invalidation-mode.patch b/00328-pyc-timestamp-invalidation-mode.patch deleted file mode 100644 index fbe9ed5..0000000 --- a/00328-pyc-timestamp-invalidation-mode.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Thu, 11 Jul 2019 13:44:13 +0200 -Subject: [PATCH] 00328: Restore pyc to TIMESTAMP invalidation mode as default - in rpmbuild - -Since Fedora 31, the $SOURCE_DATE_EPOCH is set in rpmbuild to the latest -%changelog date. This makes Python default to the CHECKED_HASH pyc -invalidation mode, bringing more reproducible builds traded for an import -performance decrease. To avoid that, we don't default to CHECKED_HASH -when $RPM_BUILD_ROOT is set (i.e. when we are building RPM packages). - -See https://src.fedoraproject.org/rpms/redhat-rpm-config/pull-request/57#comment-27426 -Downstream only: only used when building RPM packages -Ideally, we should talk to upstream and explain why we don't want this ---- - Lib/py_compile.py | 3 ++- - Lib/test/test_py_compile.py | 2 ++ - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/Lib/py_compile.py b/Lib/py_compile.py -index a81f493731..bba3642bf2 100644 ---- a/Lib/py_compile.py -+++ b/Lib/py_compile.py -@@ -70,7 +70,8 @@ class PycInvalidationMode(enum.Enum): - - - def _get_default_invalidation_mode(): -- if os.environ.get('SOURCE_DATE_EPOCH'): -+ if (os.environ.get('SOURCE_DATE_EPOCH') and not -+ os.environ.get('RPM_BUILD_ROOT')): - return PycInvalidationMode.CHECKED_HASH - else: - return PycInvalidationMode.TIMESTAMP -diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py -index e6791c6916..b2d3dcf7fb 100644 ---- a/Lib/test/test_py_compile.py -+++ b/Lib/test/test_py_compile.py -@@ -19,6 +19,7 @@ def without_source_date_epoch(fxn): - def wrapper(*args, **kwargs): - with support.EnvironmentVarGuard() as env: - env.unset('SOURCE_DATE_EPOCH') -+ env.unset('RPM_BUILD_ROOT') - return fxn(*args, **kwargs) - return wrapper - -@@ -29,6 +30,7 @@ def with_source_date_epoch(fxn): - def wrapper(*args, **kwargs): - with support.EnvironmentVarGuard() as env: - env['SOURCE_DATE_EPOCH'] = '123456789' -+ env.unset('RPM_BUILD_ROOT') - return fxn(*args, **kwargs) - return wrapper - diff --git a/check-pyc-timestamps.py b/check-pyc-timestamps.py index 91af4fd..e421fca 100644 --- a/check-pyc-timestamps.py +++ b/check-pyc-timestamps.py @@ -19,11 +19,9 @@ not_compiled = [ '*/test/bad_coding.py', '*/test/bad_coding2.py', '*/test/badsyntax_*.py', - '*/lib2to3/tests/data/bom.py', - '*/lib2to3/tests/data/crlf.py', - '*/lib2to3/tests/data/different_encoding.py', - '*/lib2to3/tests/data/false_encoding.py', - '*/lib2to3/tests/data/py2_test_grammar.py', + '*/lib2to3/tests/data/*.py', + '*/lib2to3/tests/data/*/*.py', + '*/lib2to3/tests/data/*/*/*.py', '*.debug-gdb.py', ] diff --git a/python3.9.spec b/python3.9.spec index c27334d..9c8729a 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -337,20 +337,6 @@ Patch189: 00189-use-rpm-wheels.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=2014513 Patch251: 00251-change-user-install-location.patch -# 00328 # 367fdcb5a075f083aea83ac174999272a8faf75c -# Restore pyc to TIMESTAMP invalidation mode as default in rpmbuild -# -# Since Fedora 31, the $SOURCE_DATE_EPOCH is set in rpmbuild to the latest -# %%changelog date. This makes Python default to the CHECKED_HASH pyc -# invalidation mode, bringing more reproducible builds traded for an import -# performance decrease. To avoid that, we don't default to CHECKED_HASH -# when $RPM_BUILD_ROOT is set (i.e. when we are building RPM packages). -# -# See https://src.fedoraproject.org/rpms/redhat-rpm-config/pull-request/57#comment-27426 -# Downstream only: only used when building RPM packages -# Ideally, we should talk to upstream and explain why we don't want this -Patch328: 00328-pyc-timestamp-invalidation-mode.patch - # 00353 # ab4cc97b643cfe99f567e3a03e5617b507183771 # Original names for architectures with different names downstream # @@ -1099,15 +1085,25 @@ find . -name "*~" -exec rm -f {} \; # Python CMD line options: # -s - don't add user site directory to sys.path # -B - don't write .pyc files on import +# Clamp the source mtime first, see https://fedoraproject.org/wiki/Changes/ReproducibleBuildsClampMtimes +# The clamp_source_mtime module is only guaranteed to exist on Fedoras that enabled this option: +%if 0%{?clamp_mtime_to_source_date_epoch} +LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ +PYTHONPATH="%{_rpmconfigdir}/redhat" \ +%{buildroot}%{_bindir}/python%{pybasever} -s -B -m clamp_source_mtime %{buildroot}%{pylibdir} +%endif # compileall CMD line options: # -f - force rebuild even if timestamps are up to date # -o - optimization levels to run compilation with # -s - part of path to left-strip from path to source file (buildroot) # -p - path to add as prefix to path to source file (/ to make it absolute) # --hardlink-dupes - hardlink different optimization level pycs together if identical (saves space) +# --invalidation-mode - we prefer the timestamp invalidation mode for performance reasons +# -x - skip test modules with SyntaxErrors (taken from the Makefile) LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ %{buildroot}%{_bindir}/python%{pybasever} -s -B -m compileall \ --f %{_smp_mflags} -o 0 -o 1 -o 2 -s %{buildroot} -p / %{buildroot} --hardlink-dupes || : +-f %{_smp_mflags} -o 0 -o 1 -o 2 -s %{buildroot} -p / %{buildroot} --hardlink-dupes --invalidation-mode=timestamp \ +-x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' # Turn this BRP off, it is done by compileall2 --hardlink-dupes above %global __brp_python_hardlink %{nil} @@ -1802,6 +1798,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Jan 03 2023 Miro Hrončok - 3.9.16-2 +- No longer patch the default bytecode cache invalidation policy + * Wed Dec 07 2022 Tomáš Hrnčiar - 3.9.16-1 - Update to 3.9.16 From 9b71f8369141c1840c8d87db1655fcefc576ddff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 6 Jan 2023 11:05:28 +0000 Subject: [PATCH 46/89] Opt-out from https://fedoraproject.org/wiki/Changes/fno-omit-frame-pointer See https://lists.fedoraproject.org/archives/list/python-devel@lists.fedoraproject.org/thread/6TQYCHMX4FZLF27U5BCEC7IFV6XNBKJP/ for rationale, namely https://lists.fedoraproject.org/archives/list/python-devel@lists.fedoraproject.org/message/ZVDEXGPU6JQFXB3XHYZ4IXVQNNR3YM3V/ Summary: Python is currently slower with frame pointers due to a slowdown in _PyEval_EvalFrameDefault, but we expect this to be solved in Python 3.12. Tracking bugzilla: https://bugzilla.redhat.com/2158729 This change does not require a release bump. It is only needed to be here to prevent the next builds from including frame pointers. --- python3.9.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python3.9.spec b/python3.9.spec index 9c8729a..7d613c4 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -201,6 +201,12 @@ License: Python %{warn:Doing a main_python build with wrong %%__default_python3_pkgversion (0%{?__default_python3_pkgversion}, but this is %pyshortver)} %endif +# Opt-out from https://fedoraproject.org/wiki/Changes/fno-omit-frame-pointer +# Python is slower with frame pointers, but we expect to remove this in Python 3.12+ +# See https://lists.fedoraproject.org/archives/list/python-devel@lists.fedoraproject.org/thread/6TQYCHMX4FZLF27U5BCEC7IFV6XNBKJP/ +# Tracking bugzilla: https://bugzilla.redhat.com/2158729 +%undefine _include_frame_pointers + # ======================= # Build-time requirements # ======================= From 26dc60a272aa9f901ecf6a987d17bd64d43897a8 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 20 Jan 2023 18:45:57 +0000 Subject: [PATCH 47/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 7d613c4..2d81e29 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1804,6 +1804,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jan 20 2023 Fedora Release Engineering - 3.9.16-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Tue Jan 03 2023 Miro Hrončok - 3.9.16-2 - No longer patch the default bytecode cache invalidation policy From 1d79558046773a528e9796106d67cd816aca1dfa Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Fri, 26 May 2023 02:15:16 +0200 Subject: [PATCH 48/89] Security fix for CVE-2023-24329 Resolves: rhbz#2174016 --- 00399-cve-2023-24329.patch | 229 +++++++++++++++++++++++++++++++++++++ python3.9.spec | 18 ++- 2 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 00399-cve-2023-24329.patch diff --git a/00399-cve-2023-24329.patch b/00399-cve-2023-24329.patch new file mode 100644 index 0000000..ee526d3 --- /dev/null +++ b/00399-cve-2023-24329.patch @@ -0,0 +1,229 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Wed, 17 May 2023 14:41:25 -0700 +Subject: [PATCH] 00399: CVE-2023-24329 + +* gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508) + +`urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595. + +This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%20any%20leading%20and%20trailing%20C0%20control%20or%20space%20from%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329). + +--------- + +(cherry picked from commit 2f630e1ce18ad2e07428296532a68b11dc66ad10) + +Co-authored-by: Illia Volochii +Co-authored-by: Gregory P. Smith [Google] +--- + Doc/library/urllib.parse.rst | 46 +++++++++++++- + Lib/test/test_urlparse.py | 61 ++++++++++++++++++- + Lib/urllib/parse.py | 12 ++++ + ...-03-07-20-59-17.gh-issue-102153.14CLSZ.rst | 3 + + 4 files changed, 119 insertions(+), 3 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst + +diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst +index f0f8605128..c76b5879ea 100644 +--- a/Doc/library/urllib.parse.rst ++++ b/Doc/library/urllib.parse.rst +@@ -159,6 +159,10 @@ or on combining URL components into a URL string. + ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', + params='', query='', fragment='') + ++ .. warning:: ++ ++ :func:`urlparse` does not perform validation. See :ref:`URL parsing ++ security ` for details. + + .. versionchanged:: 3.2 + Added IPv6 URL parsing capabilities. +@@ -323,8 +327,14 @@ or on combining URL components into a URL string. + ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is + decomposed before parsing, no error will be raised. + +- Following the `WHATWG spec`_ that updates RFC 3986, ASCII newline +- ``\n``, ``\r`` and tab ``\t`` characters are stripped from the URL. ++ Following some of the `WHATWG spec`_ that updates RFC 3986, leading C0 ++ control and space characters are stripped from the URL. ``\n``, ++ ``\r`` and tab ``\t`` characters are removed from the URL at any position. ++ ++ .. warning:: ++ ++ :func:`urlsplit` does not perform validation. See :ref:`URL parsing ++ security ` for details. + + .. versionchanged:: 3.6 + Out-of-range port numbers now raise :exc:`ValueError`, instead of +@@ -337,6 +347,9 @@ or on combining URL components into a URL string. + .. versionchanged:: 3.9.5 + ASCII newline and tab characters are stripped from the URL. + ++ .. versionchanged:: 3.11.4 ++ Leading WHATWG C0 control and space characters are stripped from the URL. ++ + .. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser + + .. function:: urlunsplit(parts) +@@ -413,6 +426,35 @@ or on combining URL components into a URL string. + or ``scheme://host/path``). If *url* is not a wrapped URL, it is returned + without changes. + ++.. _url-parsing-security: ++ ++URL parsing security ++-------------------- ++ ++The :func:`urlsplit` and :func:`urlparse` APIs do not perform **validation** of ++inputs. They may not raise errors on inputs that other applications consider ++invalid. They may also succeed on some inputs that might not be considered ++URLs elsewhere. Their purpose is for practical functionality rather than ++purity. ++ ++Instead of raising an exception on unusual input, they may instead return some ++component parts as empty strings. Or components may contain more than perhaps ++they should. ++ ++We recommend that users of these APIs where the values may be used anywhere ++with security implications code defensively. Do some verification within your ++code before trusting a returned component part. Does that ``scheme`` make ++sense? Is that a sensible ``path``? Is there anything strange about that ++``hostname``? etc. ++ ++What constitutes a URL is not universally well defined. Different applications ++have different needs and desired constraints. For instance the living `WHATWG ++spec`_ describes what user facing web clients such as a web browser require. ++While :rfc:`3986` is more general. These functions incorporate some aspects of ++both, but cannot be claimed compliant with either. The APIs and existing user ++code with expectations on specific behaviors predate both standards leading us ++to be very cautious about making API behavior changes. ++ + .. _parsing-ascii-encoded-bytes: + + Parsing ASCII Encoded Bytes +diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py +index 31943f357f..574da5bd69 100644 +--- a/Lib/test/test_urlparse.py ++++ b/Lib/test/test_urlparse.py +@@ -649,6 +649,65 @@ class UrlParseTestCase(unittest.TestCase): + self.assertEqual(p.scheme, "http") + self.assertEqual(p.geturl(), "http://www.python.org/javascript:alert('msg')/?query=something#fragment") + ++ def test_urlsplit_strip_url(self): ++ noise = bytes(range(0, 0x20 + 1)) ++ base_url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag" ++ ++ url = noise.decode("utf-8") + base_url ++ p = urllib.parse.urlsplit(url) ++ self.assertEqual(p.scheme, "http") ++ self.assertEqual(p.netloc, "User:Pass@www.python.org:080") ++ self.assertEqual(p.path, "/doc/") ++ self.assertEqual(p.query, "query=yes") ++ self.assertEqual(p.fragment, "frag") ++ self.assertEqual(p.username, "User") ++ self.assertEqual(p.password, "Pass") ++ self.assertEqual(p.hostname, "www.python.org") ++ self.assertEqual(p.port, 80) ++ self.assertEqual(p.geturl(), base_url) ++ ++ url = noise + base_url.encode("utf-8") ++ p = urllib.parse.urlsplit(url) ++ self.assertEqual(p.scheme, b"http") ++ self.assertEqual(p.netloc, b"User:Pass@www.python.org:080") ++ self.assertEqual(p.path, b"/doc/") ++ self.assertEqual(p.query, b"query=yes") ++ self.assertEqual(p.fragment, b"frag") ++ self.assertEqual(p.username, b"User") ++ self.assertEqual(p.password, b"Pass") ++ self.assertEqual(p.hostname, b"www.python.org") ++ self.assertEqual(p.port, 80) ++ self.assertEqual(p.geturl(), base_url.encode("utf-8")) ++ ++ # Test that trailing space is preserved as some applications rely on ++ # this within query strings. ++ query_spaces_url = "https://www.python.org:88/doc/?query= " ++ p = urllib.parse.urlsplit(noise.decode("utf-8") + query_spaces_url) ++ self.assertEqual(p.scheme, "https") ++ self.assertEqual(p.netloc, "www.python.org:88") ++ self.assertEqual(p.path, "/doc/") ++ self.assertEqual(p.query, "query= ") ++ self.assertEqual(p.port, 88) ++ self.assertEqual(p.geturl(), query_spaces_url) ++ ++ p = urllib.parse.urlsplit("www.pypi.org ") ++ # That "hostname" gets considered a "path" due to the ++ # trailing space and our existing logic... YUCK... ++ # and re-assembles via geturl aka unurlsplit into the original. ++ # django.core.validators.URLValidator (at least through v3.2) relies on ++ # this, for better or worse, to catch it in a ValidationError via its ++ # regular expressions. ++ # Here we test the basic round trip concept of such a trailing space. ++ self.assertEqual(urllib.parse.urlunsplit(p), "www.pypi.org ") ++ ++ # with scheme as cache-key ++ url = "//www.python.org/" ++ scheme = noise.decode("utf-8") + "https" + noise.decode("utf-8") ++ for _ in range(2): ++ p = urllib.parse.urlsplit(url, scheme=scheme) ++ self.assertEqual(p.scheme, "https") ++ self.assertEqual(p.geturl(), "https://www.python.org/") ++ + def test_attributes_bad_port(self): + """Check handling of invalid ports.""" + for bytes in (False, True): +@@ -656,7 +715,7 @@ class UrlParseTestCase(unittest.TestCase): + for port in ("foo", "1.5", "-1", "0x10"): + with self.subTest(bytes=bytes, parse=parse, port=port): + netloc = "www.example.net:" + port +- url = "http://" + netloc ++ url = "http://" + netloc + "/" + if bytes: + netloc = netloc.encode("ascii") + url = url.encode("ascii") +diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py +index b7965fe3d2..5b7193f67c 100644 +--- a/Lib/urllib/parse.py ++++ b/Lib/urllib/parse.py +@@ -25,6 +25,10 @@ currently not entirely compliant with this RFC due to defacto + scenarios for parsing, and for backward compatibility purposes, some + parsing quirks from older RFCs are retained. The testcases in + test_urlparse.py provides a good indicator of parsing behavior. ++ ++The WHATWG URL Parser spec should also be considered. We are not compliant with ++it either due to existing user code API behavior expectations (Hyrum's Law). ++It serves as a useful guide when making changes. + """ + + import re +@@ -78,6 +82,10 @@ scheme_chars = ('abcdefghijklmnopqrstuvwxyz' + '0123456789' + '+-.') + ++# Leading and trailing C0 control and space to be stripped per WHATWG spec. ++# == "".join([chr(i) for i in range(0, 0x20 + 1)]) ++_WHATWG_C0_CONTROL_OR_SPACE = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ' ++ + # Unsafe bytes to be removed per WHATWG spec + _UNSAFE_URL_BYTES_TO_REMOVE = ['\t', '\r', '\n'] + +@@ -456,6 +464,10 @@ def urlsplit(url, scheme='', allow_fragments=True): + """ + + url, scheme, _coerce_result = _coerce_args(url, scheme) ++ # Only lstrip url as some applications rely on preserving trailing space. ++ # (https://url.spec.whatwg.org/#concept-basic-url-parser would strip both) ++ url = url.lstrip(_WHATWG_C0_CONTROL_OR_SPACE) ++ scheme = scheme.strip(_WHATWG_C0_CONTROL_OR_SPACE) + + for b in _UNSAFE_URL_BYTES_TO_REMOVE: + url = url.replace(b, "") +diff --git a/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst +new file mode 100644 +index 0000000000..e57ac4ed3a +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst +@@ -0,0 +1,3 @@ ++:func:`urllib.parse.urlsplit` now strips leading C0 control and space ++characters following the specification for URLs defined by WHATWG in ++response to CVE-2023-24329. Patch by Illia Volochii. diff --git a/python3.9.spec b/python3.9.spec index 2d81e29..bf53063 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 4%{?dist} License: Python @@ -379,6 +379,18 @@ Patch353: 00353-architecture-names-upstream-downstream.patch # https://github.com/GrahamDumpleton/mod_wsgi/issues/730 Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +# 00399 # c32eff86eb80f6a6bdcbf4b1b6535fbc627b51a2 +# CVE-2023-24329 +# +# * gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508) +# +# `urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595. +# +# This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%%20any%%20leading%%20and%%20trailing%%20C0%%20control%%20or%%20space%%20from%%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329). +# +# --------- +Patch399: 00399-cve-2023-24329.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1804,6 +1816,10 @@ CheckPython optimized # ====================================================== %changelog +* Mon May 29 2023 Lumír Balhar - 3.9.16-4 +- Security fix for CVE-2023-24329 +- Resolves: rhbz#2174016 + * Fri Jan 20 2023 Fedora Release Engineering - 3.9.16-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild From 9a234fc3166ac6a270261523c7195ba3a5452bf7 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Fri, 26 May 2023 02:15:16 +0200 Subject: [PATCH 49/89] Security fix for CVE-2023-24329 Resolves: rhbz#2174016 --- 00399-cve-2023-24329.patch | 229 +++++++++++++++++++++++++++++++++++++ python3.9.spec | 18 ++- 2 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 00399-cve-2023-24329.patch diff --git a/00399-cve-2023-24329.patch b/00399-cve-2023-24329.patch new file mode 100644 index 0000000..ee526d3 --- /dev/null +++ b/00399-cve-2023-24329.patch @@ -0,0 +1,229 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Wed, 17 May 2023 14:41:25 -0700 +Subject: [PATCH] 00399: CVE-2023-24329 + +* gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508) + +`urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595. + +This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%20any%20leading%20and%20trailing%20C0%20control%20or%20space%20from%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329). + +--------- + +(cherry picked from commit 2f630e1ce18ad2e07428296532a68b11dc66ad10) + +Co-authored-by: Illia Volochii +Co-authored-by: Gregory P. Smith [Google] +--- + Doc/library/urllib.parse.rst | 46 +++++++++++++- + Lib/test/test_urlparse.py | 61 ++++++++++++++++++- + Lib/urllib/parse.py | 12 ++++ + ...-03-07-20-59-17.gh-issue-102153.14CLSZ.rst | 3 + + 4 files changed, 119 insertions(+), 3 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst + +diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst +index f0f8605128..c76b5879ea 100644 +--- a/Doc/library/urllib.parse.rst ++++ b/Doc/library/urllib.parse.rst +@@ -159,6 +159,10 @@ or on combining URL components into a URL string. + ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', + params='', query='', fragment='') + ++ .. warning:: ++ ++ :func:`urlparse` does not perform validation. See :ref:`URL parsing ++ security ` for details. + + .. versionchanged:: 3.2 + Added IPv6 URL parsing capabilities. +@@ -323,8 +327,14 @@ or on combining URL components into a URL string. + ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is + decomposed before parsing, no error will be raised. + +- Following the `WHATWG spec`_ that updates RFC 3986, ASCII newline +- ``\n``, ``\r`` and tab ``\t`` characters are stripped from the URL. ++ Following some of the `WHATWG spec`_ that updates RFC 3986, leading C0 ++ control and space characters are stripped from the URL. ``\n``, ++ ``\r`` and tab ``\t`` characters are removed from the URL at any position. ++ ++ .. warning:: ++ ++ :func:`urlsplit` does not perform validation. See :ref:`URL parsing ++ security ` for details. + + .. versionchanged:: 3.6 + Out-of-range port numbers now raise :exc:`ValueError`, instead of +@@ -337,6 +347,9 @@ or on combining URL components into a URL string. + .. versionchanged:: 3.9.5 + ASCII newline and tab characters are stripped from the URL. + ++ .. versionchanged:: 3.11.4 ++ Leading WHATWG C0 control and space characters are stripped from the URL. ++ + .. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser + + .. function:: urlunsplit(parts) +@@ -413,6 +426,35 @@ or on combining URL components into a URL string. + or ``scheme://host/path``). If *url* is not a wrapped URL, it is returned + without changes. + ++.. _url-parsing-security: ++ ++URL parsing security ++-------------------- ++ ++The :func:`urlsplit` and :func:`urlparse` APIs do not perform **validation** of ++inputs. They may not raise errors on inputs that other applications consider ++invalid. They may also succeed on some inputs that might not be considered ++URLs elsewhere. Their purpose is for practical functionality rather than ++purity. ++ ++Instead of raising an exception on unusual input, they may instead return some ++component parts as empty strings. Or components may contain more than perhaps ++they should. ++ ++We recommend that users of these APIs where the values may be used anywhere ++with security implications code defensively. Do some verification within your ++code before trusting a returned component part. Does that ``scheme`` make ++sense? Is that a sensible ``path``? Is there anything strange about that ++``hostname``? etc. ++ ++What constitutes a URL is not universally well defined. Different applications ++have different needs and desired constraints. For instance the living `WHATWG ++spec`_ describes what user facing web clients such as a web browser require. ++While :rfc:`3986` is more general. These functions incorporate some aspects of ++both, but cannot be claimed compliant with either. The APIs and existing user ++code with expectations on specific behaviors predate both standards leading us ++to be very cautious about making API behavior changes. ++ + .. _parsing-ascii-encoded-bytes: + + Parsing ASCII Encoded Bytes +diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py +index 31943f357f..574da5bd69 100644 +--- a/Lib/test/test_urlparse.py ++++ b/Lib/test/test_urlparse.py +@@ -649,6 +649,65 @@ class UrlParseTestCase(unittest.TestCase): + self.assertEqual(p.scheme, "http") + self.assertEqual(p.geturl(), "http://www.python.org/javascript:alert('msg')/?query=something#fragment") + ++ def test_urlsplit_strip_url(self): ++ noise = bytes(range(0, 0x20 + 1)) ++ base_url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag" ++ ++ url = noise.decode("utf-8") + base_url ++ p = urllib.parse.urlsplit(url) ++ self.assertEqual(p.scheme, "http") ++ self.assertEqual(p.netloc, "User:Pass@www.python.org:080") ++ self.assertEqual(p.path, "/doc/") ++ self.assertEqual(p.query, "query=yes") ++ self.assertEqual(p.fragment, "frag") ++ self.assertEqual(p.username, "User") ++ self.assertEqual(p.password, "Pass") ++ self.assertEqual(p.hostname, "www.python.org") ++ self.assertEqual(p.port, 80) ++ self.assertEqual(p.geturl(), base_url) ++ ++ url = noise + base_url.encode("utf-8") ++ p = urllib.parse.urlsplit(url) ++ self.assertEqual(p.scheme, b"http") ++ self.assertEqual(p.netloc, b"User:Pass@www.python.org:080") ++ self.assertEqual(p.path, b"/doc/") ++ self.assertEqual(p.query, b"query=yes") ++ self.assertEqual(p.fragment, b"frag") ++ self.assertEqual(p.username, b"User") ++ self.assertEqual(p.password, b"Pass") ++ self.assertEqual(p.hostname, b"www.python.org") ++ self.assertEqual(p.port, 80) ++ self.assertEqual(p.geturl(), base_url.encode("utf-8")) ++ ++ # Test that trailing space is preserved as some applications rely on ++ # this within query strings. ++ query_spaces_url = "https://www.python.org:88/doc/?query= " ++ p = urllib.parse.urlsplit(noise.decode("utf-8") + query_spaces_url) ++ self.assertEqual(p.scheme, "https") ++ self.assertEqual(p.netloc, "www.python.org:88") ++ self.assertEqual(p.path, "/doc/") ++ self.assertEqual(p.query, "query= ") ++ self.assertEqual(p.port, 88) ++ self.assertEqual(p.geturl(), query_spaces_url) ++ ++ p = urllib.parse.urlsplit("www.pypi.org ") ++ # That "hostname" gets considered a "path" due to the ++ # trailing space and our existing logic... YUCK... ++ # and re-assembles via geturl aka unurlsplit into the original. ++ # django.core.validators.URLValidator (at least through v3.2) relies on ++ # this, for better or worse, to catch it in a ValidationError via its ++ # regular expressions. ++ # Here we test the basic round trip concept of such a trailing space. ++ self.assertEqual(urllib.parse.urlunsplit(p), "www.pypi.org ") ++ ++ # with scheme as cache-key ++ url = "//www.python.org/" ++ scheme = noise.decode("utf-8") + "https" + noise.decode("utf-8") ++ for _ in range(2): ++ p = urllib.parse.urlsplit(url, scheme=scheme) ++ self.assertEqual(p.scheme, "https") ++ self.assertEqual(p.geturl(), "https://www.python.org/") ++ + def test_attributes_bad_port(self): + """Check handling of invalid ports.""" + for bytes in (False, True): +@@ -656,7 +715,7 @@ class UrlParseTestCase(unittest.TestCase): + for port in ("foo", "1.5", "-1", "0x10"): + with self.subTest(bytes=bytes, parse=parse, port=port): + netloc = "www.example.net:" + port +- url = "http://" + netloc ++ url = "http://" + netloc + "/" + if bytes: + netloc = netloc.encode("ascii") + url = url.encode("ascii") +diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py +index b7965fe3d2..5b7193f67c 100644 +--- a/Lib/urllib/parse.py ++++ b/Lib/urllib/parse.py +@@ -25,6 +25,10 @@ currently not entirely compliant with this RFC due to defacto + scenarios for parsing, and for backward compatibility purposes, some + parsing quirks from older RFCs are retained. The testcases in + test_urlparse.py provides a good indicator of parsing behavior. ++ ++The WHATWG URL Parser spec should also be considered. We are not compliant with ++it either due to existing user code API behavior expectations (Hyrum's Law). ++It serves as a useful guide when making changes. + """ + + import re +@@ -78,6 +82,10 @@ scheme_chars = ('abcdefghijklmnopqrstuvwxyz' + '0123456789' + '+-.') + ++# Leading and trailing C0 control and space to be stripped per WHATWG spec. ++# == "".join([chr(i) for i in range(0, 0x20 + 1)]) ++_WHATWG_C0_CONTROL_OR_SPACE = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ' ++ + # Unsafe bytes to be removed per WHATWG spec + _UNSAFE_URL_BYTES_TO_REMOVE = ['\t', '\r', '\n'] + +@@ -456,6 +464,10 @@ def urlsplit(url, scheme='', allow_fragments=True): + """ + + url, scheme, _coerce_result = _coerce_args(url, scheme) ++ # Only lstrip url as some applications rely on preserving trailing space. ++ # (https://url.spec.whatwg.org/#concept-basic-url-parser would strip both) ++ url = url.lstrip(_WHATWG_C0_CONTROL_OR_SPACE) ++ scheme = scheme.strip(_WHATWG_C0_CONTROL_OR_SPACE) + + for b in _UNSAFE_URL_BYTES_TO_REMOVE: + url = url.replace(b, "") +diff --git a/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst +new file mode 100644 +index 0000000000..e57ac4ed3a +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst +@@ -0,0 +1,3 @@ ++:func:`urllib.parse.urlsplit` now strips leading C0 control and space ++characters following the specification for URLs defined by WHATWG in ++response to CVE-2023-24329. Patch by Illia Volochii. diff --git a/python3.9.spec b/python3.9.spec index 2d81e29..bf53063 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 4%{?dist} License: Python @@ -379,6 +379,18 @@ Patch353: 00353-architecture-names-upstream-downstream.patch # https://github.com/GrahamDumpleton/mod_wsgi/issues/730 Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +# 00399 # c32eff86eb80f6a6bdcbf4b1b6535fbc627b51a2 +# CVE-2023-24329 +# +# * gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508) +# +# `urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595. +# +# This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%%20any%%20leading%%20and%%20trailing%%20C0%%20control%%20or%%20space%%20from%%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329). +# +# --------- +Patch399: 00399-cve-2023-24329.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1804,6 +1816,10 @@ CheckPython optimized # ====================================================== %changelog +* Mon May 29 2023 Lumír Balhar - 3.9.16-4 +- Security fix for CVE-2023-24329 +- Resolves: rhbz#2174016 + * Fri Jan 20 2023 Fedora Release Engineering - 3.9.16-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild From 4b77d9d333a45a476026888a935078dd84737e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Thu, 8 Jun 2023 10:07:10 +0200 Subject: [PATCH 50/89] Update to 3.9.17 --- 00189-use-rpm-wheels.patch | 4 +- 00399-cve-2023-24329.patch | 229 ------------------------------------- python3.9.spec | 23 ++-- sources | 4 +- 4 files changed, 11 insertions(+), 249 deletions(-) delete mode 100644 00399-cve-2023-24329.patch diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 4b0fe64..dfb47f4 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 981534c4a0..77d7ec5a65 100644 +index 07065c3cb7..77d7ec5a65 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -31,7 +31,7 @@ index 981534c4a0..77d7ec5a65 100644 __all__ = ["version", "bootstrap"] -_SETUPTOOLS_VERSION = "58.1.0" --_PIP_VERSION = "22.0.4" +-_PIP_VERSION = "23.0.1" + +_WHEEL_DIR = "/usr/share/python-wheels/" + diff --git a/00399-cve-2023-24329.patch b/00399-cve-2023-24329.patch deleted file mode 100644 index ee526d3..0000000 --- a/00399-cve-2023-24329.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Wed, 17 May 2023 14:41:25 -0700 -Subject: [PATCH] 00399: CVE-2023-24329 - -* gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508) - -`urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595. - -This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%20any%20leading%20and%20trailing%20C0%20control%20or%20space%20from%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329). - ---------- - -(cherry picked from commit 2f630e1ce18ad2e07428296532a68b11dc66ad10) - -Co-authored-by: Illia Volochii -Co-authored-by: Gregory P. Smith [Google] ---- - Doc/library/urllib.parse.rst | 46 +++++++++++++- - Lib/test/test_urlparse.py | 61 ++++++++++++++++++- - Lib/urllib/parse.py | 12 ++++ - ...-03-07-20-59-17.gh-issue-102153.14CLSZ.rst | 3 + - 4 files changed, 119 insertions(+), 3 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst - -diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst -index f0f8605128..c76b5879ea 100644 ---- a/Doc/library/urllib.parse.rst -+++ b/Doc/library/urllib.parse.rst -@@ -159,6 +159,10 @@ or on combining URL components into a URL string. - ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', - params='', query='', fragment='') - -+ .. warning:: -+ -+ :func:`urlparse` does not perform validation. See :ref:`URL parsing -+ security ` for details. - - .. versionchanged:: 3.2 - Added IPv6 URL parsing capabilities. -@@ -323,8 +327,14 @@ or on combining URL components into a URL string. - ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is - decomposed before parsing, no error will be raised. - -- Following the `WHATWG spec`_ that updates RFC 3986, ASCII newline -- ``\n``, ``\r`` and tab ``\t`` characters are stripped from the URL. -+ Following some of the `WHATWG spec`_ that updates RFC 3986, leading C0 -+ control and space characters are stripped from the URL. ``\n``, -+ ``\r`` and tab ``\t`` characters are removed from the URL at any position. -+ -+ .. warning:: -+ -+ :func:`urlsplit` does not perform validation. See :ref:`URL parsing -+ security ` for details. - - .. versionchanged:: 3.6 - Out-of-range port numbers now raise :exc:`ValueError`, instead of -@@ -337,6 +347,9 @@ or on combining URL components into a URL string. - .. versionchanged:: 3.9.5 - ASCII newline and tab characters are stripped from the URL. - -+ .. versionchanged:: 3.11.4 -+ Leading WHATWG C0 control and space characters are stripped from the URL. -+ - .. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser - - .. function:: urlunsplit(parts) -@@ -413,6 +426,35 @@ or on combining URL components into a URL string. - or ``scheme://host/path``). If *url* is not a wrapped URL, it is returned - without changes. - -+.. _url-parsing-security: -+ -+URL parsing security -+-------------------- -+ -+The :func:`urlsplit` and :func:`urlparse` APIs do not perform **validation** of -+inputs. They may not raise errors on inputs that other applications consider -+invalid. They may also succeed on some inputs that might not be considered -+URLs elsewhere. Their purpose is for practical functionality rather than -+purity. -+ -+Instead of raising an exception on unusual input, they may instead return some -+component parts as empty strings. Or components may contain more than perhaps -+they should. -+ -+We recommend that users of these APIs where the values may be used anywhere -+with security implications code defensively. Do some verification within your -+code before trusting a returned component part. Does that ``scheme`` make -+sense? Is that a sensible ``path``? Is there anything strange about that -+``hostname``? etc. -+ -+What constitutes a URL is not universally well defined. Different applications -+have different needs and desired constraints. For instance the living `WHATWG -+spec`_ describes what user facing web clients such as a web browser require. -+While :rfc:`3986` is more general. These functions incorporate some aspects of -+both, but cannot be claimed compliant with either. The APIs and existing user -+code with expectations on specific behaviors predate both standards leading us -+to be very cautious about making API behavior changes. -+ - .. _parsing-ascii-encoded-bytes: - - Parsing ASCII Encoded Bytes -diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py -index 31943f357f..574da5bd69 100644 ---- a/Lib/test/test_urlparse.py -+++ b/Lib/test/test_urlparse.py -@@ -649,6 +649,65 @@ class UrlParseTestCase(unittest.TestCase): - self.assertEqual(p.scheme, "http") - self.assertEqual(p.geturl(), "http://www.python.org/javascript:alert('msg')/?query=something#fragment") - -+ def test_urlsplit_strip_url(self): -+ noise = bytes(range(0, 0x20 + 1)) -+ base_url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag" -+ -+ url = noise.decode("utf-8") + base_url -+ p = urllib.parse.urlsplit(url) -+ self.assertEqual(p.scheme, "http") -+ self.assertEqual(p.netloc, "User:Pass@www.python.org:080") -+ self.assertEqual(p.path, "/doc/") -+ self.assertEqual(p.query, "query=yes") -+ self.assertEqual(p.fragment, "frag") -+ self.assertEqual(p.username, "User") -+ self.assertEqual(p.password, "Pass") -+ self.assertEqual(p.hostname, "www.python.org") -+ self.assertEqual(p.port, 80) -+ self.assertEqual(p.geturl(), base_url) -+ -+ url = noise + base_url.encode("utf-8") -+ p = urllib.parse.urlsplit(url) -+ self.assertEqual(p.scheme, b"http") -+ self.assertEqual(p.netloc, b"User:Pass@www.python.org:080") -+ self.assertEqual(p.path, b"/doc/") -+ self.assertEqual(p.query, b"query=yes") -+ self.assertEqual(p.fragment, b"frag") -+ self.assertEqual(p.username, b"User") -+ self.assertEqual(p.password, b"Pass") -+ self.assertEqual(p.hostname, b"www.python.org") -+ self.assertEqual(p.port, 80) -+ self.assertEqual(p.geturl(), base_url.encode("utf-8")) -+ -+ # Test that trailing space is preserved as some applications rely on -+ # this within query strings. -+ query_spaces_url = "https://www.python.org:88/doc/?query= " -+ p = urllib.parse.urlsplit(noise.decode("utf-8") + query_spaces_url) -+ self.assertEqual(p.scheme, "https") -+ self.assertEqual(p.netloc, "www.python.org:88") -+ self.assertEqual(p.path, "/doc/") -+ self.assertEqual(p.query, "query= ") -+ self.assertEqual(p.port, 88) -+ self.assertEqual(p.geturl(), query_spaces_url) -+ -+ p = urllib.parse.urlsplit("www.pypi.org ") -+ # That "hostname" gets considered a "path" due to the -+ # trailing space and our existing logic... YUCK... -+ # and re-assembles via geturl aka unurlsplit into the original. -+ # django.core.validators.URLValidator (at least through v3.2) relies on -+ # this, for better or worse, to catch it in a ValidationError via its -+ # regular expressions. -+ # Here we test the basic round trip concept of such a trailing space. -+ self.assertEqual(urllib.parse.urlunsplit(p), "www.pypi.org ") -+ -+ # with scheme as cache-key -+ url = "//www.python.org/" -+ scheme = noise.decode("utf-8") + "https" + noise.decode("utf-8") -+ for _ in range(2): -+ p = urllib.parse.urlsplit(url, scheme=scheme) -+ self.assertEqual(p.scheme, "https") -+ self.assertEqual(p.geturl(), "https://www.python.org/") -+ - def test_attributes_bad_port(self): - """Check handling of invalid ports.""" - for bytes in (False, True): -@@ -656,7 +715,7 @@ class UrlParseTestCase(unittest.TestCase): - for port in ("foo", "1.5", "-1", "0x10"): - with self.subTest(bytes=bytes, parse=parse, port=port): - netloc = "www.example.net:" + port -- url = "http://" + netloc -+ url = "http://" + netloc + "/" - if bytes: - netloc = netloc.encode("ascii") - url = url.encode("ascii") -diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py -index b7965fe3d2..5b7193f67c 100644 ---- a/Lib/urllib/parse.py -+++ b/Lib/urllib/parse.py -@@ -25,6 +25,10 @@ currently not entirely compliant with this RFC due to defacto - scenarios for parsing, and for backward compatibility purposes, some - parsing quirks from older RFCs are retained. The testcases in - test_urlparse.py provides a good indicator of parsing behavior. -+ -+The WHATWG URL Parser spec should also be considered. We are not compliant with -+it either due to existing user code API behavior expectations (Hyrum's Law). -+It serves as a useful guide when making changes. - """ - - import re -@@ -78,6 +82,10 @@ scheme_chars = ('abcdefghijklmnopqrstuvwxyz' - '0123456789' - '+-.') - -+# Leading and trailing C0 control and space to be stripped per WHATWG spec. -+# == "".join([chr(i) for i in range(0, 0x20 + 1)]) -+_WHATWG_C0_CONTROL_OR_SPACE = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ' -+ - # Unsafe bytes to be removed per WHATWG spec - _UNSAFE_URL_BYTES_TO_REMOVE = ['\t', '\r', '\n'] - -@@ -456,6 +464,10 @@ def urlsplit(url, scheme='', allow_fragments=True): - """ - - url, scheme, _coerce_result = _coerce_args(url, scheme) -+ # Only lstrip url as some applications rely on preserving trailing space. -+ # (https://url.spec.whatwg.org/#concept-basic-url-parser would strip both) -+ url = url.lstrip(_WHATWG_C0_CONTROL_OR_SPACE) -+ scheme = scheme.strip(_WHATWG_C0_CONTROL_OR_SPACE) - - for b in _UNSAFE_URL_BYTES_TO_REMOVE: - url = url.replace(b, "") -diff --git a/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst -new file mode 100644 -index 0000000000..e57ac4ed3a ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2023-03-07-20-59-17.gh-issue-102153.14CLSZ.rst -@@ -0,0 +1,3 @@ -+:func:`urllib.parse.urlsplit` now strips leading C0 control and space -+characters following the specification for URLs defined by WHATWG in -+response to CVE-2023-24329. Patch by Illia Volochii. diff --git a/python3.9.spec b/python3.9.spec index bf53063..f4b3174 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.16 +%global general_version %{pybasever}.17 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 4%{?dist} +Release: 1%{?dist} License: Python @@ -311,7 +311,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # a79a85be3f0ad45792d998aed1104c2c2a0ef729 +# 00189 # 60517f098bd1525ad454adf7252b60a3d6b0f8ba # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -323,7 +323,7 @@ Patch189: 00189-use-rpm-wheels.patch # The versions are written in Lib/ensurepip/__init__.py, this patch removes them. # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: -%global pip_version 22.0.4 +%global pip_version 23.0.1 %global setuptools_version 58.1.0 # 00251 # 1b1047c14ff98eae6d355b4aac4df3e388813f62 @@ -379,18 +379,6 @@ Patch353: 00353-architecture-names-upstream-downstream.patch # https://github.com/GrahamDumpleton/mod_wsgi/issues/730 Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch -# 00399 # c32eff86eb80f6a6bdcbf4b1b6535fbc627b51a2 -# CVE-2023-24329 -# -# * gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508) -# -# `urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595. -# -# This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%%20any%%20leading%%20and%%20trailing%%20C0%%20control%%20or%%20space%%20from%%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329). -# -# --------- -Patch399: 00399-cve-2023-24329.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1816,6 +1804,9 @@ CheckPython optimized # ====================================================== %changelog +* Thu Jun 08 2023 Tomáš Hrnčiar - 3.9.17-1 +- Update to 3.9.17 + * Mon May 29 2023 Lumír Balhar - 3.9.16-4 - Security fix for CVE-2023-24329 - Resolves: rhbz#2174016 diff --git a/sources b/sources index 3885014..46c321f 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.16.tar.xz) = b5fd0afe131c82bbce6ddf887c59eef6945910d6a9a2bc87c0927f4e4a096bf9ca4d25bcb729c40f6ebb8a65fbe8bf7b0b97a7c4a8c9e551240eb4f34b878653 -SHA512 (Python-3.9.16.tar.xz.asc) = 468959c36a3ec6136f57a39475fff4745a25be0cb5d3d58cf3e5faf0b9ce2d2a8b89f1f9fea1479c4c6ad12ac49e97c1cfd4291c978bb3d30df5a582ec315210 +SHA512 (Python-3.9.17.tar.xz) = 994d92346e563a4635411808744eac8207c68e6fc9c1db1c2eb4103dad8553aaad4a8116e38c61f28cb17905a12cc46dccdde985e1c45882bf1815081b88b6be +SHA512 (Python-3.9.17.tar.xz.asc) = 948196f104539b2e05b17fb5ef2387be392c515222213def7ab6f5b0f490d60e472e8df2dc6ec1df1d293a34d8c26a761412c93aabbdefd3390ee8bdef95a5d8 From 7b9f870dc59d2b6ee2f75852b948553164c0ee95 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 21 Jul 2023 15:43:15 +0000 Subject: [PATCH 51/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index f4b3174..35747ac 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -1804,6 +1804,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 21 2023 Fedora Release Engineering - 3.9.17-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Thu Jun 08 2023 Tomáš Hrnčiar - 3.9.17-1 - Update to 3.9.17 From c7a252caa89ae4fc16f3fd5dc99233d6b31ecf6e Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Mon, 22 May 2023 19:23:07 +0200 Subject: [PATCH 52/89] Remove extra distro-applied CFLAGS passed to user-built C extensions Only -fexceptions and -fcf-protection are preserved for binary compatibility with user-built python C extension. https://fedoraproject.org/wiki/Changes/Python_Extension_Flags_Reduction --- python3.9.spec | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 35747ac..0004a3f 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -825,14 +825,15 @@ topdir=$(pwd) # Standard library built here will still use the %%build_...flags, # Fedora packages utilizing %%py3_build will use them as well # https://fedoraproject.org/wiki/Changes/Python_Extension_Flags -export CFLAGS="%{extension_cflags} -D_GNU_SOURCE -fPIC -fwrapv" +# https://fedoraproject.org/wiki/Changes/Python_Extension_Flags_Reduction +export CFLAGS="%{extension_cflags}" export CFLAGS_NODIST="%{build_cflags} -D_GNU_SOURCE -fPIC -fwrapv%{?with_no_semantic_interposition: -fno-semantic-interposition}" -export CXXFLAGS="%{extension_cxxflags} -D_GNU_SOURCE -fPIC -fwrapv" +export CXXFLAGS="%{extension_cxxflags}" export CPPFLAGS="$(pkg-config --cflags-only-I libffi)" -export OPT="%{extension_cflags} -D_GNU_SOURCE -fPIC -fwrapv" +export OPT="%{extension_cflags}" export LINKCC="gcc" export CFLAGS="$CFLAGS $(pkg-config --cflags openssl)" -export LDFLAGS="%{extension_ldflags} -g $(pkg-config --libs-only-L openssl)" +export LDFLAGS="%{extension_ldflags} $(pkg-config --libs-only-L openssl)" export LDFLAGS_NODIST="%{build_ldflags}%{?with_no_semantic_interposition: -fno-semantic-interposition} -g $(pkg-config --libs-only-L openssl)" # We can build several different configurations of Python: regular and debug. @@ -1804,6 +1805,10 @@ CheckPython optimized # ====================================================== %changelog +* Wed Aug 02 2023 Charalampos Stratakis - 3.9.17-3 +- Remove extra distro-applied CFLAGS passed to user built C extensions +- https://fedoraproject.org/wiki/Changes/Python_Extension_Flags_Reduction + * Fri Jul 21 2023 Fedora Release Engineering - 3.9.17-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild From 77e0d4f1565ada8d2387b873afe56a62d71d4e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Mon, 28 Aug 2023 16:21:38 +0200 Subject: [PATCH 53/89] Update to 3.9.18 --- python3.9.spec | 7 +++++-- sources | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 0004a3f..1e3cee0 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.17 +%global general_version %{pybasever}.18 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 1%{?dist} License: Python @@ -1805,6 +1805,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Aug 28 2023 Tomáš Hrnčiar - 3.9.18-1 +- Update to 3.9.18 + * Wed Aug 02 2023 Charalampos Stratakis - 3.9.17-3 - Remove extra distro-applied CFLAGS passed to user built C extensions - https://fedoraproject.org/wiki/Changes/Python_Extension_Flags_Reduction diff --git a/sources b/sources index 46c321f..19cb08f 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.17.tar.xz) = 994d92346e563a4635411808744eac8207c68e6fc9c1db1c2eb4103dad8553aaad4a8116e38c61f28cb17905a12cc46dccdde985e1c45882bf1815081b88b6be -SHA512 (Python-3.9.17.tar.xz.asc) = 948196f104539b2e05b17fb5ef2387be392c515222213def7ab6f5b0f490d60e472e8df2dc6ec1df1d293a34d8c26a761412c93aabbdefd3390ee8bdef95a5d8 +SHA512 (Python-3.9.18.tar.xz) = aab155aca757d298394eddb91ff9a8f239665bd46feb495c6b6f735bbcb7489c05c858cc4cd08f1575c24f293b33492d763e9a140d92f0b2b0cc81a165a677c7 +SHA512 (Python-3.9.18.tar.xz.asc) = dff9a86df2b0774b68e7c762bacf05e2482dbb218301acfdc9128fc600bbc51c97a3a44f6b7cee87bd4e153bcb4a0af3c98109560d0c7861b7508edc9ae05ea1 From d25ca05b8fcb9dbba05f1385a989ef658ac0fce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 23 Nov 2023 11:50:56 +0100 Subject: [PATCH 54/89] Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM - Resolves: rhbz#2147519 --- ...igure-check-for-pthread_scope_system.patch | 47 +++++++++++++++++++ python3.9.spec | 10 +++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch diff --git a/00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch b/00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch new file mode 100644 index 0000000..0c63a32 --- /dev/null +++ b/00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Erlend E. Aasland" +Date: Sun, 6 Nov 2022 22:39:34 +0100 +Subject: [PATCH] 00407: gh-99086: Fix implicit int compiler warning in + configure check for PTHREAD_SCOPE_SYSTEM + +Co-authored-by: Sam James +--- + .../next/Build/2022-11-04-02-58-10.gh-issue-99086.DV_4Br.rst | 1 + + configure | 2 +- + configure.ac | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + create mode 100644 Misc/NEWS.d/next/Build/2022-11-04-02-58-10.gh-issue-99086.DV_4Br.rst + +diff --git a/Misc/NEWS.d/next/Build/2022-11-04-02-58-10.gh-issue-99086.DV_4Br.rst b/Misc/NEWS.d/next/Build/2022-11-04-02-58-10.gh-issue-99086.DV_4Br.rst +new file mode 100644 +index 0000000000..e320ecfdfb +--- /dev/null ++++ b/Misc/NEWS.d/next/Build/2022-11-04-02-58-10.gh-issue-99086.DV_4Br.rst +@@ -0,0 +1 @@ ++Fix ``-Wimplicit-int`` compiler warning in :program:`configure` check for ``PTHREAD_SCOPE_SYSTEM``. +diff --git a/configure b/configure +index b7be60eaa3..51c2a231ac 100755 +--- a/configure ++++ b/configure +@@ -11151,7 +11151,7 @@ else + void *foo(void *parm) { + return NULL; + } +- main() { ++ int main() { + pthread_attr_t attr; + pthread_t id; + if (pthread_attr_init(&attr)) return (-1); +diff --git a/configure.ac b/configure.ac +index aa515da465..7729ccee9c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3336,7 +3336,7 @@ if test "$posix_threads" = "yes"; then + void *foo(void *parm) { + return NULL; + } +- main() { ++ int main() { + pthread_attr_t attr; + pthread_t id; + if (pthread_attr_init(&attr)) return (-1); diff --git a/python3.9.spec b/python3.9.spec index 1e3cee0..7ca983e 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -379,6 +379,10 @@ Patch353: 00353-architecture-names-upstream-downstream.patch # https://github.com/GrahamDumpleton/mod_wsgi/issues/730 Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +# 00407 # 17dbfc39d1118a479e7ea244ad46fb6eeeb38280 +# gh-99086: Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM +Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1805,6 +1809,10 @@ CheckPython optimized # ====================================================== %changelog +* Thu Nov 23 2023 Miro Hrončok - 3.9.18-2 +- Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM +- Resolves: rhbz#2147519 + * Mon Aug 28 2023 Tomáš Hrnčiar - 3.9.18-1 - Update to 3.9.18 From 1341447949b1e50097b7173f7e95e5f0850ce84b Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Mon, 18 Dec 2023 13:15:55 +0100 Subject: [PATCH 55/89] Security fix for CVE-2023-27043 (rhbz#2196194) --- ...-addresses-in-email-parseaddr-111116.patch | 500 ++++++++++++++++++ python3.9.spec | 14 +- 2 files changed, 513 insertions(+), 1 deletion(-) create mode 100644 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch diff --git a/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch b/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch new file mode 100644 index 0000000..af44881 --- /dev/null +++ b/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch @@ -0,0 +1,500 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Victor Stinner +Date: Fri, 15 Dec 2023 16:10:40 +0100 +Subject: [PATCH] 00415: [CVE-2023-27043] gh-102988: Reject malformed addresses + in email.parseaddr() (#111116) + +Detect email address parsing errors and return empty tuple to +indicate the parsing error (old API). Add an optional 'strict' +parameter to getaddresses() and parseaddr() functions. Patch by +Thomas Dwyer. + +Co-Authored-By: Thomas Dwyer +--- + Doc/library/email.utils.rst | 19 +- + Lib/email/utils.py | 151 ++++++++++++- + Lib/test/test_email/test_email.py | 204 +++++++++++++++++- + ...-10-20-15-28-08.gh-issue-102988.dStNO7.rst | 8 + + 4 files changed, 361 insertions(+), 21 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst + +diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst +index 4d0e920eb0..104229e9e5 100644 +--- a/Doc/library/email.utils.rst ++++ b/Doc/library/email.utils.rst +@@ -60,13 +60,18 @@ of the new API. + begins with angle brackets, they are stripped off. + + +-.. function:: parseaddr(address) ++.. function:: parseaddr(address, *, strict=True) + + Parse address -- which should be the value of some address-containing field such + as :mailheader:`To` or :mailheader:`Cc` -- into its constituent *realname* and + *email address* parts. Returns a tuple of that information, unless the parse + fails, in which case a 2-tuple of ``('', '')`` is returned. + ++ If *strict* is true, use a strict parser which rejects malformed inputs. ++ ++ .. versionchanged:: 3.13 ++ Add *strict* optional parameter and reject malformed inputs by default. ++ + + .. function:: formataddr(pair, charset='utf-8') + +@@ -84,12 +89,15 @@ of the new API. + Added the *charset* option. + + +-.. function:: getaddresses(fieldvalues) ++.. function:: getaddresses(fieldvalues, *, strict=True) + + This method returns a list of 2-tuples of the form returned by ``parseaddr()``. + *fieldvalues* is a sequence of header field values as might be returned by +- :meth:`Message.get_all `. Here's a simple +- example that gets all the recipients of a message:: ++ :meth:`Message.get_all `. ++ ++ If *strict* is true, use a strict parser which rejects malformed inputs. ++ ++ Here's a simple example that gets all the recipients of a message:: + + from email.utils import getaddresses + +@@ -99,6 +107,9 @@ of the new API. + resent_ccs = msg.get_all('resent-cc', []) + all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) + ++ .. versionchanged:: 3.13 ++ Add *strict* optional parameter and reject malformed inputs by default. ++ + + .. function:: parsedate(date) + +diff --git a/Lib/email/utils.py b/Lib/email/utils.py +index 48d30160aa..7ca7a7c886 100644 +--- a/Lib/email/utils.py ++++ b/Lib/email/utils.py +@@ -48,6 +48,7 @@ TICK = "'" + specialsre = re.compile(r'[][\\()<>@,:;".]') + escapesre = re.compile(r'[\\"]') + ++ + def _has_surrogates(s): + """Return True if s contains surrogate-escaped binary data.""" + # This check is based on the fact that unless there are surrogates, utf8 +@@ -106,12 +107,127 @@ def formataddr(pair, charset='utf-8'): + return address + + ++def _iter_escaped_chars(addr): ++ pos = 0 ++ escape = False ++ for pos, ch in enumerate(addr): ++ if escape: ++ yield (pos, '\\' + ch) ++ escape = False ++ elif ch == '\\': ++ escape = True ++ else: ++ yield (pos, ch) ++ if escape: ++ yield (pos, '\\') + +-def getaddresses(fieldvalues): +- """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" +- all = COMMASPACE.join(str(v) for v in fieldvalues) +- a = _AddressList(all) +- return a.addresslist ++ ++def _strip_quoted_realnames(addr): ++ """Strip real names between quotes.""" ++ if '"' not in addr: ++ # Fast path ++ return addr ++ ++ start = 0 ++ open_pos = None ++ result = [] ++ for pos, ch in _iter_escaped_chars(addr): ++ if ch == '"': ++ if open_pos is None: ++ open_pos = pos ++ else: ++ if start != open_pos: ++ result.append(addr[start:open_pos]) ++ start = pos + 1 ++ open_pos = None ++ ++ if start < len(addr): ++ result.append(addr[start:]) ++ ++ return ''.join(result) ++ ++ ++supports_strict_parsing = True ++ ++def getaddresses(fieldvalues, *, strict=True): ++ """Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue. ++ ++ When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in ++ its place. ++ ++ If strict is true, use a strict parser which rejects malformed inputs. ++ """ ++ ++ # If strict is true, if the resulting list of parsed addresses is greater ++ # than the number of fieldvalues in the input list, a parsing error has ++ # occurred and consequently a list containing a single empty 2-tuple [('', ++ # '')] is returned in its place. This is done to avoid invalid output. ++ # ++ # Malformed input: getaddresses(['alice@example.com ']) ++ # Invalid output: [('', 'alice@example.com'), ('', 'bob@example.com')] ++ # Safe output: [('', '')] ++ ++ if not strict: ++ all = COMMASPACE.join(str(v) for v in fieldvalues) ++ a = _AddressList(all) ++ return a.addresslist ++ ++ fieldvalues = [str(v) for v in fieldvalues] ++ fieldvalues = _pre_parse_validation(fieldvalues) ++ addr = COMMASPACE.join(fieldvalues) ++ a = _AddressList(addr) ++ result = _post_parse_validation(a.addresslist) ++ ++ # Treat output as invalid if the number of addresses is not equal to the ++ # expected number of addresses. ++ n = 0 ++ for v in fieldvalues: ++ # When a comma is used in the Real Name part it is not a deliminator. ++ # So strip those out before counting the commas. ++ v = _strip_quoted_realnames(v) ++ # Expected number of addresses: 1 + number of commas ++ n += 1 + v.count(',') ++ if len(result) != n: ++ return [('', '')] ++ ++ return result ++ ++ ++def _check_parenthesis(addr): ++ # Ignore parenthesis in quoted real names. ++ addr = _strip_quoted_realnames(addr) ++ ++ opens = 0 ++ for pos, ch in _iter_escaped_chars(addr): ++ if ch == '(': ++ opens += 1 ++ elif ch == ')': ++ opens -= 1 ++ if opens < 0: ++ return False ++ return (opens == 0) ++ ++ ++def _pre_parse_validation(email_header_fields): ++ accepted_values = [] ++ for v in email_header_fields: ++ if not _check_parenthesis(v): ++ v = "('', '')" ++ accepted_values.append(v) ++ ++ return accepted_values ++ ++ ++def _post_parse_validation(parsed_email_header_tuples): ++ accepted_values = [] ++ # The parser would have parsed a correctly formatted domain-literal ++ # The existence of an [ after parsing indicates a parsing failure ++ for v in parsed_email_header_tuples: ++ if '[' in v[1]: ++ v = ('', '') ++ accepted_values.append(v) ++ ++ return accepted_values + + + def _format_timetuple_and_zone(timetuple, zone): +@@ -202,16 +318,33 @@ def parsedate_to_datetime(data): + tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) + + +-def parseaddr(addr): ++def parseaddr(addr, *, strict=True): + """ + Parse addr into its constituent realname and email address parts. + + Return a tuple of realname and email address, unless the parse fails, in + which case return a 2-tuple of ('', ''). ++ ++ If strict is True, use a strict parser which rejects malformed inputs. + """ +- addrs = _AddressList(addr).addresslist +- if not addrs: +- return '', '' ++ if not strict: ++ addrs = _AddressList(addr).addresslist ++ if not addrs: ++ return ('', '') ++ return addrs[0] ++ ++ if isinstance(addr, list): ++ addr = addr[0] ++ ++ if not isinstance(addr, str): ++ return ('', '') ++ ++ addr = _pre_parse_validation([addr])[0] ++ addrs = _post_parse_validation(_AddressList(addr).addresslist) ++ ++ if not addrs or len(addrs) > 1: ++ return ('', '') ++ + return addrs[0] + + +diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py +index 761ea90b78..0c689643de 100644 +--- a/Lib/test/test_email/test_email.py ++++ b/Lib/test/test_email/test_email.py +@@ -16,6 +16,7 @@ from unittest.mock import patch + + import email + import email.policy ++import email.utils + + from email.charset import Charset + from email.header import Header, decode_header, make_header +@@ -3263,15 +3264,154 @@ Foo + [('Al Person', 'aperson@dom.ain'), + ('Bud Person', 'bperson@dom.ain')]) + ++ def test_getaddresses_comma_in_name(self): ++ """GH-106669 regression test.""" ++ self.assertEqual( ++ utils.getaddresses( ++ [ ++ '"Bud, Person" ', ++ 'aperson@dom.ain (Al Person)', ++ '"Mariusz Felisiak" ', ++ ] ++ ), ++ [ ++ ('Bud, Person', 'bperson@dom.ain'), ++ ('Al Person', 'aperson@dom.ain'), ++ ('Mariusz Felisiak', 'to@example.com'), ++ ], ++ ) ++ ++ def test_parsing_errors(self): ++ """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" ++ alice = 'alice@example.org' ++ bob = 'bob@example.com' ++ empty = ('', '') ++ ++ # Test utils.getaddresses() and utils.parseaddr() on malformed email ++ # addresses: default behavior (strict=True) rejects malformed address, ++ # and strict=False which tolerates malformed address. ++ for invalid_separator, expected_non_strict in ( ++ ('(', [(f'<{bob}>', alice)]), ++ (')', [('', alice), empty, ('', bob)]), ++ ('<', [('', alice), empty, ('', bob), empty]), ++ ('>', [('', alice), empty, ('', bob)]), ++ ('[', [('', f'{alice}[<{bob}>]')]), ++ (']', [('', alice), empty, ('', bob)]), ++ ('@', [empty, empty, ('', bob)]), ++ (';', [('', alice), empty, ('', bob)]), ++ (':', [('', alice), ('', bob)]), ++ ('.', [('', alice + '.'), ('', bob)]), ++ ('"', [('', alice), ('', f'<{bob}>')]), ++ ): ++ address = f'{alice}{invalid_separator}<{bob}>' ++ with self.subTest(address=address): ++ self.assertEqual(utils.getaddresses([address]), ++ [empty]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ expected_non_strict) ++ ++ self.assertEqual(utils.parseaddr([address]), ++ empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Comma (',') is treated differently depending on strict parameter. ++ # Comma without quotes. ++ address = f'{alice},<{bob}>' ++ self.assertEqual(utils.getaddresses([address]), ++ [('', alice), ('', bob)]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ [('', alice), ('', bob)]) ++ self.assertEqual(utils.parseaddr([address]), ++ empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Real name between quotes containing comma. ++ address = '"Alice, alice@example.org" ' ++ expected_strict = ('Alice, alice@example.org', 'bob@example.com') ++ self.assertEqual(utils.getaddresses([address]), [expected_strict]) ++ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) ++ self.assertEqual(utils.parseaddr([address]), expected_strict) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Valid parenthesis in comments. ++ address = 'alice@example.org (Alice)' ++ expected_strict = ('Alice', 'alice@example.org') ++ self.assertEqual(utils.getaddresses([address]), [expected_strict]) ++ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) ++ self.assertEqual(utils.parseaddr([address]), expected_strict) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Invalid parenthesis in comments. ++ address = 'alice@example.org )Alice(' ++ self.assertEqual(utils.getaddresses([address]), [empty]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ [('', 'alice@example.org'), ('', ''), ('', 'Alice')]) ++ self.assertEqual(utils.parseaddr([address]), empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Two addresses with quotes separated by comma. ++ address = '"Jane Doe" , "John Doe" ' ++ self.assertEqual(utils.getaddresses([address]), ++ [('Jane Doe', 'jane@example.net'), ++ ('John Doe', 'john@example.net')]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ [('Jane Doe', 'jane@example.net'), ++ ('John Doe', 'john@example.net')]) ++ self.assertEqual(utils.parseaddr([address]), empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Test email.utils.supports_strict_parsing attribute ++ self.assertEqual(email.utils.supports_strict_parsing, True) ++ + def test_getaddresses_nasty(self): +- eq = self.assertEqual +- eq(utils.getaddresses(['foo: ;']), [('', '')]) +- eq(utils.getaddresses( +- ['[]*-- =~$']), +- [('', ''), ('', ''), ('', '*--')]) +- eq(utils.getaddresses( +- ['foo: ;', '"Jason R. Mastaler" ']), +- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) ++ for addresses, expected in ( ++ (['"Sürname, Firstname" '], ++ [('Sürname, Firstname', 'to@example.com')]), ++ ++ (['foo: ;'], ++ [('', '')]), ++ ++ (['foo: ;', '"Jason R. Mastaler" '], ++ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), ++ ++ ([r'Pete(A nice \) chap) '], ++ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), ++ ++ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], ++ [('', '')]), ++ ++ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], ++ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), ++ ++ (['John Doe '], ++ [('John Doe (comment)', 'jdoe@machine.example')]), ++ ++ (['"Mary Smith: Personal Account" '], ++ [('Mary Smith: Personal Account', 'smith@home.example')]), ++ ++ (['Undisclosed recipients:;'], ++ [('', '')]), ++ ++ ([r', "Giant; \"Big\" Box" '], ++ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), ++ ): ++ with self.subTest(addresses=addresses): ++ self.assertEqual(utils.getaddresses(addresses), ++ expected) ++ self.assertEqual(utils.getaddresses(addresses, strict=False), ++ expected) ++ ++ addresses = ['[]*-- =~$'] ++ self.assertEqual(utils.getaddresses(addresses), ++ [('', '')]) ++ self.assertEqual(utils.getaddresses(addresses, strict=False), ++ [('', ''), ('', ''), ('', '*--')]) + + def test_getaddresses_embedded_comment(self): + """Test proper handling of a nested comment""" +@@ -3460,6 +3600,54 @@ multipart/report + m = cls(*constructor, policy=email.policy.default) + self.assertIs(m.policy, email.policy.default) + ++ def test_iter_escaped_chars(self): ++ self.assertEqual(list(utils._iter_escaped_chars(r'a\\b\"c\\"d')), ++ [(0, 'a'), ++ (2, '\\\\'), ++ (3, 'b'), ++ (5, '\\"'), ++ (6, 'c'), ++ (8, '\\\\'), ++ (9, '"'), ++ (10, 'd')]) ++ self.assertEqual(list(utils._iter_escaped_chars('a\\')), ++ [(0, 'a'), (1, '\\')]) ++ ++ def test_strip_quoted_realnames(self): ++ def check(addr, expected): ++ self.assertEqual(utils._strip_quoted_realnames(addr), expected) ++ ++ check('"Jane Doe" , "John Doe" ', ++ ' , ') ++ check(r'"Jane \"Doe\"." ', ++ ' ') ++ ++ # special cases ++ check(r'before"name"after', 'beforeafter') ++ check(r'before"name"', 'before') ++ check(r'b"name"', 'b') # single char ++ check(r'"name"after', 'after') ++ check(r'"name"a', 'a') # single char ++ check(r'"name"', '') ++ ++ # no change ++ for addr in ( ++ 'Jane Doe , John Doe ', ++ 'lone " quote', ++ ): ++ self.assertEqual(utils._strip_quoted_realnames(addr), addr) ++ ++ ++ def test_check_parenthesis(self): ++ addr = 'alice@example.net' ++ self.assertTrue(utils._check_parenthesis(f'{addr} (Alice)')) ++ self.assertFalse(utils._check_parenthesis(f'{addr} )Alice(')) ++ self.assertFalse(utils._check_parenthesis(f'{addr} (Alice))')) ++ self.assertFalse(utils._check_parenthesis(f'{addr} ((Alice)')) ++ ++ # Ignore real name between quotes ++ self.assertTrue(utils._check_parenthesis(f'")Alice((" {addr}')) ++ + + # Test the iterator/generators + class TestIterators(TestEmailBase): +diff --git a/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst +new file mode 100644 +index 0000000000..3d0e9e4078 +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst +@@ -0,0 +1,8 @@ ++:func:`email.utils.getaddresses` and :func:`email.utils.parseaddr` now ++return ``('', '')`` 2-tuples in more situations where invalid email ++addresses are encountered instead of potentially inaccurate values. Add ++optional *strict* parameter to these two functions: use ``strict=False`` to ++get the old behavior, accept malformed inputs. ++``getattr(email.utils, 'supports_strict_parsing', False)`` can be use to check ++if the *strict* paramater is available. Patch by Thomas Dwyer and Victor ++Stinner to improve the CVE-2023-27043 fix. diff --git a/python3.9.spec b/python3.9.spec index 7ca983e..43ef99e 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -383,6 +383,15 @@ Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-g # gh-99086: Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch +# 00415 # 512c60eb23a8d7b26d74824a6d7bbefb6feefb65 +# [CVE-2023-27043] gh-102988: Reject malformed addresses in email.parseaddr() (#111116) +# +# Detect email address parsing errors and return empty tuple to +# indicate the parsing error (old API). Add an optional 'strict' +# parameter to getaddresses() and parseaddr() functions. Patch by +# Thomas Dwyer. +Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1809,6 +1818,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Dec 18 2023 Lumír Balhar - 3.9.18-3 +- Security fix for CVE-2023-27043 (rhbz#2196194) + * Thu Nov 23 2023 Miro Hrončok - 3.9.18-2 - Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM - Resolves: rhbz#2147519 From 45fe9e38c329e92aed074cabea6ac98e56b1e193 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 22 Jan 2024 09:22:35 +0000 Subject: [PATCH 56/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 43ef99e..35869a1 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 4%{?dist} License: Python @@ -1818,6 +1818,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Jan 22 2024 Fedora Release Engineering - 3.9.18-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Mon Dec 18 2023 Lumír Balhar - 3.9.18-3 - Security fix for CVE-2023-27043 (rhbz#2196194) From 53abe334d1981ac6e0d74d8c5913e45d6392783f Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 26 Jan 2024 13:34:33 +0000 Subject: [PATCH 57/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 35869a1..5901362 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 4%{?dist} +Release: 5%{?dist} License: Python @@ -1818,6 +1818,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jan 26 2024 Fedora Release Engineering - 3.9.18-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Mon Jan 22 2024 Fedora Release Engineering - 3.9.18-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From d1898e800cb69b81f34d794b3ec4834014211639 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Thu, 25 Jan 2024 15:12:20 +0100 Subject: [PATCH 58/89] Fix test_zlib with zlib-ng-compat --- ...h-non-int-suffix-gh-112771-gh-112774.patch | 66 +++++++++++++++++++ python3.9.spec | 11 +++- 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch diff --git a/00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch b/00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch new file mode 100644 index 0000000..ce6c9f4 --- /dev/null +++ b/00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Tue, 5 Dec 2023 21:02:06 +0100 +Subject: [PATCH] 00419: gh-112769: test_zlib: Fix comparison of + ZLIB_RUNTIME_VERSION with non-int suffix (GH-112771) (GH-112774) + +zlib-ng defines the version as "1.3.0.zlib-ng". +(cherry picked from commit d384813ff18b33280a90b6d2011654528a2b6ad1) +--- + Lib/test/test_zlib.py | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py +index 02509cdf55..2a9e7e5ed3 100644 +--- a/Lib/test/test_zlib.py ++++ b/Lib/test/test_zlib.py +@@ -17,6 +17,20 @@ requires_Decompress_copy = unittest.skipUnless( + 'requires Decompress.copy()') + + ++def _zlib_runtime_version_tuple(zlib_version=zlib.ZLIB_RUNTIME_VERSION): ++ # Register "1.2.3" as "1.2.3.0" ++ # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux" ++ v = zlib_version.split('-', 1)[0].split('.') ++ if len(v) < 4: ++ v.append('0') ++ elif not v[-1].isnumeric(): ++ v[-1] = '0' ++ return tuple(map(int, v)) ++ ++ ++ZLIB_RUNTIME_VERSION_TUPLE = _zlib_runtime_version_tuple() ++ ++ + class VersionTestCase(unittest.TestCase): + + def test_library_version(self): +@@ -437,9 +451,8 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): + sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH', + 'Z_PARTIAL_FLUSH'] + +- ver = tuple(int(v) for v in zlib.ZLIB_RUNTIME_VERSION.split('.')) + # Z_BLOCK has a known failure prior to 1.2.5.3 +- if ver >= (1, 2, 5, 3): ++ if ZLIB_RUNTIME_VERSION_TUPLE >= (1, 2, 5, 3): + sync_opt.append('Z_BLOCK') + + sync_opt = [getattr(zlib, opt) for opt in sync_opt +@@ -768,16 +781,7 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): + + def test_wbits(self): + # wbits=0 only supported since zlib v1.2.3.5 +- # Register "1.2.3" as "1.2.3.0" +- # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux" +- v = zlib.ZLIB_RUNTIME_VERSION.split('-', 1)[0].split('.') +- if len(v) < 4: +- v.append('0') +- elif not v[-1].isnumeric(): +- v[-1] = '0' +- +- v = tuple(map(int, v)) +- supports_wbits_0 = v >= (1, 2, 3, 5) ++ supports_wbits_0 = ZLIB_RUNTIME_VERSION_TUPLE >= (1, 2, 3, 5) + + co = zlib.compressobj(level=1, wbits=15) + zlib15 = co.compress(HAMLET_SCENE) + co.flush() diff --git a/python3.9.spec b/python3.9.spec index 5901362..5421790 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 5%{?dist} +Release: 6%{?dist} License: Python @@ -392,6 +392,12 @@ Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-fo # Thomas Dwyer. Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch +# 00419 # f13682530cc7e4daec2e40acd56508846fdd3aad +# gh-112769: test_zlib: Fix comparison of ZLIB_RUNTIME_VERSION with non-int suffix (GH-112771) (GH-112774) +# +# zlib-ng defines the version as "1.3.0.zlib-ng". +Patch419: 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1818,6 +1824,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Jan 29 2024 Karolina Surma - 3.9.18-6 +- Fix test_zlib when building with zlib-ng-compat + * Fri Jan 26 2024 Fedora Release Engineering - 3.9.18-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 800c22e4844a1d08bcc9cb649e75b3ded08c6d21 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Wed, 28 Feb 2024 17:16:55 +0100 Subject: [PATCH 59/89] Fix tests for XMLPullParser with Expat 2.6.0 See also: https://bugzilla.redhat.com/2264859 --- ...s-for-xmlpullparser-with-expat-2-6-0.patch | 110 ++++++++++++++++++ python3.9.spec | 12 +- 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch diff --git a/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch b/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch new file mode 100644 index 0000000..cf5babc --- /dev/null +++ b/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Wed, 21 Feb 2024 05:22:55 -0600 +Subject: [PATCH] 00422: gh-115133: Fix tests for XMLPullParser with Expat + 2.6.0 + +Feeding the parser by too small chunks defers parsing to prevent +CVE-2023-52425. Future versions of Expat may be more reactive. +(cherry picked from commit 4a08e7b3431cd32a0daf22a33421cd3035343dc4) + +Co-authored-by: Serhiy Storchaka +--- + Lib/test/test_xml_etree.py | 60 ++++++++++++------- + ...-02-08-14-21-28.gh-issue-115133.ycl4ko.rst | 2 + + 2 files changed, 40 insertions(+), 22 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst + +diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py +index 7c346f279a..48e7c79932 100644 +--- a/Lib/test/test_xml_etree.py ++++ b/Lib/test/test_xml_etree.py +@@ -13,6 +13,7 @@ import itertools + import operator + import os + import pickle ++import pyexpat + import sys + import textwrap + import types +@@ -102,6 +103,12 @@ EXTERNAL_ENTITY_XML = """\ + &entity; + """ + ++ ++fails_with_expat_2_6_0 = (unittest.expectedFailure ++ if pyexpat.version_info >= (2, 6, 0) else ++ lambda test: test) ++ ++ + def checkwarnings(*filters, quiet=False): + def decorator(test): + def newtest(*args, **kwargs): +@@ -1391,28 +1398,37 @@ class XMLPullParserTest(unittest.TestCase): + self.assertEqual([(action, elem.tag) for action, elem in events], + expected) + +- def test_simple_xml(self): +- for chunk_size in (None, 1, 5): +- with self.subTest(chunk_size=chunk_size): +- parser = ET.XMLPullParser() +- self.assert_event_tags(parser, []) +- self._feed(parser, "\n", chunk_size) +- self.assert_event_tags(parser, []) +- self._feed(parser, +- "\n text\n", chunk_size) +- self.assert_event_tags(parser, [('end', 'element')]) +- self._feed(parser, "texttail\n", chunk_size) +- self._feed(parser, "\n", chunk_size) +- self.assert_event_tags(parser, [ +- ('end', 'element'), +- ('end', 'empty-element'), +- ]) +- self._feed(parser, "\n", chunk_size) +- self.assert_event_tags(parser, [('end', 'root')]) +- self.assertIsNone(parser.close()) ++ def test_simple_xml(self, chunk_size=None): ++ parser = ET.XMLPullParser() ++ self.assert_event_tags(parser, []) ++ self._feed(parser, "\n", chunk_size) ++ self.assert_event_tags(parser, []) ++ self._feed(parser, ++ "\n text\n", chunk_size) ++ self.assert_event_tags(parser, [('end', 'element')]) ++ self._feed(parser, "texttail\n", chunk_size) ++ self._feed(parser, "\n", chunk_size) ++ self.assert_event_tags(parser, [ ++ ('end', 'element'), ++ ('end', 'empty-element'), ++ ]) ++ self._feed(parser, "\n", chunk_size) ++ self.assert_event_tags(parser, [('end', 'root')]) ++ self.assertIsNone(parser.close()) ++ ++ @fails_with_expat_2_6_0 ++ def test_simple_xml_chunk_1(self): ++ self.test_simple_xml(chunk_size=1) ++ ++ @fails_with_expat_2_6_0 ++ def test_simple_xml_chunk_5(self): ++ self.test_simple_xml(chunk_size=5) ++ ++ def test_simple_xml_chunk_22(self): ++ self.test_simple_xml(chunk_size=22) + + def test_feed_while_iterating(self): + parser = ET.XMLPullParser() +diff --git a/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst b/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst +new file mode 100644 +index 0000000000..6f1015235c +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst +@@ -0,0 +1,2 @@ ++Fix tests for :class:`~xml.etree.ElementTree.XMLPullParser` with Expat ++2.6.0. diff --git a/python3.9.spec b/python3.9.spec index 5421790..9d09fa1 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 6%{?dist} +Release: 7%{?dist} License: Python @@ -398,6 +398,13 @@ Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-par # zlib-ng defines the version as "1.3.0.zlib-ng". Patch419: 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch +# 00422 # 3363cf965ad5749742569d341919724c9e69accf +# gh-115133: Fix tests for XMLPullParser with Expat 2.6.0 +# +# Feeding the parser by too small chunks defers parsing to prevent +# CVE-2023-52425. Future versions of Expat may be more reactive. +Patch422: 00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1824,6 +1831,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Feb 28 2024 Charalampos Stratakis - 3.9.18-7 +- Fix tests for XMLPullParser with Expat 2.6.0 + * Mon Jan 29 2024 Karolina Surma - 3.9.18-6 - Fix test_zlib when building with zlib-ng-compat From 8af0aa70c5424a37aaf6ade5ae2c78df5e0d232f Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Wed, 28 Feb 2024 17:16:55 +0100 Subject: [PATCH 60/89] Fix tests for XMLPullParser with Expat 2.6.0 See also: https://bugzilla.redhat.com/2264859 --- ...s-for-xmlpullparser-with-expat-2-6-0.patch | 110 ++++++++++++++++++ python3.9.spec | 12 +- 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch diff --git a/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch b/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch new file mode 100644 index 0000000..cf5babc --- /dev/null +++ b/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Wed, 21 Feb 2024 05:22:55 -0600 +Subject: [PATCH] 00422: gh-115133: Fix tests for XMLPullParser with Expat + 2.6.0 + +Feeding the parser by too small chunks defers parsing to prevent +CVE-2023-52425. Future versions of Expat may be more reactive. +(cherry picked from commit 4a08e7b3431cd32a0daf22a33421cd3035343dc4) + +Co-authored-by: Serhiy Storchaka +--- + Lib/test/test_xml_etree.py | 60 ++++++++++++------- + ...-02-08-14-21-28.gh-issue-115133.ycl4ko.rst | 2 + + 2 files changed, 40 insertions(+), 22 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst + +diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py +index 7c346f279a..48e7c79932 100644 +--- a/Lib/test/test_xml_etree.py ++++ b/Lib/test/test_xml_etree.py +@@ -13,6 +13,7 @@ import itertools + import operator + import os + import pickle ++import pyexpat + import sys + import textwrap + import types +@@ -102,6 +103,12 @@ EXTERNAL_ENTITY_XML = """\ + &entity; + """ + ++ ++fails_with_expat_2_6_0 = (unittest.expectedFailure ++ if pyexpat.version_info >= (2, 6, 0) else ++ lambda test: test) ++ ++ + def checkwarnings(*filters, quiet=False): + def decorator(test): + def newtest(*args, **kwargs): +@@ -1391,28 +1398,37 @@ class XMLPullParserTest(unittest.TestCase): + self.assertEqual([(action, elem.tag) for action, elem in events], + expected) + +- def test_simple_xml(self): +- for chunk_size in (None, 1, 5): +- with self.subTest(chunk_size=chunk_size): +- parser = ET.XMLPullParser() +- self.assert_event_tags(parser, []) +- self._feed(parser, "\n", chunk_size) +- self.assert_event_tags(parser, []) +- self._feed(parser, +- "\n text\n", chunk_size) +- self.assert_event_tags(parser, [('end', 'element')]) +- self._feed(parser, "texttail\n", chunk_size) +- self._feed(parser, "\n", chunk_size) +- self.assert_event_tags(parser, [ +- ('end', 'element'), +- ('end', 'empty-element'), +- ]) +- self._feed(parser, "\n", chunk_size) +- self.assert_event_tags(parser, [('end', 'root')]) +- self.assertIsNone(parser.close()) ++ def test_simple_xml(self, chunk_size=None): ++ parser = ET.XMLPullParser() ++ self.assert_event_tags(parser, []) ++ self._feed(parser, "\n", chunk_size) ++ self.assert_event_tags(parser, []) ++ self._feed(parser, ++ "\n text\n", chunk_size) ++ self.assert_event_tags(parser, [('end', 'element')]) ++ self._feed(parser, "texttail\n", chunk_size) ++ self._feed(parser, "\n", chunk_size) ++ self.assert_event_tags(parser, [ ++ ('end', 'element'), ++ ('end', 'empty-element'), ++ ]) ++ self._feed(parser, "\n", chunk_size) ++ self.assert_event_tags(parser, [('end', 'root')]) ++ self.assertIsNone(parser.close()) ++ ++ @fails_with_expat_2_6_0 ++ def test_simple_xml_chunk_1(self): ++ self.test_simple_xml(chunk_size=1) ++ ++ @fails_with_expat_2_6_0 ++ def test_simple_xml_chunk_5(self): ++ self.test_simple_xml(chunk_size=5) ++ ++ def test_simple_xml_chunk_22(self): ++ self.test_simple_xml(chunk_size=22) + + def test_feed_while_iterating(self): + parser = ET.XMLPullParser() +diff --git a/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst b/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst +new file mode 100644 +index 0000000000..6f1015235c +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst +@@ -0,0 +1,2 @@ ++Fix tests for :class:`~xml.etree.ElementTree.XMLPullParser` with Expat ++2.6.0. diff --git a/python3.9.spec b/python3.9.spec index 43ef99e..f690be7 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 4%{?dist} License: Python @@ -392,6 +392,13 @@ Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-fo # Thomas Dwyer. Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch +# 00422 # 3363cf965ad5749742569d341919724c9e69accf +# gh-115133: Fix tests for XMLPullParser with Expat 2.6.0 +# +# Feeding the parser by too small chunks defers parsing to prevent +# CVE-2023-52425. Future versions of Expat may be more reactive. +Patch422: 00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1818,6 +1825,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Feb 28 2024 Charalampos Stratakis - 3.9.18-4 +- Fix tests for XMLPullParser with Expat 2.6.0 + * Mon Dec 18 2023 Lumír Balhar - 3.9.18-3 - Security fix for CVE-2023-27043 (rhbz#2196194) From 59b6d298e95925a8accf571bace0e276eedf2806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 20 Mar 2024 13:46:34 +0100 Subject: [PATCH 61/89] Update to 3.9.19 --- 00111-no-static-lib.patch | 2 +- 00251-change-user-install-location.patch | 4 +- ...s-for-xmlpullparser-with-expat-2-6-0.patch | 110 ------------------ python3.9.spec | 14 +-- sources | 4 +- 5 files changed, 10 insertions(+), 124 deletions(-) delete mode 100644 00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index d6ac5d4..37966be 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -21,7 +21,7 @@ Co-authored-by: Miro Hrončok 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in -index c0272bfcdd..b64837c126 100644 +index a276d535c7..568018827b 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -588,7 +588,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 074e59d..f961419 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -61,10 +61,10 @@ index aaa300efa9..18f01f10d4 100644 else: if self.exec_prefix is None: diff --git a/Lib/site.py b/Lib/site.py -index 9e617afb00..db14f715f9 100644 +index 54ffc4fdc0..930b91813e 100644 --- a/Lib/site.py +++ b/Lib/site.py -@@ -353,7 +353,14 @@ def getsitepackages(prefixes=None): +@@ -362,7 +362,14 @@ def getsitepackages(prefixes=None): return sitepackages def addsitepackages(known_paths, prefixes=None): diff --git a/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch b/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch deleted file mode 100644 index cf5babc..0000000 --- a/00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Wed, 21 Feb 2024 05:22:55 -0600 -Subject: [PATCH] 00422: gh-115133: Fix tests for XMLPullParser with Expat - 2.6.0 - -Feeding the parser by too small chunks defers parsing to prevent -CVE-2023-52425. Future versions of Expat may be more reactive. -(cherry picked from commit 4a08e7b3431cd32a0daf22a33421cd3035343dc4) - -Co-authored-by: Serhiy Storchaka ---- - Lib/test/test_xml_etree.py | 60 ++++++++++++------- - ...-02-08-14-21-28.gh-issue-115133.ycl4ko.rst | 2 + - 2 files changed, 40 insertions(+), 22 deletions(-) - create mode 100644 Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst - -diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py -index 7c346f279a..48e7c79932 100644 ---- a/Lib/test/test_xml_etree.py -+++ b/Lib/test/test_xml_etree.py -@@ -13,6 +13,7 @@ import itertools - import operator - import os - import pickle -+import pyexpat - import sys - import textwrap - import types -@@ -102,6 +103,12 @@ EXTERNAL_ENTITY_XML = """\ - &entity; - """ - -+ -+fails_with_expat_2_6_0 = (unittest.expectedFailure -+ if pyexpat.version_info >= (2, 6, 0) else -+ lambda test: test) -+ -+ - def checkwarnings(*filters, quiet=False): - def decorator(test): - def newtest(*args, **kwargs): -@@ -1391,28 +1398,37 @@ class XMLPullParserTest(unittest.TestCase): - self.assertEqual([(action, elem.tag) for action, elem in events], - expected) - -- def test_simple_xml(self): -- for chunk_size in (None, 1, 5): -- with self.subTest(chunk_size=chunk_size): -- parser = ET.XMLPullParser() -- self.assert_event_tags(parser, []) -- self._feed(parser, "\n", chunk_size) -- self.assert_event_tags(parser, []) -- self._feed(parser, -- "\n text\n", chunk_size) -- self.assert_event_tags(parser, [('end', 'element')]) -- self._feed(parser, "texttail\n", chunk_size) -- self._feed(parser, "\n", chunk_size) -- self.assert_event_tags(parser, [ -- ('end', 'element'), -- ('end', 'empty-element'), -- ]) -- self._feed(parser, "\n", chunk_size) -- self.assert_event_tags(parser, [('end', 'root')]) -- self.assertIsNone(parser.close()) -+ def test_simple_xml(self, chunk_size=None): -+ parser = ET.XMLPullParser() -+ self.assert_event_tags(parser, []) -+ self._feed(parser, "\n", chunk_size) -+ self.assert_event_tags(parser, []) -+ self._feed(parser, -+ "\n text\n", chunk_size) -+ self.assert_event_tags(parser, [('end', 'element')]) -+ self._feed(parser, "texttail\n", chunk_size) -+ self._feed(parser, "\n", chunk_size) -+ self.assert_event_tags(parser, [ -+ ('end', 'element'), -+ ('end', 'empty-element'), -+ ]) -+ self._feed(parser, "\n", chunk_size) -+ self.assert_event_tags(parser, [('end', 'root')]) -+ self.assertIsNone(parser.close()) -+ -+ @fails_with_expat_2_6_0 -+ def test_simple_xml_chunk_1(self): -+ self.test_simple_xml(chunk_size=1) -+ -+ @fails_with_expat_2_6_0 -+ def test_simple_xml_chunk_5(self): -+ self.test_simple_xml(chunk_size=5) -+ -+ def test_simple_xml_chunk_22(self): -+ self.test_simple_xml(chunk_size=22) - - def test_feed_while_iterating(self): - parser = ET.XMLPullParser() -diff --git a/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst b/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst -new file mode 100644 -index 0000000000..6f1015235c ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2024-02-08-14-21-28.gh-issue-115133.ycl4ko.rst -@@ -0,0 +1,2 @@ -+Fix tests for :class:`~xml.etree.ElementTree.XMLPullParser` with Expat -+2.6.0. diff --git a/python3.9.spec b/python3.9.spec index 9d09fa1..70c657b 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.18 +%global general_version %{pybasever}.19 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 7%{?dist} +Release: 1%{?dist} License: Python @@ -398,13 +398,6 @@ Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-par # zlib-ng defines the version as "1.3.0.zlib-ng". Patch419: 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch -# 00422 # 3363cf965ad5749742569d341919724c9e69accf -# gh-115133: Fix tests for XMLPullParser with Expat 2.6.0 -# -# Feeding the parser by too small chunks defers parsing to prevent -# CVE-2023-52425. Future versions of Expat may be more reactive. -Patch422: 00422-gh-115133-fix-tests-for-xmlpullparser-with-expat-2-6-0.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1831,6 +1824,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Mar 20 2024 Tomáš Hrnčiar - 3.9.19-1 +- Update to 3.9.19 + * Wed Feb 28 2024 Charalampos Stratakis - 3.9.18-7 - Fix tests for XMLPullParser with Expat 2.6.0 diff --git a/sources b/sources index 19cb08f..be10285 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.18.tar.xz) = aab155aca757d298394eddb91ff9a8f239665bd46feb495c6b6f735bbcb7489c05c858cc4cd08f1575c24f293b33492d763e9a140d92f0b2b0cc81a165a677c7 -SHA512 (Python-3.9.18.tar.xz.asc) = dff9a86df2b0774b68e7c762bacf05e2482dbb218301acfdc9128fc600bbc51c97a3a44f6b7cee87bd4e153bcb4a0af3c98109560d0c7861b7508edc9ae05ea1 +SHA512 (Python-3.9.19.tar.xz) = 5577830c734e63a70bbc62cd33d263b9aa87c4381b49cb694c3559067c4c682a55506b65ec5514a8e0a5abf6294dc728e909385d449ae1c388e62f83cea9bb89 +SHA512 (Python-3.9.19.tar.xz.asc) = f7f4946243dfc56de2c84f50276b088d347f17054f50e3331d1e312e2a8e2c6ed1b4b4a807202b51137fd2af3fc9218cafa42ed348a954ace896d9a432e2defd From 64188e0caeb0a8918412b8a1d5c0cdf36f271afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 17 Apr 2024 22:58:28 +0000 Subject: [PATCH 62/89] Require expat >= 2.6 to prevent errors when creating venvs with older expat The code in CPython uses XML_SetReparseDeferralEnabled when expat is >= 2.6 during the build. However, when users upgrade Python independently on the expat package, they may have expat 2.5 installed and see errors like: $ python3.1X -m venv venv Error: Command '['venv/bin/python3.1X', '-m', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1. $ venv/bin/python3.1X -m ensurepip --upgrade --default-pip Traceback (most recent call last): ... File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_internal/commands/install.py", line 15, in from pip._internal.cli.req_command import ( ...<3 lines>... ) File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_internal/cli/req_command.py", line 21, in from pip._internal.index.package_finder import PackageFinder File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_internal/index/package_finder.py", line 30, in from pip._internal.req import InstallRequirement File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_internal/req/__init__.py", line 8, in from .req_install import InstallRequirement File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_internal/req/req_install.py", line 40, in from pip._internal.operations.install.wheel import install_wheel File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_internal/operations/install/wheel.py", line 39, in from pip._vendor.distlib.scripts import ScriptMaker File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_vendor/distlib/scripts.py", line 16, in from .compat import sysconfig, detect_encoding, ZipFile File "/tmp/.../pip-24.0-py3-none-any.whl/pip/_vendor/distlib/compat.py", line 81, in import xmlrpc.client as xmlrpclib File "/usr/lib64/python3.1X/xmlrpc/client.py", line 138, in from xml.parsers import expat File "/usr/lib64/python3.1X/xml/parsers/expat.py", line 4, in from pyexpat import * ImportError: /usr/lib64/python3.1X/lib-dynload/pyexpat.cpython-31X-x86_64-linux-gnu.so: undefined symbol: XML_SetReparseDeferralEnabled Traceback (most recent call last): ... subprocess.CalledProcessError: Command '['venv/bin/python3.1X', '-W', 'ignore::DeprecationWarning', '-c', '\nimport runpy\nimport sys\nsys.path = [\'/tmp/.../pip-24.0-py3-none-any.whl\'] + sys.path\nsys.argv[1:] = [\'install\', \'--no-cache-dir\', \'--no-index\', \'--find-links\', \'/tmp/...\', \'--upgrade\', \'pip\']\nrunpy.run_module("pip", run_name="__main__", alter_sys=True)\n']' returned non-zero exit status 1. Thanks to Markus Falb for discovering this problem. https://lists.fedoraproject.org/archives/list/python-devel@lists.fedoraproject.org/thread/7XHGWHBQDNFKNGSZTP44SSD6PQKZPG6C/ --- python3.9.spec | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 70c657b..3a2e159 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -218,7 +218,8 @@ BuildRequires: bluez-libs-devel BuildRequires: bzip2 BuildRequires: bzip2-devel BuildRequires: desktop-file-utils -BuildRequires: expat-devel +# See the runtime requirement in the -libs subpackage +BuildRequires: expat-devel >= 2.6 BuildRequires: findutils BuildRequires: gcc-c++ @@ -564,6 +565,14 @@ Recommends: (%{pkgname}-tkinter%{?_isa} = %{version}-%{release} if tk%{?_isa}) # The zoneinfo module needs tzdata Requires: tzdata +# The requirement on libexpat is generated, but we need to version it. +# When built with expat >= 2.6, but installed with older expat, we get: +# ImportError: /usr/lib64/python3.X/lib-dynload/pyexpat.cpython-....so: +# undefined symbol: XML_SetReparseDeferralEnabled +# This breaks many things, including python -m venv. +# Other subpackages (like -debug) also need this, but they all depend on -libs. +Requires: expat >= 2.6 + # https://fedoraproject.org/wiki/Changes/Move_usr_bin_python_into_separate_package # In Fedora 31, several "unversioned" files like /usr/bin/pydoc and all the # "unversioned" provides were moved from python2 to python3. @@ -755,6 +764,14 @@ Provides: bundled(libmpdec) = %{libmpdec_version} # The zoneinfo module needs tzdata Requires: tzdata +# The requirement on libexpat is generated, but we need to version it. +# When built with expat >= 2.6, but installed with older expat, we get: +# ImportError: /usr/lib64/python3.X/lib-dynload/pyexpat.cpython-....so: +# undefined symbol: XML_SetReparseDeferralEnabled +# This breaks many things, including python -m venv. +# Other subpackages (like -debug) also need this, but they all depend on -libs. +Requires: expat >= 2.6 + # The description for the flat package (SRPM and built) %description Python %{pybasever} package for developers. @@ -1824,6 +1841,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Apr 17 2024 Miro Hrončok - 3.9.19-2 +- Require expat >= 2.6 to prevent errors when creating venvs with older expat + * Wed Mar 20 2024 Tomáš Hrnčiar - 3.9.19-1 - Update to 3.9.19 From 66a8abedb7d597dccc13d496c3639b156ed58a32 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jul 2024 17:27:24 +0000 Subject: [PATCH 63/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 3a2e159..7207f62 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -1841,6 +1841,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 19 2024 Fedora Release Engineering - 3.9.19-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Wed Apr 17 2024 Miro Hrončok - 3.9.19-2 - Require expat >= 2.6 to prevent errors when creating venvs with older expat From b5c1ec2e2e16204328d7e74b6abaf8e4e1c6dd92 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Tue, 23 Jul 2024 13:22:18 +0200 Subject: [PATCH 64/89] Require systemtap-sdt-devel for sys/sdt.h --- python3.9.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 7207f62..b7c02c4 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 4%{?dist} License: Python @@ -261,6 +261,7 @@ BuildRequires: valgrind-devel BuildRequires: xz-devel BuildRequires: zlib-devel +BuildRequires: systemtap-sdt-devel BuildRequires: /usr/bin/dtrace # workaround http://bugs.python.org/issue19804 (test_uuid requires ifconfig) @@ -1841,6 +1842,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Jul 23 2024 Lumír Balhar - 3.9.19-4 +- Require systemtap-sdt-devel for sys/sdt.h + * Fri Jul 19 2024 Fedora Release Engineering - 3.9.19-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From d6f5072e8dc28a694eaf0b466375cad14c365447 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Wed, 14 Aug 2024 07:34:35 +0200 Subject: [PATCH 65/89] Security fix for CVE-2024-4032 (rhbz#2293397) --- ...113179-gh-113186-gh-118177-gh-118472.patch | 399 ++++++++++++++++++ python3.9.spec | 35 +- 2 files changed, 433 insertions(+), 1 deletion(-) create mode 100644 00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch diff --git a/00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch b/00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch new file mode 100644 index 0000000..1f3563b --- /dev/null +++ b/00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch @@ -0,0 +1,399 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Petr Viktorin +Date: Tue, 7 May 2024 11:57:58 +0200 +Subject: [PATCH] 00431: gh-113171: gh-65056: Fix "private" (non-global) IP + address ranges (GH-113179) (GH-113186) (GH-118177) (GH-118472) + +The _private_networks variables, used by various is_private +implementations, were missing some ranges and at the same time had +overly strict ranges (where there are more specific ranges considered +globally reachable by the IANA registries). + +This patch updates the ranges with what was missing or otherwise +incorrect. + +100.64.0.0/10 is left alone, for now, as it's been made special in [1]. + +The _address_exclude_many() call returns 8 networks for IPv4, 121 +networks for IPv6. + +[1] https://github.com/python/cpython/issues/61602 + +In 3.10 and below, is_private checks whether the network and broadcast +address are both private. +In later versions (where the test wss backported from), it checks +whether they both are in the same private network. + +For 0.0.0.0/0, both 0.0.0.0 and 255.225.255.255 are private, +but one is in 0.0.0.0/8 ("This network") and the other in +255.255.255.255/32 ("Limited broadcast"). + +--------- + +Co-authored-by: Jakub Stasiak +--- + Doc/library/ipaddress.rst | 43 ++++++++- + Doc/tools/susp-ignored.csv | 8 ++ + Doc/whatsnew/3.9.rst | 9 ++ + Lib/ipaddress.py | 95 +++++++++++++++---- + Lib/test/test_ipaddress.py | 52 ++++++++++ + ...-03-14-01-38-44.gh-issue-113171.VFnObz.rst | 9 ++ + 6 files changed, 195 insertions(+), 21 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst + +diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst +index 9c2dff5570..f9c1ebf3f3 100644 +--- a/Doc/library/ipaddress.rst ++++ b/Doc/library/ipaddress.rst +@@ -188,18 +188,53 @@ write code that handles both IP versions correctly. Address objects are + + .. attribute:: is_private + +- ``True`` if the address is allocated for private networks. See ++ ``True`` if the address is defined as not globally reachable by + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ +- (for IPv6). ++ (for IPv6) with the following exceptions: ++ ++ * ``is_private`` is ``False`` for the shared address space (``100.64.0.0/10``) ++ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: ++ ++ address.is_private == address.ipv4_mapped.is_private ++ ++ ``is_private`` has value opposite to :attr:`is_global`, except for the shared address space ++ (``100.64.0.0/10`` range) where they are both ``False``. ++ ++ .. versionchanged:: 3.9.20 ++ ++ Fixed some false positives and false negatives. ++ ++ * ``192.0.0.0/24`` is considered private with the exception of ``192.0.0.9/32`` and ++ ``192.0.0.10/32`` (previously: only the ``192.0.0.0/29`` sub-range was considered private). ++ * ``64:ff9b:1::/48`` is considered private. ++ * ``2002::/16`` is considered private. ++ * There are exceptions within ``2001::/23`` (otherwise considered private): ``2001:1::1/128``, ++ ``2001:1::2/128``, ``2001:3::/32``, ``2001:4:112::/48``, ``2001:20::/28``, ``2001:30::/28``. ++ The exceptions are not considered private. + + .. attribute:: is_global + +- ``True`` if the address is allocated for public networks. See ++ ``True`` if the address is defined as globally reachable by + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ +- (for IPv6). ++ (for IPv6) with the following exception: ++ ++ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: ++ ++ address.is_global == address.ipv4_mapped.is_global ++ ++ ``is_global`` has value opposite to :attr:`is_private`, except for the shared address space ++ (``100.64.0.0/10`` range) where they are both ``False``. + + .. versionadded:: 3.4 + ++ .. versionchanged:: 3.9.20 ++ ++ Fixed some false positives and false negatives, see :attr:`is_private` for details. ++ + .. attribute:: is_unspecified + + ``True`` if the address is unspecified. See :RFC:`5735` (for IPv4) +diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv +index 3eb3d7954f..de91a50bad 100644 +--- a/Doc/tools/susp-ignored.csv ++++ b/Doc/tools/susp-ignored.csv +@@ -169,6 +169,14 @@ library/ipaddress,,:db00,2001:db00::0/24 + library/ipaddress,,::,2001:db00::0/24 + library/ipaddress,,:db00,2001:db00::0/ffff:ff00:: + library/ipaddress,,::,2001:db00::0/ffff:ff00:: ++library/ipaddress,,:ff9b,64:ff9b:1::/48 ++library/ipaddress,,::,64:ff9b:1::/48 ++library/ipaddress,,::,2001:: ++library/ipaddress,,::,2001:1:: ++library/ipaddress,,::,2001:3:: ++library/ipaddress,,::,2001:4:112:: ++library/ipaddress,,::,2001:20:: ++library/ipaddress,,::,2001:30:: + library/itertools,,:step,elements from seq[start:stop:step] + library/itertools,,:stop,elements from seq[start:stop:step] + library/itertools,,::,kernel = tuple(kernel)[::-1] +diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst +index 0064e074a3..1756a37338 100644 +--- a/Doc/whatsnew/3.9.rst ++++ b/Doc/whatsnew/3.9.rst +@@ -1616,3 +1616,12 @@ tarfile + :exc:`DeprecationWarning`. + In Python 3.14, the default will switch to ``'data'``. + (Contributed by Petr Viktorin in :pep:`706`.) ++ ++Notable changes in 3.9.20 ++========================= ++ ++ipaddress ++--------- ++ ++* Fixed ``is_global`` and ``is_private`` behavior in ``IPv4Address``, ++ ``IPv6Address``, ``IPv4Network`` and ``IPv6Network``. +diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py +index 25f373a06a..9b35340d9a 100644 +--- a/Lib/ipaddress.py ++++ b/Lib/ipaddress.py +@@ -1322,18 +1322,41 @@ class IPv4Address(_BaseV4, _BaseAddress): + @property + @functools.lru_cache() + def is_private(self): +- """Test if this address is allocated for private networks. ++ """``True`` if the address is defined as not globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exceptions: + +- Returns: +- A boolean, True if the address is reserved per +- iana-ipv4-special-registry. ++ * ``is_private`` is ``False`` for ``100.64.0.0/10`` ++ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: + ++ address.is_private == address.ipv4_mapped.is_private ++ ++ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. + """ +- return any(self in net for net in self._constants._private_networks) ++ return ( ++ any(self in net for net in self._constants._private_networks) ++ and all(self not in net for net in self._constants._private_networks_exceptions) ++ ) + + @property + @functools.lru_cache() + def is_global(self): ++ """``True`` if the address is defined as globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exception: ++ ++ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: ++ ++ address.is_global == address.ipv4_mapped.is_global ++ ++ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. ++ """ + return self not in self._constants._public_network and not self.is_private + + @property +@@ -1537,13 +1560,15 @@ class _IPv4Constants: + + _public_network = IPv4Network('100.64.0.0/10') + ++ # Not globally reachable address blocks listed on ++ # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), +- IPv4Network('192.0.0.0/29'), ++ IPv4Network('192.0.0.0/24'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), +@@ -1554,6 +1579,11 @@ class _IPv4Constants: + IPv4Network('255.255.255.255/32'), + ] + ++ _private_networks_exceptions = [ ++ IPv4Network('192.0.0.9/32'), ++ IPv4Network('192.0.0.10/32'), ++ ] ++ + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') +@@ -1995,23 +2025,42 @@ class IPv6Address(_BaseV6, _BaseAddress): + @property + @functools.lru_cache() + def is_private(self): +- """Test if this address is allocated for private networks. ++ """``True`` if the address is defined as not globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exceptions: + +- Returns: +- A boolean, True if the address is reserved per +- iana-ipv6-special-registry. ++ * ``is_private`` is ``False`` for ``100.64.0.0/10`` ++ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: + ++ address.is_private == address.ipv4_mapped.is_private ++ ++ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. + """ +- return any(self in net for net in self._constants._private_networks) ++ ipv4_mapped = self.ipv4_mapped ++ if ipv4_mapped is not None: ++ return ipv4_mapped.is_private ++ return ( ++ any(self in net for net in self._constants._private_networks) ++ and all(self not in net for net in self._constants._private_networks_exceptions) ++ ) + + @property + def is_global(self): +- """Test if this address is allocated for public networks. ++ """``True`` if the address is defined as globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exception: + +- Returns: +- A boolean, true if the address is not reserved per +- iana-ipv6-special-registry. ++ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: + ++ address.is_global == address.ipv4_mapped.is_global ++ ++ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. + """ + return not self.is_private + +@@ -2252,19 +2301,31 @@ class _IPv6Constants: + + _multicast_network = IPv6Network('ff00::/8') + ++ # Not globally reachable address blocks listed on ++ # https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), ++ IPv6Network('64:ff9b:1::/48'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), +- IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), +- IPv6Network('2001:10::/28'), ++ # IANA says N/A, let's consider it not globally reachable to be safe ++ IPv6Network('2002::/16'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + ++ _private_networks_exceptions = [ ++ IPv6Network('2001:1::1/128'), ++ IPv6Network('2001:1::2/128'), ++ IPv6Network('2001:3::/32'), ++ IPv6Network('2001:4:112::/48'), ++ IPv6Network('2001:20::/28'), ++ IPv6Network('2001:30::/28'), ++ ] ++ + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), +diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py +index 90897f6bed..bd14f04f6c 100644 +--- a/Lib/test/test_ipaddress.py ++++ b/Lib/test/test_ipaddress.py +@@ -2263,6 +2263,10 @@ class IpaddrUnitTest(unittest.TestCase): + self.assertEqual(True, ipaddress.ip_address( + '172.31.255.255').is_private) + self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private) ++ self.assertFalse(ipaddress.ip_address('192.0.0.0').is_global) ++ self.assertTrue(ipaddress.ip_address('192.0.0.9').is_global) ++ self.assertTrue(ipaddress.ip_address('192.0.0.10').is_global) ++ self.assertFalse(ipaddress.ip_address('192.0.0.255').is_global) + + self.assertEqual(True, + ipaddress.ip_address('169.254.100.200').is_link_local) +@@ -2278,6 +2282,40 @@ class IpaddrUnitTest(unittest.TestCase): + self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback) + self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified) + ++ def testPrivateNetworks(self): ++ self.assertEqual(True, ipaddress.ip_network("0.0.0.0/0").is_private) ++ self.assertEqual(False, ipaddress.ip_network("1.0.0.0/8").is_private) ++ ++ self.assertEqual(True, ipaddress.ip_network("0.0.0.0/8").is_private) ++ self.assertEqual(True, ipaddress.ip_network("10.0.0.0/8").is_private) ++ self.assertEqual(True, ipaddress.ip_network("127.0.0.0/8").is_private) ++ self.assertEqual(True, ipaddress.ip_network("169.254.0.0/16").is_private) ++ self.assertEqual(True, ipaddress.ip_network("172.16.0.0/12").is_private) ++ self.assertEqual(True, ipaddress.ip_network("192.0.0.0/29").is_private) ++ self.assertEqual(False, ipaddress.ip_network("192.0.0.9/32").is_private) ++ self.assertEqual(True, ipaddress.ip_network("192.0.0.170/31").is_private) ++ self.assertEqual(True, ipaddress.ip_network("192.0.2.0/24").is_private) ++ self.assertEqual(True, ipaddress.ip_network("192.168.0.0/16").is_private) ++ self.assertEqual(True, ipaddress.ip_network("198.18.0.0/15").is_private) ++ self.assertEqual(True, ipaddress.ip_network("198.51.100.0/24").is_private) ++ self.assertEqual(True, ipaddress.ip_network("203.0.113.0/24").is_private) ++ self.assertEqual(True, ipaddress.ip_network("240.0.0.0/4").is_private) ++ self.assertEqual(True, ipaddress.ip_network("255.255.255.255/32").is_private) ++ ++ self.assertEqual(False, ipaddress.ip_network("::/0").is_private) ++ self.assertEqual(False, ipaddress.ip_network("::ff/128").is_private) ++ ++ self.assertEqual(True, ipaddress.ip_network("::1/128").is_private) ++ self.assertEqual(True, ipaddress.ip_network("::/128").is_private) ++ self.assertEqual(True, ipaddress.ip_network("::ffff:0:0/96").is_private) ++ self.assertEqual(True, ipaddress.ip_network("100::/64").is_private) ++ self.assertEqual(True, ipaddress.ip_network("2001:2::/48").is_private) ++ self.assertEqual(False, ipaddress.ip_network("2001:3::/48").is_private) ++ self.assertEqual(True, ipaddress.ip_network("2001:db8::/32").is_private) ++ self.assertEqual(True, ipaddress.ip_network("2001:10::/28").is_private) ++ self.assertEqual(True, ipaddress.ip_network("fc00::/7").is_private) ++ self.assertEqual(True, ipaddress.ip_network("fe80::/10").is_private) ++ + def testReservedIpv6(self): + + self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast) +@@ -2351,6 +2389,20 @@ class IpaddrUnitTest(unittest.TestCase): + self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified) + self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified) + ++ self.assertFalse(ipaddress.ip_address('64:ff9b:1::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:1::1').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:1::2').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:2::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:3::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:4::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:4:112::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:10::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:20::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:30::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:40::').is_global) ++ self.assertFalse(ipaddress.ip_address('2002::').is_global) ++ + # some generic IETF reserved addresses + self.assertEqual(True, ipaddress.ip_address('100::').is_reserved) + self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved) +diff --git a/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst b/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst +new file mode 100644 +index 0000000000..f9a72473be +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst +@@ -0,0 +1,9 @@ ++Fixed various false positives and false negatives in ++ ++* :attr:`ipaddress.IPv4Address.is_private` (see these docs for details) ++* :attr:`ipaddress.IPv4Address.is_global` ++* :attr:`ipaddress.IPv6Address.is_private` ++* :attr:`ipaddress.IPv6Address.is_global` ++ ++Also in the corresponding :class:`ipaddress.IPv4Network` and :class:`ipaddress.IPv6Network` ++attributes. diff --git a/python3.9.spec b/python3.9.spec index b7c02c4..c924e0f 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 4%{?dist} +Release: 5%{?dist} License: Python @@ -400,6 +400,36 @@ Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-par # zlib-ng defines the version as "1.3.0.zlib-ng". Patch419: 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch +# 00431 # 1216ca6d2f3d6fc7ef7bf33b78b7a887be02e467 +# gh-113171: gh-65056: Fix "private" (non-global) IP address ranges (GH-113179) (GH-113186) (GH-118177) (GH-118472) +# +# The _private_networks variables, used by various is_private +# implementations, were missing some ranges and at the same time had +# overly strict ranges (where there are more specific ranges considered +# globally reachable by the IANA registries). +# +# This patch updates the ranges with what was missing or otherwise +# incorrect. +# +# 100.64.0.0/10 is left alone, for now, as it's been made special in [1]. +# +# The _address_exclude_many() call returns 8 networks for IPv4, 121 +# networks for IPv6. +# +# [1] https://github.com/python/cpython/issues/61602 +# +# In 3.10 and below, is_private checks whether the network and broadcast +# address are both private. +# In later versions (where the test wss backported from), it checks +# whether they both are in the same private network. +# +# For 0.0.0.0/0, both 0.0.0.0 and 255.225.255.255 are private, +# but one is in 0.0.0.0/8 ("This network") and the other in +# 255.255.255.255/32 ("Limited broadcast"). +# +# --------- +Patch431: 00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1842,6 +1872,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Aug 13 2024 Lumír Balhar - 3.9.19-5 +- Security fix for CVE-2024-4032 (rhbz#2293397) + * Tue Jul 23 2024 Lumír Balhar - 3.9.19-4 - Require systemtap-sdt-devel for sys/sdt.h From 77d7aaf42c57760d56a7c507b84dd6dc5ea0c319 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Wed, 14 Aug 2024 07:36:16 +0200 Subject: [PATCH 66/89] Security fix for CVE-2024-6923 (rhbz#2303164) --- ...d-verify-headers-are-sound-gh-122233.patch | 356 ++++++++++++++++++ python3.9.spec | 20 + 2 files changed, 376 insertions(+) create mode 100644 00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch diff --git a/00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch b/00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch new file mode 100644 index 0000000..432920d --- /dev/null +++ b/00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch @@ -0,0 +1,356 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Petr Viktorin +Date: Wed, 31 Jul 2024 00:19:48 +0200 +Subject: [PATCH] 00435: gh-121650: Encode newlines in headers, and verify + headers are sound (GH-122233) + +Per RFC 2047: + +> [...] these encoding schemes allow the +> encoding of arbitrary octet values, mail readers that implement this +> decoding should also ensure that display of the decoded data on the +> recipient's terminal will not cause unwanted side-effects + +It seems that the "quoted-word" scheme is a valid way to include +a newline character in a header value, just like we already allow +undecodable bytes or control characters. +They do need to be properly quoted when serialized to text, though. + +This should fail for custom fold() implementations that aren't careful +about newlines. + +(cherry picked from commit 097633981879b3c9de9a1dd120d3aa585ecc2384) + +Co-authored-by: Petr Viktorin +Co-authored-by: Bas Bloemsaat +Co-authored-by: Serhiy Storchaka +--- + Doc/library/email.errors.rst | 6 ++ + Doc/library/email.policy.rst | 18 ++++++ + Doc/whatsnew/3.9.rst | 12 ++++ + Lib/email/_header_value_parser.py | 12 +++- + Lib/email/_policybase.py | 8 +++ + Lib/email/errors.py | 4 ++ + Lib/email/generator.py | 13 +++- + Lib/test/test_email/test_generator.py | 62 +++++++++++++++++++ + Lib/test/test_email/test_policy.py | 26 ++++++++ + ...-07-27-16-10-41.gh-issue-121650.nf6oc9.rst | 5 ++ + 10 files changed, 162 insertions(+), 4 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst + +diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst +index f4b9f52509..878c09bb04 100644 +--- a/Doc/library/email.errors.rst ++++ b/Doc/library/email.errors.rst +@@ -59,6 +59,12 @@ The following exception classes are defined in the :mod:`email.errors` module: + :class:`~email.mime.image.MIMEImage`). + + ++.. exception:: HeaderWriteError() ++ ++ Raised when an error occurs when the :mod:`~email.generator` outputs ++ headers. ++ ++ + Here is the list of the defects that the :class:`~email.parser.FeedParser` + can find while parsing messages. Note that the defects are added to the message + where the problem was found, so for example, if a message nested inside a +diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst +index bf53b9520f..57a75ce452 100644 +--- a/Doc/library/email.policy.rst ++++ b/Doc/library/email.policy.rst +@@ -229,6 +229,24 @@ added matters. To illustrate:: + + .. versionadded:: 3.6 + ++ ++ .. attribute:: verify_generated_headers ++ ++ If ``True`` (the default), the generator will raise ++ :exc:`~email.errors.HeaderWriteError` instead of writing a header ++ that is improperly folded or delimited, such that it would ++ be parsed as multiple headers or joined with adjacent data. ++ Such headers can be generated by custom header classes or bugs ++ in the ``email`` module. ++ ++ As it's a security feature, this defaults to ``True`` even in the ++ :class:`~email.policy.Compat32` policy. ++ For backwards compatible, but unsafe, behavior, it must be set to ++ ``False`` explicitly. ++ ++ .. versionadded:: 3.9.20 ++ ++ + The following :class:`Policy` method is intended to be called by code using + the email library to create policy instances with custom settings: + +diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst +index 1756a37338..eeda4e6955 100644 +--- a/Doc/whatsnew/3.9.rst ++++ b/Doc/whatsnew/3.9.rst +@@ -1625,3 +1625,15 @@ ipaddress + + * Fixed ``is_global`` and ``is_private`` behavior in ``IPv4Address``, + ``IPv6Address``, ``IPv4Network`` and ``IPv6Network``. ++ ++email ++----- ++ ++* Headers with embedded newlines are now quoted on output. ++ ++ The :mod:`~email.generator` will now refuse to serialize (write) headers ++ that are improperly folded or delimited, such that they would be parsed as ++ multiple headers or joined with adjacent data. ++ If you need to turn this safety feature off, ++ set :attr:`~email.policy.Policy.verify_generated_headers`. ++ (Contributed by Bas Bloemsaat and Petr Viktorin in :gh:`121650`.) +diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py +index 8a8fb8bc42..e394cfd2e1 100644 +--- a/Lib/email/_header_value_parser.py ++++ b/Lib/email/_header_value_parser.py +@@ -92,6 +92,8 @@ TOKEN_ENDS = TSPECIALS | WSP + ASPECIALS = TSPECIALS | set("*'%") + ATTRIBUTE_ENDS = ASPECIALS | WSP + EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%') ++NLSET = {'\n', '\r'} ++SPECIALSNL = SPECIALS | NLSET + + def quote_string(value): + return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"' +@@ -2778,9 +2780,13 @@ def _refold_parse_tree(parse_tree, *, policy): + wrap_as_ew_blocked -= 1 + continue + tstr = str(part) +- if part.token_type == 'ptext' and set(tstr) & SPECIALS: +- # Encode if tstr contains special characters. +- want_encoding = True ++ if not want_encoding: ++ if part.token_type == 'ptext': ++ # Encode if tstr contains special characters. ++ want_encoding = not SPECIALSNL.isdisjoint(tstr) ++ else: ++ # Encode if tstr contains newlines. ++ want_encoding = not NLSET.isdisjoint(tstr) + try: + tstr.encode(encoding) + charset = encoding +diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py +index c9cbadd2a8..d1f48211f9 100644 +--- a/Lib/email/_policybase.py ++++ b/Lib/email/_policybase.py +@@ -157,6 +157,13 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta): + message_factory -- the class to use to create new message objects. + If the value is None, the default is Message. + ++ verify_generated_headers ++ -- if true, the generator verifies that each header ++ they are properly folded, so that a parser won't ++ treat it as multiple headers, start-of-body, or ++ part of another header. ++ This is a check against custom Header & fold() ++ implementations. + """ + + raise_on_defect = False +@@ -165,6 +172,7 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta): + max_line_length = 78 + mangle_from_ = False + message_factory = None ++ verify_generated_headers = True + + def handle_defect(self, obj, defect): + """Based on policy, either raise defect or call register_defect. +diff --git a/Lib/email/errors.py b/Lib/email/errors.py +index d28a680010..1a0d5c63e6 100644 +--- a/Lib/email/errors.py ++++ b/Lib/email/errors.py +@@ -29,6 +29,10 @@ class CharsetError(MessageError): + """An illegal charset was given.""" + + ++class HeaderWriteError(MessageError): ++ """Error while writing headers.""" ++ ++ + # These are parsing defects which the parser was able to work around. + class MessageDefect(ValueError): + """Base class for a message defect.""" +diff --git a/Lib/email/generator.py b/Lib/email/generator.py +index c9b121624e..89224ae41c 100644 +--- a/Lib/email/generator.py ++++ b/Lib/email/generator.py +@@ -14,12 +14,14 @@ import random + from copy import deepcopy + from io import StringIO, BytesIO + from email.utils import _has_surrogates ++from email.errors import HeaderWriteError + + UNDERSCORE = '_' + NL = '\n' # XXX: no longer used by the code below. + + NLCRE = re.compile(r'\r\n|\r|\n') + fcre = re.compile(r'^From ', re.MULTILINE) ++NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]') + + + +@@ -223,7 +225,16 @@ class Generator: + + def _write_headers(self, msg): + for h, v in msg.raw_items(): +- self.write(self.policy.fold(h, v)) ++ folded = self.policy.fold(h, v) ++ if self.policy.verify_generated_headers: ++ linesep = self.policy.linesep ++ if not folded.endswith(self.policy.linesep): ++ raise HeaderWriteError( ++ f'folded header does not end with {linesep!r}: {folded!r}') ++ if NEWLINE_WITHOUT_FWSP.search(folded.removesuffix(linesep)): ++ raise HeaderWriteError( ++ f'folded header contains newline: {folded!r}') ++ self.write(folded) + # A blank line always separates headers from body + self.write(self._NL) + +diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py +index 89e7edeb63..d29400f0ed 100644 +--- a/Lib/test/test_email/test_generator.py ++++ b/Lib/test/test_email/test_generator.py +@@ -6,6 +6,7 @@ from email.message import EmailMessage + from email.generator import Generator, BytesGenerator + from email.headerregistry import Address + from email import policy ++import email.errors + from test.test_email import TestEmailBase, parameterize + + +@@ -216,6 +217,44 @@ class TestGeneratorBase: + g.flatten(msg) + self.assertEqual(s.getvalue(), self.typ(expected)) + ++ def test_keep_encoded_newlines(self): ++ msg = self.msgmaker(self.typ(textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com ++ ++ None ++ """))) ++ expected = textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com ++ ++ None ++ """) ++ s = self.ioclass() ++ g = self.genclass(s, policy=self.policy.clone(max_line_length=80)) ++ g.flatten(msg) ++ self.assertEqual(s.getvalue(), self.typ(expected)) ++ ++ def test_keep_long_encoded_newlines(self): ++ msg = self.msgmaker(self.typ(textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com ++ ++ None ++ """))) ++ expected = textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject ++ =?utf-8?q?=0A?=Bcc: ++ injection@example.com ++ ++ None ++ """) ++ s = self.ioclass() ++ g = self.genclass(s, policy=self.policy.clone(max_line_length=30)) ++ g.flatten(msg) ++ self.assertEqual(s.getvalue(), self.typ(expected)) ++ + + class TestGenerator(TestGeneratorBase, TestEmailBase): + +@@ -224,6 +263,29 @@ class TestGenerator(TestGeneratorBase, TestEmailBase): + ioclass = io.StringIO + typ = str + ++ def test_verify_generated_headers(self): ++ """gh-121650: by default the generator prevents header injection""" ++ class LiteralHeader(str): ++ name = 'Header' ++ def fold(self, **kwargs): ++ return self ++ ++ for text in ( ++ 'Value\r\nBad Injection\r\n', ++ 'NoNewLine' ++ ): ++ with self.subTest(text=text): ++ message = message_from_string( ++ "Header: Value\r\n\r\nBody", ++ policy=self.policy, ++ ) ++ ++ del message['Header'] ++ message['Header'] = LiteralHeader(text) ++ ++ with self.assertRaises(email.errors.HeaderWriteError): ++ message.as_string() ++ + + class TestBytesGenerator(TestGeneratorBase, TestEmailBase): + +diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py +index e87c275549..ff1ddf7d7a 100644 +--- a/Lib/test/test_email/test_policy.py ++++ b/Lib/test/test_email/test_policy.py +@@ -26,6 +26,7 @@ class PolicyAPITests(unittest.TestCase): + 'raise_on_defect': False, + 'mangle_from_': True, + 'message_factory': None, ++ 'verify_generated_headers': True, + } + # These default values are the ones set on email.policy.default. + # If any of these defaults change, the docs must be updated. +@@ -277,6 +278,31 @@ class PolicyAPITests(unittest.TestCase): + with self.assertRaises(email.errors.HeaderParseError): + policy.fold("Subject", subject) + ++ def test_verify_generated_headers(self): ++ """Turning protection off allows header injection""" ++ policy = email.policy.default.clone(verify_generated_headers=False) ++ for text in ( ++ 'Header: Value\r\nBad: Injection\r\n', ++ 'Header: NoNewLine' ++ ): ++ with self.subTest(text=text): ++ message = email.message_from_string( ++ "Header: Value\r\n\r\nBody", ++ policy=policy, ++ ) ++ class LiteralHeader(str): ++ name = 'Header' ++ def fold(self, **kwargs): ++ return self ++ ++ del message['Header'] ++ message['Header'] = LiteralHeader(text) ++ ++ self.assertEqual( ++ message.as_string(), ++ f"{text}\nBody", ++ ) ++ + # XXX: Need subclassing tests. + # For adding subclassed objects, make sure the usual rules apply (subclass + # wins), but that the order still works (right overrides left). +diff --git a/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst b/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst +new file mode 100644 +index 0000000000..83dd28d4ac +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst +@@ -0,0 +1,5 @@ ++:mod:`email` headers with embedded newlines are now quoted on output. The ++:mod:`~email.generator` will now refuse to serialize (write) headers that ++are unsafely folded or delimited; see ++:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas ++Bloemsaat and Petr Viktorin in :gh:`121650`.) diff --git a/python3.9.spec b/python3.9.spec index c924e0f..1eafbbf 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -430,6 +430,25 @@ Patch419: 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with- # --------- Patch431: 00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch +# 00435 # f2924d30f4dd44804219c10410a57dd96764d297 +# gh-121650: Encode newlines in headers, and verify headers are sound (GH-122233) +# +# Per RFC 2047: +# +# > [...] these encoding schemes allow the +# > encoding of arbitrary octet values, mail readers that implement this +# > decoding should also ensure that display of the decoded data on the +# > recipient's terminal will not cause unwanted side-effects +# +# It seems that the "quoted-word" scheme is a valid way to include +# a newline character in a header value, just like we already allow +# undecodable bytes or control characters. +# They do need to be properly quoted when serialized to text, though. +# +# This should fail for custom fold() implementations that aren't careful +# about newlines. +Patch435: 00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1874,6 +1893,7 @@ CheckPython optimized %changelog * Tue Aug 13 2024 Lumír Balhar - 3.9.19-5 - Security fix for CVE-2024-4032 (rhbz#2293397) +- Security fix for CVE-2024-6923 (rhbz#2303164) * Tue Jul 23 2024 Lumír Balhar - 3.9.19-4 - Require systemtap-sdt-devel for sys/sdt.h From 931a09385d133ab84aab10a695c13629257f12a0 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Fri, 23 Aug 2024 15:17:50 +0200 Subject: [PATCH 67/89] Security fix for CVE-2024-8088 Fixes: rhbz#2307466 --- ...22905-sanitize-names-in-zipfile-path.patch | 128 ++++++++++++++++++ python3.9.spec | 10 +- 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch diff --git a/00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch b/00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch new file mode 100644 index 0000000..fed0497 --- /dev/null +++ b/00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch @@ -0,0 +1,128 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Jason R. Coombs" +Date: Mon, 19 Aug 2024 19:28:20 -0400 +Subject: [PATCH] 00436: [CVE-2024-8088] gh-122905: Sanitize names in + zipfile.Path. + +Co-authored-by: Jason R. Coombs +--- + Lib/test/test_zipfile.py | 17 ++++++ + Lib/zipfile.py | 61 ++++++++++++++++++- + ...-08-11-14-08-04.gh-issue-122905.7tDsxA.rst | 1 + + 3 files changed, 78 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst + +diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py +index 17e95eb862..9a72152357 100644 +--- a/Lib/test/test_zipfile.py ++++ b/Lib/test/test_zipfile.py +@@ -3054,6 +3054,23 @@ class TestPath(unittest.TestCase): + data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)] + zipfile.CompleteDirs._implied_dirs(data) + ++ def test_malformed_paths(self): ++ """ ++ Path should handle malformed paths. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr("/one-slash.txt", b"content") ++ zf.writestr("//two-slash.txt", b"content") ++ zf.writestr("../parent.txt", b"content") ++ zf.filename = '' ++ root = zipfile.Path(zf) ++ assert list(map(str, root.iterdir())) == [ ++ 'one-slash.txt', ++ 'two-slash.txt', ++ 'parent.txt', ++ ] ++ + + if __name__ == "__main__": + unittest.main() +diff --git a/Lib/zipfile.py b/Lib/zipfile.py +index 95f95ee112..2e9b2868cd 100644 +--- a/Lib/zipfile.py ++++ b/Lib/zipfile.py +@@ -9,6 +9,7 @@ import io + import itertools + import os + import posixpath ++import re + import shutil + import stat + import struct +@@ -2177,7 +2178,65 @@ def _difference(minuend, subtrahend): + return itertools.filterfalse(set(subtrahend).__contains__, minuend) + + +-class CompleteDirs(ZipFile): ++class SanitizedNames: ++ """ ++ ZipFile mix-in to ensure names are sanitized. ++ """ ++ ++ def namelist(self): ++ return list(map(self._sanitize, super().namelist())) ++ ++ @staticmethod ++ def _sanitize(name): ++ r""" ++ Ensure a relative path with posix separators and no dot names. ++ Modeled after ++ https://github.com/python/cpython/blob/bcc1be39cb1d04ad9fc0bd1b9193d3972835a57c/Lib/zipfile/__init__.py#L1799-L1813 ++ but provides consistent cross-platform behavior. ++ >>> san = SanitizedNames._sanitize ++ >>> san('/foo/bar') ++ 'foo/bar' ++ >>> san('//foo.txt') ++ 'foo.txt' ++ >>> san('foo/.././bar.txt') ++ 'foo/bar.txt' ++ >>> san('foo../.bar.txt') ++ 'foo../.bar.txt' ++ >>> san('\\foo\\bar.txt') ++ 'foo/bar.txt' ++ >>> san('D:\\foo.txt') ++ 'D/foo.txt' ++ >>> san('\\\\server\\share\\file.txt') ++ 'server/share/file.txt' ++ >>> san('\\\\?\\GLOBALROOT\\Volume3') ++ '?/GLOBALROOT/Volume3' ++ >>> san('\\\\.\\PhysicalDrive1\\root') ++ 'PhysicalDrive1/root' ++ Retain any trailing slash. ++ >>> san('abc/') ++ 'abc/' ++ Raises a ValueError if the result is empty. ++ >>> san('../..') ++ Traceback (most recent call last): ++ ... ++ ValueError: Empty filename ++ """ ++ ++ def allowed(part): ++ return part and part not in {'..', '.'} ++ ++ # Remove the drive letter. ++ # Don't use ntpath.splitdrive, because that also strips UNC paths ++ bare = re.sub('^([A-Z]):', r'\1', name, flags=re.IGNORECASE) ++ clean = bare.replace('\\', '/') ++ parts = clean.split('/') ++ joined = '/'.join(filter(allowed, parts)) ++ if not joined: ++ raise ValueError("Empty filename") ++ return joined + '/' * name.endswith('/') ++ ++ ++class CompleteDirs(SanitizedNames, ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. +diff --git a/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst b/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst +new file mode 100644 +index 0000000000..1be44c906c +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst +@@ -0,0 +1 @@ ++:class:`zipfile.Path` objects now sanitize names from the zipfile. diff --git a/python3.9.spec b/python3.9.spec index 1eafbbf..fd40aa3 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 5%{?dist} +Release: 6%{?dist} License: Python @@ -449,6 +449,10 @@ Patch431: 00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-1 # about newlines. Patch435: 00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch +# 00436 # 506dd77b7132f69ada7185b8bb91eba0e1296aa8 +# [CVE-2024-8088] gh-122905: Sanitize names in zipfile.Path. +Patch436: 00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1891,6 +1895,10 @@ CheckPython optimized # ====================================================== %changelog +* Fri Aug 23 2024 Charalampos Stratakis - 3.9.19-6 +- Security fix for CVE-2024-8088 +- Fixes: rhbz#2307466 + * Tue Aug 13 2024 Lumír Balhar - 3.9.19-5 - Security fix for CVE-2024-4032 (rhbz#2293397) - Security fix for CVE-2024-6923 (rhbz#2303164) From 1f0b956059eb691cc74424c772483f4899c069d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 27 Aug 2024 13:36:46 +0000 Subject: [PATCH 68/89] Skip test_sendfile_close_peer_in_the_middle_of_receiving on ppc64le Reported upstream https://github.com/python/cpython/issues/123384 Which was a duplicate of https://github.com/python/cpython/issues/120226 The test is fixed on the main branch, but skipping is easier than backporting. The failure occurs with Kernel 6.10.x even when Python is built with an older Kernel. By skipping the tests, we can ship a CVE fix. --- python3.9.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python3.9.spec b/python3.9.spec index fd40aa3..6cc8bc9 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -1352,6 +1352,8 @@ CheckPython() { # package: rpmbuild requires /usr/bin/pythonX.Y to be installed # test_gdb on arm on Fedora 33: # https://bugzilla.redhat.com/show_bug.cgi?id=1846390 + # test_sendfile_close_peer_in_the_middle_of_receiving: + # https://github.com/python/cpython/issues/120226 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest -j0 --timeout=1800 \ %if %{with bootstrap} @@ -1365,6 +1367,9 @@ CheckPython() { -x test_gdb \ %endif %endif + %ifarch ppc64le + -i test_sendfile_close_peer_in_the_middle_of_receiving \ + %endif echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName From 994b826cd1598d8927917dbf51d3d1834a111315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 11 Sep 2024 20:15:48 +0200 Subject: [PATCH 69/89] Update to 3.9.20 --- ...-addresses-in-email-parseaddr-111116.patch | 500 ------------------ ...h-non-int-suffix-gh-112771-gh-112774.patch | 66 --- ...113179-gh-113186-gh-118177-gh-118472.patch | 399 -------------- ...d-verify-headers-are-sound-gh-122233.patch | 356 ------------- ...22905-sanitize-names-in-zipfile-path.patch | 128 ----- python3.9.spec | 75 +-- sources | 4 +- 7 files changed, 7 insertions(+), 1521 deletions(-) delete mode 100644 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch delete mode 100644 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch delete mode 100644 00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch delete mode 100644 00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch delete mode 100644 00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch diff --git a/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch b/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch deleted file mode 100644 index af44881..0000000 --- a/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch +++ /dev/null @@ -1,500 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Victor Stinner -Date: Fri, 15 Dec 2023 16:10:40 +0100 -Subject: [PATCH] 00415: [CVE-2023-27043] gh-102988: Reject malformed addresses - in email.parseaddr() (#111116) - -Detect email address parsing errors and return empty tuple to -indicate the parsing error (old API). Add an optional 'strict' -parameter to getaddresses() and parseaddr() functions. Patch by -Thomas Dwyer. - -Co-Authored-By: Thomas Dwyer ---- - Doc/library/email.utils.rst | 19 +- - Lib/email/utils.py | 151 ++++++++++++- - Lib/test/test_email/test_email.py | 204 +++++++++++++++++- - ...-10-20-15-28-08.gh-issue-102988.dStNO7.rst | 8 + - 4 files changed, 361 insertions(+), 21 deletions(-) - create mode 100644 Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst - -diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst -index 4d0e920eb0..104229e9e5 100644 ---- a/Doc/library/email.utils.rst -+++ b/Doc/library/email.utils.rst -@@ -60,13 +60,18 @@ of the new API. - begins with angle brackets, they are stripped off. - - --.. function:: parseaddr(address) -+.. function:: parseaddr(address, *, strict=True) - - Parse address -- which should be the value of some address-containing field such - as :mailheader:`To` or :mailheader:`Cc` -- into its constituent *realname* and - *email address* parts. Returns a tuple of that information, unless the parse - fails, in which case a 2-tuple of ``('', '')`` is returned. - -+ If *strict* is true, use a strict parser which rejects malformed inputs. -+ -+ .. versionchanged:: 3.13 -+ Add *strict* optional parameter and reject malformed inputs by default. -+ - - .. function:: formataddr(pair, charset='utf-8') - -@@ -84,12 +89,15 @@ of the new API. - Added the *charset* option. - - --.. function:: getaddresses(fieldvalues) -+.. function:: getaddresses(fieldvalues, *, strict=True) - - This method returns a list of 2-tuples of the form returned by ``parseaddr()``. - *fieldvalues* is a sequence of header field values as might be returned by -- :meth:`Message.get_all `. Here's a simple -- example that gets all the recipients of a message:: -+ :meth:`Message.get_all `. -+ -+ If *strict* is true, use a strict parser which rejects malformed inputs. -+ -+ Here's a simple example that gets all the recipients of a message:: - - from email.utils import getaddresses - -@@ -99,6 +107,9 @@ of the new API. - resent_ccs = msg.get_all('resent-cc', []) - all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) - -+ .. versionchanged:: 3.13 -+ Add *strict* optional parameter and reject malformed inputs by default. -+ - - .. function:: parsedate(date) - -diff --git a/Lib/email/utils.py b/Lib/email/utils.py -index 48d30160aa..7ca7a7c886 100644 ---- a/Lib/email/utils.py -+++ b/Lib/email/utils.py -@@ -48,6 +48,7 @@ TICK = "'" - specialsre = re.compile(r'[][\\()<>@,:;".]') - escapesre = re.compile(r'[\\"]') - -+ - def _has_surrogates(s): - """Return True if s contains surrogate-escaped binary data.""" - # This check is based on the fact that unless there are surrogates, utf8 -@@ -106,12 +107,127 @@ def formataddr(pair, charset='utf-8'): - return address - - -+def _iter_escaped_chars(addr): -+ pos = 0 -+ escape = False -+ for pos, ch in enumerate(addr): -+ if escape: -+ yield (pos, '\\' + ch) -+ escape = False -+ elif ch == '\\': -+ escape = True -+ else: -+ yield (pos, ch) -+ if escape: -+ yield (pos, '\\') - --def getaddresses(fieldvalues): -- """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" -- all = COMMASPACE.join(str(v) for v in fieldvalues) -- a = _AddressList(all) -- return a.addresslist -+ -+def _strip_quoted_realnames(addr): -+ """Strip real names between quotes.""" -+ if '"' not in addr: -+ # Fast path -+ return addr -+ -+ start = 0 -+ open_pos = None -+ result = [] -+ for pos, ch in _iter_escaped_chars(addr): -+ if ch == '"': -+ if open_pos is None: -+ open_pos = pos -+ else: -+ if start != open_pos: -+ result.append(addr[start:open_pos]) -+ start = pos + 1 -+ open_pos = None -+ -+ if start < len(addr): -+ result.append(addr[start:]) -+ -+ return ''.join(result) -+ -+ -+supports_strict_parsing = True -+ -+def getaddresses(fieldvalues, *, strict=True): -+ """Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue. -+ -+ When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in -+ its place. -+ -+ If strict is true, use a strict parser which rejects malformed inputs. -+ """ -+ -+ # If strict is true, if the resulting list of parsed addresses is greater -+ # than the number of fieldvalues in the input list, a parsing error has -+ # occurred and consequently a list containing a single empty 2-tuple [('', -+ # '')] is returned in its place. This is done to avoid invalid output. -+ # -+ # Malformed input: getaddresses(['alice@example.com ']) -+ # Invalid output: [('', 'alice@example.com'), ('', 'bob@example.com')] -+ # Safe output: [('', '')] -+ -+ if not strict: -+ all = COMMASPACE.join(str(v) for v in fieldvalues) -+ a = _AddressList(all) -+ return a.addresslist -+ -+ fieldvalues = [str(v) for v in fieldvalues] -+ fieldvalues = _pre_parse_validation(fieldvalues) -+ addr = COMMASPACE.join(fieldvalues) -+ a = _AddressList(addr) -+ result = _post_parse_validation(a.addresslist) -+ -+ # Treat output as invalid if the number of addresses is not equal to the -+ # expected number of addresses. -+ n = 0 -+ for v in fieldvalues: -+ # When a comma is used in the Real Name part it is not a deliminator. -+ # So strip those out before counting the commas. -+ v = _strip_quoted_realnames(v) -+ # Expected number of addresses: 1 + number of commas -+ n += 1 + v.count(',') -+ if len(result) != n: -+ return [('', '')] -+ -+ return result -+ -+ -+def _check_parenthesis(addr): -+ # Ignore parenthesis in quoted real names. -+ addr = _strip_quoted_realnames(addr) -+ -+ opens = 0 -+ for pos, ch in _iter_escaped_chars(addr): -+ if ch == '(': -+ opens += 1 -+ elif ch == ')': -+ opens -= 1 -+ if opens < 0: -+ return False -+ return (opens == 0) -+ -+ -+def _pre_parse_validation(email_header_fields): -+ accepted_values = [] -+ for v in email_header_fields: -+ if not _check_parenthesis(v): -+ v = "('', '')" -+ accepted_values.append(v) -+ -+ return accepted_values -+ -+ -+def _post_parse_validation(parsed_email_header_tuples): -+ accepted_values = [] -+ # The parser would have parsed a correctly formatted domain-literal -+ # The existence of an [ after parsing indicates a parsing failure -+ for v in parsed_email_header_tuples: -+ if '[' in v[1]: -+ v = ('', '') -+ accepted_values.append(v) -+ -+ return accepted_values - - - def _format_timetuple_and_zone(timetuple, zone): -@@ -202,16 +318,33 @@ def parsedate_to_datetime(data): - tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) - - --def parseaddr(addr): -+def parseaddr(addr, *, strict=True): - """ - Parse addr into its constituent realname and email address parts. - - Return a tuple of realname and email address, unless the parse fails, in - which case return a 2-tuple of ('', ''). -+ -+ If strict is True, use a strict parser which rejects malformed inputs. - """ -- addrs = _AddressList(addr).addresslist -- if not addrs: -- return '', '' -+ if not strict: -+ addrs = _AddressList(addr).addresslist -+ if not addrs: -+ return ('', '') -+ return addrs[0] -+ -+ if isinstance(addr, list): -+ addr = addr[0] -+ -+ if not isinstance(addr, str): -+ return ('', '') -+ -+ addr = _pre_parse_validation([addr])[0] -+ addrs = _post_parse_validation(_AddressList(addr).addresslist) -+ -+ if not addrs or len(addrs) > 1: -+ return ('', '') -+ - return addrs[0] - - -diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py -index 761ea90b78..0c689643de 100644 ---- a/Lib/test/test_email/test_email.py -+++ b/Lib/test/test_email/test_email.py -@@ -16,6 +16,7 @@ from unittest.mock import patch - - import email - import email.policy -+import email.utils - - from email.charset import Charset - from email.header import Header, decode_header, make_header -@@ -3263,15 +3264,154 @@ Foo - [('Al Person', 'aperson@dom.ain'), - ('Bud Person', 'bperson@dom.ain')]) - -+ def test_getaddresses_comma_in_name(self): -+ """GH-106669 regression test.""" -+ self.assertEqual( -+ utils.getaddresses( -+ [ -+ '"Bud, Person" ', -+ 'aperson@dom.ain (Al Person)', -+ '"Mariusz Felisiak" ', -+ ] -+ ), -+ [ -+ ('Bud, Person', 'bperson@dom.ain'), -+ ('Al Person', 'aperson@dom.ain'), -+ ('Mariusz Felisiak', 'to@example.com'), -+ ], -+ ) -+ -+ def test_parsing_errors(self): -+ """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" -+ alice = 'alice@example.org' -+ bob = 'bob@example.com' -+ empty = ('', '') -+ -+ # Test utils.getaddresses() and utils.parseaddr() on malformed email -+ # addresses: default behavior (strict=True) rejects malformed address, -+ # and strict=False which tolerates malformed address. -+ for invalid_separator, expected_non_strict in ( -+ ('(', [(f'<{bob}>', alice)]), -+ (')', [('', alice), empty, ('', bob)]), -+ ('<', [('', alice), empty, ('', bob), empty]), -+ ('>', [('', alice), empty, ('', bob)]), -+ ('[', [('', f'{alice}[<{bob}>]')]), -+ (']', [('', alice), empty, ('', bob)]), -+ ('@', [empty, empty, ('', bob)]), -+ (';', [('', alice), empty, ('', bob)]), -+ (':', [('', alice), ('', bob)]), -+ ('.', [('', alice + '.'), ('', bob)]), -+ ('"', [('', alice), ('', f'<{bob}>')]), -+ ): -+ address = f'{alice}{invalid_separator}<{bob}>' -+ with self.subTest(address=address): -+ self.assertEqual(utils.getaddresses([address]), -+ [empty]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ expected_non_strict) -+ -+ self.assertEqual(utils.parseaddr([address]), -+ empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Comma (',') is treated differently depending on strict parameter. -+ # Comma without quotes. -+ address = f'{alice},<{bob}>' -+ self.assertEqual(utils.getaddresses([address]), -+ [('', alice), ('', bob)]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ [('', alice), ('', bob)]) -+ self.assertEqual(utils.parseaddr([address]), -+ empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Real name between quotes containing comma. -+ address = '"Alice, alice@example.org" ' -+ expected_strict = ('Alice, alice@example.org', 'bob@example.com') -+ self.assertEqual(utils.getaddresses([address]), [expected_strict]) -+ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) -+ self.assertEqual(utils.parseaddr([address]), expected_strict) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Valid parenthesis in comments. -+ address = 'alice@example.org (Alice)' -+ expected_strict = ('Alice', 'alice@example.org') -+ self.assertEqual(utils.getaddresses([address]), [expected_strict]) -+ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) -+ self.assertEqual(utils.parseaddr([address]), expected_strict) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Invalid parenthesis in comments. -+ address = 'alice@example.org )Alice(' -+ self.assertEqual(utils.getaddresses([address]), [empty]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ [('', 'alice@example.org'), ('', ''), ('', 'Alice')]) -+ self.assertEqual(utils.parseaddr([address]), empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Two addresses with quotes separated by comma. -+ address = '"Jane Doe" , "John Doe" ' -+ self.assertEqual(utils.getaddresses([address]), -+ [('Jane Doe', 'jane@example.net'), -+ ('John Doe', 'john@example.net')]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ [('Jane Doe', 'jane@example.net'), -+ ('John Doe', 'john@example.net')]) -+ self.assertEqual(utils.parseaddr([address]), empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Test email.utils.supports_strict_parsing attribute -+ self.assertEqual(email.utils.supports_strict_parsing, True) -+ - def test_getaddresses_nasty(self): -- eq = self.assertEqual -- eq(utils.getaddresses(['foo: ;']), [('', '')]) -- eq(utils.getaddresses( -- ['[]*-- =~$']), -- [('', ''), ('', ''), ('', '*--')]) -- eq(utils.getaddresses( -- ['foo: ;', '"Jason R. Mastaler" ']), -- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) -+ for addresses, expected in ( -+ (['"Sürname, Firstname" '], -+ [('Sürname, Firstname', 'to@example.com')]), -+ -+ (['foo: ;'], -+ [('', '')]), -+ -+ (['foo: ;', '"Jason R. Mastaler" '], -+ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), -+ -+ ([r'Pete(A nice \) chap) '], -+ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), -+ -+ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], -+ [('', '')]), -+ -+ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], -+ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), -+ -+ (['John Doe '], -+ [('John Doe (comment)', 'jdoe@machine.example')]), -+ -+ (['"Mary Smith: Personal Account" '], -+ [('Mary Smith: Personal Account', 'smith@home.example')]), -+ -+ (['Undisclosed recipients:;'], -+ [('', '')]), -+ -+ ([r', "Giant; \"Big\" Box" '], -+ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), -+ ): -+ with self.subTest(addresses=addresses): -+ self.assertEqual(utils.getaddresses(addresses), -+ expected) -+ self.assertEqual(utils.getaddresses(addresses, strict=False), -+ expected) -+ -+ addresses = ['[]*-- =~$'] -+ self.assertEqual(utils.getaddresses(addresses), -+ [('', '')]) -+ self.assertEqual(utils.getaddresses(addresses, strict=False), -+ [('', ''), ('', ''), ('', '*--')]) - - def test_getaddresses_embedded_comment(self): - """Test proper handling of a nested comment""" -@@ -3460,6 +3600,54 @@ multipart/report - m = cls(*constructor, policy=email.policy.default) - self.assertIs(m.policy, email.policy.default) - -+ def test_iter_escaped_chars(self): -+ self.assertEqual(list(utils._iter_escaped_chars(r'a\\b\"c\\"d')), -+ [(0, 'a'), -+ (2, '\\\\'), -+ (3, 'b'), -+ (5, '\\"'), -+ (6, 'c'), -+ (8, '\\\\'), -+ (9, '"'), -+ (10, 'd')]) -+ self.assertEqual(list(utils._iter_escaped_chars('a\\')), -+ [(0, 'a'), (1, '\\')]) -+ -+ def test_strip_quoted_realnames(self): -+ def check(addr, expected): -+ self.assertEqual(utils._strip_quoted_realnames(addr), expected) -+ -+ check('"Jane Doe" , "John Doe" ', -+ ' , ') -+ check(r'"Jane \"Doe\"." ', -+ ' ') -+ -+ # special cases -+ check(r'before"name"after', 'beforeafter') -+ check(r'before"name"', 'before') -+ check(r'b"name"', 'b') # single char -+ check(r'"name"after', 'after') -+ check(r'"name"a', 'a') # single char -+ check(r'"name"', '') -+ -+ # no change -+ for addr in ( -+ 'Jane Doe , John Doe ', -+ 'lone " quote', -+ ): -+ self.assertEqual(utils._strip_quoted_realnames(addr), addr) -+ -+ -+ def test_check_parenthesis(self): -+ addr = 'alice@example.net' -+ self.assertTrue(utils._check_parenthesis(f'{addr} (Alice)')) -+ self.assertFalse(utils._check_parenthesis(f'{addr} )Alice(')) -+ self.assertFalse(utils._check_parenthesis(f'{addr} (Alice))')) -+ self.assertFalse(utils._check_parenthesis(f'{addr} ((Alice)')) -+ -+ # Ignore real name between quotes -+ self.assertTrue(utils._check_parenthesis(f'")Alice((" {addr}')) -+ - - # Test the iterator/generators - class TestIterators(TestEmailBase): -diff --git a/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst -new file mode 100644 -index 0000000000..3d0e9e4078 ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst -@@ -0,0 +1,8 @@ -+:func:`email.utils.getaddresses` and :func:`email.utils.parseaddr` now -+return ``('', '')`` 2-tuples in more situations where invalid email -+addresses are encountered instead of potentially inaccurate values. Add -+optional *strict* parameter to these two functions: use ``strict=False`` to -+get the old behavior, accept malformed inputs. -+``getattr(email.utils, 'supports_strict_parsing', False)`` can be use to check -+if the *strict* paramater is available. Patch by Thomas Dwyer and Victor -+Stinner to improve the CVE-2023-27043 fix. diff --git a/00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch b/00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch deleted file mode 100644 index ce6c9f4..0000000 --- a/00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Tue, 5 Dec 2023 21:02:06 +0100 -Subject: [PATCH] 00419: gh-112769: test_zlib: Fix comparison of - ZLIB_RUNTIME_VERSION with non-int suffix (GH-112771) (GH-112774) - -zlib-ng defines the version as "1.3.0.zlib-ng". -(cherry picked from commit d384813ff18b33280a90b6d2011654528a2b6ad1) ---- - Lib/test/test_zlib.py | 28 ++++++++++++++++------------ - 1 file changed, 16 insertions(+), 12 deletions(-) - -diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py -index 02509cdf55..2a9e7e5ed3 100644 ---- a/Lib/test/test_zlib.py -+++ b/Lib/test/test_zlib.py -@@ -17,6 +17,20 @@ requires_Decompress_copy = unittest.skipUnless( - 'requires Decompress.copy()') - - -+def _zlib_runtime_version_tuple(zlib_version=zlib.ZLIB_RUNTIME_VERSION): -+ # Register "1.2.3" as "1.2.3.0" -+ # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux" -+ v = zlib_version.split('-', 1)[0].split('.') -+ if len(v) < 4: -+ v.append('0') -+ elif not v[-1].isnumeric(): -+ v[-1] = '0' -+ return tuple(map(int, v)) -+ -+ -+ZLIB_RUNTIME_VERSION_TUPLE = _zlib_runtime_version_tuple() -+ -+ - class VersionTestCase(unittest.TestCase): - - def test_library_version(self): -@@ -437,9 +451,8 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): - sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH', - 'Z_PARTIAL_FLUSH'] - -- ver = tuple(int(v) for v in zlib.ZLIB_RUNTIME_VERSION.split('.')) - # Z_BLOCK has a known failure prior to 1.2.5.3 -- if ver >= (1, 2, 5, 3): -+ if ZLIB_RUNTIME_VERSION_TUPLE >= (1, 2, 5, 3): - sync_opt.append('Z_BLOCK') - - sync_opt = [getattr(zlib, opt) for opt in sync_opt -@@ -768,16 +781,7 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): - - def test_wbits(self): - # wbits=0 only supported since zlib v1.2.3.5 -- # Register "1.2.3" as "1.2.3.0" -- # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux" -- v = zlib.ZLIB_RUNTIME_VERSION.split('-', 1)[0].split('.') -- if len(v) < 4: -- v.append('0') -- elif not v[-1].isnumeric(): -- v[-1] = '0' -- -- v = tuple(map(int, v)) -- supports_wbits_0 = v >= (1, 2, 3, 5) -+ supports_wbits_0 = ZLIB_RUNTIME_VERSION_TUPLE >= (1, 2, 3, 5) - - co = zlib.compressobj(level=1, wbits=15) - zlib15 = co.compress(HAMLET_SCENE) + co.flush() diff --git a/00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch b/00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch deleted file mode 100644 index 1f3563b..0000000 --- a/00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Petr Viktorin -Date: Tue, 7 May 2024 11:57:58 +0200 -Subject: [PATCH] 00431: gh-113171: gh-65056: Fix "private" (non-global) IP - address ranges (GH-113179) (GH-113186) (GH-118177) (GH-118472) - -The _private_networks variables, used by various is_private -implementations, were missing some ranges and at the same time had -overly strict ranges (where there are more specific ranges considered -globally reachable by the IANA registries). - -This patch updates the ranges with what was missing or otherwise -incorrect. - -100.64.0.0/10 is left alone, for now, as it's been made special in [1]. - -The _address_exclude_many() call returns 8 networks for IPv4, 121 -networks for IPv6. - -[1] https://github.com/python/cpython/issues/61602 - -In 3.10 and below, is_private checks whether the network and broadcast -address are both private. -In later versions (where the test wss backported from), it checks -whether they both are in the same private network. - -For 0.0.0.0/0, both 0.0.0.0 and 255.225.255.255 are private, -but one is in 0.0.0.0/8 ("This network") and the other in -255.255.255.255/32 ("Limited broadcast"). - ---------- - -Co-authored-by: Jakub Stasiak ---- - Doc/library/ipaddress.rst | 43 ++++++++- - Doc/tools/susp-ignored.csv | 8 ++ - Doc/whatsnew/3.9.rst | 9 ++ - Lib/ipaddress.py | 95 +++++++++++++++---- - Lib/test/test_ipaddress.py | 52 ++++++++++ - ...-03-14-01-38-44.gh-issue-113171.VFnObz.rst | 9 ++ - 6 files changed, 195 insertions(+), 21 deletions(-) - create mode 100644 Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst - -diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst -index 9c2dff5570..f9c1ebf3f3 100644 ---- a/Doc/library/ipaddress.rst -+++ b/Doc/library/ipaddress.rst -@@ -188,18 +188,53 @@ write code that handles both IP versions correctly. Address objects are - - .. attribute:: is_private - -- ``True`` if the address is allocated for private networks. See -+ ``True`` if the address is defined as not globally reachable by - iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ -- (for IPv6). -+ (for IPv6) with the following exceptions: -+ -+ * ``is_private`` is ``False`` for the shared address space (``100.64.0.0/10``) -+ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the -+ semantics of the underlying IPv4 addresses and the following condition holds -+ (see :attr:`IPv6Address.ipv4_mapped`):: -+ -+ address.is_private == address.ipv4_mapped.is_private -+ -+ ``is_private`` has value opposite to :attr:`is_global`, except for the shared address space -+ (``100.64.0.0/10`` range) where they are both ``False``. -+ -+ .. versionchanged:: 3.9.20 -+ -+ Fixed some false positives and false negatives. -+ -+ * ``192.0.0.0/24`` is considered private with the exception of ``192.0.0.9/32`` and -+ ``192.0.0.10/32`` (previously: only the ``192.0.0.0/29`` sub-range was considered private). -+ * ``64:ff9b:1::/48`` is considered private. -+ * ``2002::/16`` is considered private. -+ * There are exceptions within ``2001::/23`` (otherwise considered private): ``2001:1::1/128``, -+ ``2001:1::2/128``, ``2001:3::/32``, ``2001:4:112::/48``, ``2001:20::/28``, ``2001:30::/28``. -+ The exceptions are not considered private. - - .. attribute:: is_global - -- ``True`` if the address is allocated for public networks. See -+ ``True`` if the address is defined as globally reachable by - iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ -- (for IPv6). -+ (for IPv6) with the following exception: -+ -+ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the -+ semantics of the underlying IPv4 addresses and the following condition holds -+ (see :attr:`IPv6Address.ipv4_mapped`):: -+ -+ address.is_global == address.ipv4_mapped.is_global -+ -+ ``is_global`` has value opposite to :attr:`is_private`, except for the shared address space -+ (``100.64.0.0/10`` range) where they are both ``False``. - - .. versionadded:: 3.4 - -+ .. versionchanged:: 3.9.20 -+ -+ Fixed some false positives and false negatives, see :attr:`is_private` for details. -+ - .. attribute:: is_unspecified - - ``True`` if the address is unspecified. See :RFC:`5735` (for IPv4) -diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv -index 3eb3d7954f..de91a50bad 100644 ---- a/Doc/tools/susp-ignored.csv -+++ b/Doc/tools/susp-ignored.csv -@@ -169,6 +169,14 @@ library/ipaddress,,:db00,2001:db00::0/24 - library/ipaddress,,::,2001:db00::0/24 - library/ipaddress,,:db00,2001:db00::0/ffff:ff00:: - library/ipaddress,,::,2001:db00::0/ffff:ff00:: -+library/ipaddress,,:ff9b,64:ff9b:1::/48 -+library/ipaddress,,::,64:ff9b:1::/48 -+library/ipaddress,,::,2001:: -+library/ipaddress,,::,2001:1:: -+library/ipaddress,,::,2001:3:: -+library/ipaddress,,::,2001:4:112:: -+library/ipaddress,,::,2001:20:: -+library/ipaddress,,::,2001:30:: - library/itertools,,:step,elements from seq[start:stop:step] - library/itertools,,:stop,elements from seq[start:stop:step] - library/itertools,,::,kernel = tuple(kernel)[::-1] -diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst -index 0064e074a3..1756a37338 100644 ---- a/Doc/whatsnew/3.9.rst -+++ b/Doc/whatsnew/3.9.rst -@@ -1616,3 +1616,12 @@ tarfile - :exc:`DeprecationWarning`. - In Python 3.14, the default will switch to ``'data'``. - (Contributed by Petr Viktorin in :pep:`706`.) -+ -+Notable changes in 3.9.20 -+========================= -+ -+ipaddress -+--------- -+ -+* Fixed ``is_global`` and ``is_private`` behavior in ``IPv4Address``, -+ ``IPv6Address``, ``IPv4Network`` and ``IPv6Network``. -diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py -index 25f373a06a..9b35340d9a 100644 ---- a/Lib/ipaddress.py -+++ b/Lib/ipaddress.py -@@ -1322,18 +1322,41 @@ class IPv4Address(_BaseV4, _BaseAddress): - @property - @functools.lru_cache() - def is_private(self): -- """Test if this address is allocated for private networks. -+ """``True`` if the address is defined as not globally reachable by -+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ -+ (for IPv6) with the following exceptions: - -- Returns: -- A boolean, True if the address is reserved per -- iana-ipv4-special-registry. -+ * ``is_private`` is ``False`` for ``100.64.0.0/10`` -+ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the -+ semantics of the underlying IPv4 addresses and the following condition holds -+ (see :attr:`IPv6Address.ipv4_mapped`):: - -+ address.is_private == address.ipv4_mapped.is_private -+ -+ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10`` -+ IPv4 range where they are both ``False``. - """ -- return any(self in net for net in self._constants._private_networks) -+ return ( -+ any(self in net for net in self._constants._private_networks) -+ and all(self not in net for net in self._constants._private_networks_exceptions) -+ ) - - @property - @functools.lru_cache() - def is_global(self): -+ """``True`` if the address is defined as globally reachable by -+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ -+ (for IPv6) with the following exception: -+ -+ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the -+ semantics of the underlying IPv4 addresses and the following condition holds -+ (see :attr:`IPv6Address.ipv4_mapped`):: -+ -+ address.is_global == address.ipv4_mapped.is_global -+ -+ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10`` -+ IPv4 range where they are both ``False``. -+ """ - return self not in self._constants._public_network and not self.is_private - - @property -@@ -1537,13 +1560,15 @@ class _IPv4Constants: - - _public_network = IPv4Network('100.64.0.0/10') - -+ # Not globally reachable address blocks listed on -+ # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml - _private_networks = [ - IPv4Network('0.0.0.0/8'), - IPv4Network('10.0.0.0/8'), - IPv4Network('127.0.0.0/8'), - IPv4Network('169.254.0.0/16'), - IPv4Network('172.16.0.0/12'), -- IPv4Network('192.0.0.0/29'), -+ IPv4Network('192.0.0.0/24'), - IPv4Network('192.0.0.170/31'), - IPv4Network('192.0.2.0/24'), - IPv4Network('192.168.0.0/16'), -@@ -1554,6 +1579,11 @@ class _IPv4Constants: - IPv4Network('255.255.255.255/32'), - ] - -+ _private_networks_exceptions = [ -+ IPv4Network('192.0.0.9/32'), -+ IPv4Network('192.0.0.10/32'), -+ ] -+ - _reserved_network = IPv4Network('240.0.0.0/4') - - _unspecified_address = IPv4Address('0.0.0.0') -@@ -1995,23 +2025,42 @@ class IPv6Address(_BaseV6, _BaseAddress): - @property - @functools.lru_cache() - def is_private(self): -- """Test if this address is allocated for private networks. -+ """``True`` if the address is defined as not globally reachable by -+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ -+ (for IPv6) with the following exceptions: - -- Returns: -- A boolean, True if the address is reserved per -- iana-ipv6-special-registry. -+ * ``is_private`` is ``False`` for ``100.64.0.0/10`` -+ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the -+ semantics of the underlying IPv4 addresses and the following condition holds -+ (see :attr:`IPv6Address.ipv4_mapped`):: - -+ address.is_private == address.ipv4_mapped.is_private -+ -+ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10`` -+ IPv4 range where they are both ``False``. - """ -- return any(self in net for net in self._constants._private_networks) -+ ipv4_mapped = self.ipv4_mapped -+ if ipv4_mapped is not None: -+ return ipv4_mapped.is_private -+ return ( -+ any(self in net for net in self._constants._private_networks) -+ and all(self not in net for net in self._constants._private_networks_exceptions) -+ ) - - @property - def is_global(self): -- """Test if this address is allocated for public networks. -+ """``True`` if the address is defined as globally reachable by -+ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ -+ (for IPv6) with the following exception: - -- Returns: -- A boolean, true if the address is not reserved per -- iana-ipv6-special-registry. -+ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the -+ semantics of the underlying IPv4 addresses and the following condition holds -+ (see :attr:`IPv6Address.ipv4_mapped`):: - -+ address.is_global == address.ipv4_mapped.is_global -+ -+ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10`` -+ IPv4 range where they are both ``False``. - """ - return not self.is_private - -@@ -2252,19 +2301,31 @@ class _IPv6Constants: - - _multicast_network = IPv6Network('ff00::/8') - -+ # Not globally reachable address blocks listed on -+ # https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml - _private_networks = [ - IPv6Network('::1/128'), - IPv6Network('::/128'), - IPv6Network('::ffff:0:0/96'), -+ IPv6Network('64:ff9b:1::/48'), - IPv6Network('100::/64'), - IPv6Network('2001::/23'), -- IPv6Network('2001:2::/48'), - IPv6Network('2001:db8::/32'), -- IPv6Network('2001:10::/28'), -+ # IANA says N/A, let's consider it not globally reachable to be safe -+ IPv6Network('2002::/16'), - IPv6Network('fc00::/7'), - IPv6Network('fe80::/10'), - ] - -+ _private_networks_exceptions = [ -+ IPv6Network('2001:1::1/128'), -+ IPv6Network('2001:1::2/128'), -+ IPv6Network('2001:3::/32'), -+ IPv6Network('2001:4:112::/48'), -+ IPv6Network('2001:20::/28'), -+ IPv6Network('2001:30::/28'), -+ ] -+ - _reserved_networks = [ - IPv6Network('::/8'), IPv6Network('100::/8'), - IPv6Network('200::/7'), IPv6Network('400::/6'), -diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py -index 90897f6bed..bd14f04f6c 100644 ---- a/Lib/test/test_ipaddress.py -+++ b/Lib/test/test_ipaddress.py -@@ -2263,6 +2263,10 @@ class IpaddrUnitTest(unittest.TestCase): - self.assertEqual(True, ipaddress.ip_address( - '172.31.255.255').is_private) - self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private) -+ self.assertFalse(ipaddress.ip_address('192.0.0.0').is_global) -+ self.assertTrue(ipaddress.ip_address('192.0.0.9').is_global) -+ self.assertTrue(ipaddress.ip_address('192.0.0.10').is_global) -+ self.assertFalse(ipaddress.ip_address('192.0.0.255').is_global) - - self.assertEqual(True, - ipaddress.ip_address('169.254.100.200').is_link_local) -@@ -2278,6 +2282,40 @@ class IpaddrUnitTest(unittest.TestCase): - self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback) - self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified) - -+ def testPrivateNetworks(self): -+ self.assertEqual(True, ipaddress.ip_network("0.0.0.0/0").is_private) -+ self.assertEqual(False, ipaddress.ip_network("1.0.0.0/8").is_private) -+ -+ self.assertEqual(True, ipaddress.ip_network("0.0.0.0/8").is_private) -+ self.assertEqual(True, ipaddress.ip_network("10.0.0.0/8").is_private) -+ self.assertEqual(True, ipaddress.ip_network("127.0.0.0/8").is_private) -+ self.assertEqual(True, ipaddress.ip_network("169.254.0.0/16").is_private) -+ self.assertEqual(True, ipaddress.ip_network("172.16.0.0/12").is_private) -+ self.assertEqual(True, ipaddress.ip_network("192.0.0.0/29").is_private) -+ self.assertEqual(False, ipaddress.ip_network("192.0.0.9/32").is_private) -+ self.assertEqual(True, ipaddress.ip_network("192.0.0.170/31").is_private) -+ self.assertEqual(True, ipaddress.ip_network("192.0.2.0/24").is_private) -+ self.assertEqual(True, ipaddress.ip_network("192.168.0.0/16").is_private) -+ self.assertEqual(True, ipaddress.ip_network("198.18.0.0/15").is_private) -+ self.assertEqual(True, ipaddress.ip_network("198.51.100.0/24").is_private) -+ self.assertEqual(True, ipaddress.ip_network("203.0.113.0/24").is_private) -+ self.assertEqual(True, ipaddress.ip_network("240.0.0.0/4").is_private) -+ self.assertEqual(True, ipaddress.ip_network("255.255.255.255/32").is_private) -+ -+ self.assertEqual(False, ipaddress.ip_network("::/0").is_private) -+ self.assertEqual(False, ipaddress.ip_network("::ff/128").is_private) -+ -+ self.assertEqual(True, ipaddress.ip_network("::1/128").is_private) -+ self.assertEqual(True, ipaddress.ip_network("::/128").is_private) -+ self.assertEqual(True, ipaddress.ip_network("::ffff:0:0/96").is_private) -+ self.assertEqual(True, ipaddress.ip_network("100::/64").is_private) -+ self.assertEqual(True, ipaddress.ip_network("2001:2::/48").is_private) -+ self.assertEqual(False, ipaddress.ip_network("2001:3::/48").is_private) -+ self.assertEqual(True, ipaddress.ip_network("2001:db8::/32").is_private) -+ self.assertEqual(True, ipaddress.ip_network("2001:10::/28").is_private) -+ self.assertEqual(True, ipaddress.ip_network("fc00::/7").is_private) -+ self.assertEqual(True, ipaddress.ip_network("fe80::/10").is_private) -+ - def testReservedIpv6(self): - - self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast) -@@ -2351,6 +2389,20 @@ class IpaddrUnitTest(unittest.TestCase): - self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified) - self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified) - -+ self.assertFalse(ipaddress.ip_address('64:ff9b:1::').is_global) -+ self.assertFalse(ipaddress.ip_address('2001::').is_global) -+ self.assertTrue(ipaddress.ip_address('2001:1::1').is_global) -+ self.assertTrue(ipaddress.ip_address('2001:1::2').is_global) -+ self.assertFalse(ipaddress.ip_address('2001:2::').is_global) -+ self.assertTrue(ipaddress.ip_address('2001:3::').is_global) -+ self.assertFalse(ipaddress.ip_address('2001:4::').is_global) -+ self.assertTrue(ipaddress.ip_address('2001:4:112::').is_global) -+ self.assertFalse(ipaddress.ip_address('2001:10::').is_global) -+ self.assertTrue(ipaddress.ip_address('2001:20::').is_global) -+ self.assertTrue(ipaddress.ip_address('2001:30::').is_global) -+ self.assertFalse(ipaddress.ip_address('2001:40::').is_global) -+ self.assertFalse(ipaddress.ip_address('2002::').is_global) -+ - # some generic IETF reserved addresses - self.assertEqual(True, ipaddress.ip_address('100::').is_reserved) - self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved) -diff --git a/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst b/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst -new file mode 100644 -index 0000000000..f9a72473be ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2024-03-14-01-38-44.gh-issue-113171.VFnObz.rst -@@ -0,0 +1,9 @@ -+Fixed various false positives and false negatives in -+ -+* :attr:`ipaddress.IPv4Address.is_private` (see these docs for details) -+* :attr:`ipaddress.IPv4Address.is_global` -+* :attr:`ipaddress.IPv6Address.is_private` -+* :attr:`ipaddress.IPv6Address.is_global` -+ -+Also in the corresponding :class:`ipaddress.IPv4Network` and :class:`ipaddress.IPv6Network` -+attributes. diff --git a/00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch b/00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch deleted file mode 100644 index 432920d..0000000 --- a/00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch +++ /dev/null @@ -1,356 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Petr Viktorin -Date: Wed, 31 Jul 2024 00:19:48 +0200 -Subject: [PATCH] 00435: gh-121650: Encode newlines in headers, and verify - headers are sound (GH-122233) - -Per RFC 2047: - -> [...] these encoding schemes allow the -> encoding of arbitrary octet values, mail readers that implement this -> decoding should also ensure that display of the decoded data on the -> recipient's terminal will not cause unwanted side-effects - -It seems that the "quoted-word" scheme is a valid way to include -a newline character in a header value, just like we already allow -undecodable bytes or control characters. -They do need to be properly quoted when serialized to text, though. - -This should fail for custom fold() implementations that aren't careful -about newlines. - -(cherry picked from commit 097633981879b3c9de9a1dd120d3aa585ecc2384) - -Co-authored-by: Petr Viktorin -Co-authored-by: Bas Bloemsaat -Co-authored-by: Serhiy Storchaka ---- - Doc/library/email.errors.rst | 6 ++ - Doc/library/email.policy.rst | 18 ++++++ - Doc/whatsnew/3.9.rst | 12 ++++ - Lib/email/_header_value_parser.py | 12 +++- - Lib/email/_policybase.py | 8 +++ - Lib/email/errors.py | 4 ++ - Lib/email/generator.py | 13 +++- - Lib/test/test_email/test_generator.py | 62 +++++++++++++++++++ - Lib/test/test_email/test_policy.py | 26 ++++++++ - ...-07-27-16-10-41.gh-issue-121650.nf6oc9.rst | 5 ++ - 10 files changed, 162 insertions(+), 4 deletions(-) - create mode 100644 Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst - -diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst -index f4b9f52509..878c09bb04 100644 ---- a/Doc/library/email.errors.rst -+++ b/Doc/library/email.errors.rst -@@ -59,6 +59,12 @@ The following exception classes are defined in the :mod:`email.errors` module: - :class:`~email.mime.image.MIMEImage`). - - -+.. exception:: HeaderWriteError() -+ -+ Raised when an error occurs when the :mod:`~email.generator` outputs -+ headers. -+ -+ - Here is the list of the defects that the :class:`~email.parser.FeedParser` - can find while parsing messages. Note that the defects are added to the message - where the problem was found, so for example, if a message nested inside a -diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst -index bf53b9520f..57a75ce452 100644 ---- a/Doc/library/email.policy.rst -+++ b/Doc/library/email.policy.rst -@@ -229,6 +229,24 @@ added matters. To illustrate:: - - .. versionadded:: 3.6 - -+ -+ .. attribute:: verify_generated_headers -+ -+ If ``True`` (the default), the generator will raise -+ :exc:`~email.errors.HeaderWriteError` instead of writing a header -+ that is improperly folded or delimited, such that it would -+ be parsed as multiple headers or joined with adjacent data. -+ Such headers can be generated by custom header classes or bugs -+ in the ``email`` module. -+ -+ As it's a security feature, this defaults to ``True`` even in the -+ :class:`~email.policy.Compat32` policy. -+ For backwards compatible, but unsafe, behavior, it must be set to -+ ``False`` explicitly. -+ -+ .. versionadded:: 3.9.20 -+ -+ - The following :class:`Policy` method is intended to be called by code using - the email library to create policy instances with custom settings: - -diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst -index 1756a37338..eeda4e6955 100644 ---- a/Doc/whatsnew/3.9.rst -+++ b/Doc/whatsnew/3.9.rst -@@ -1625,3 +1625,15 @@ ipaddress - - * Fixed ``is_global`` and ``is_private`` behavior in ``IPv4Address``, - ``IPv6Address``, ``IPv4Network`` and ``IPv6Network``. -+ -+email -+----- -+ -+* Headers with embedded newlines are now quoted on output. -+ -+ The :mod:`~email.generator` will now refuse to serialize (write) headers -+ that are improperly folded or delimited, such that they would be parsed as -+ multiple headers or joined with adjacent data. -+ If you need to turn this safety feature off, -+ set :attr:`~email.policy.Policy.verify_generated_headers`. -+ (Contributed by Bas Bloemsaat and Petr Viktorin in :gh:`121650`.) -diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py -index 8a8fb8bc42..e394cfd2e1 100644 ---- a/Lib/email/_header_value_parser.py -+++ b/Lib/email/_header_value_parser.py -@@ -92,6 +92,8 @@ TOKEN_ENDS = TSPECIALS | WSP - ASPECIALS = TSPECIALS | set("*'%") - ATTRIBUTE_ENDS = ASPECIALS | WSP - EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%') -+NLSET = {'\n', '\r'} -+SPECIALSNL = SPECIALS | NLSET - - def quote_string(value): - return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"' -@@ -2778,9 +2780,13 @@ def _refold_parse_tree(parse_tree, *, policy): - wrap_as_ew_blocked -= 1 - continue - tstr = str(part) -- if part.token_type == 'ptext' and set(tstr) & SPECIALS: -- # Encode if tstr contains special characters. -- want_encoding = True -+ if not want_encoding: -+ if part.token_type == 'ptext': -+ # Encode if tstr contains special characters. -+ want_encoding = not SPECIALSNL.isdisjoint(tstr) -+ else: -+ # Encode if tstr contains newlines. -+ want_encoding = not NLSET.isdisjoint(tstr) - try: - tstr.encode(encoding) - charset = encoding -diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py -index c9cbadd2a8..d1f48211f9 100644 ---- a/Lib/email/_policybase.py -+++ b/Lib/email/_policybase.py -@@ -157,6 +157,13 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta): - message_factory -- the class to use to create new message objects. - If the value is None, the default is Message. - -+ verify_generated_headers -+ -- if true, the generator verifies that each header -+ they are properly folded, so that a parser won't -+ treat it as multiple headers, start-of-body, or -+ part of another header. -+ This is a check against custom Header & fold() -+ implementations. - """ - - raise_on_defect = False -@@ -165,6 +172,7 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta): - max_line_length = 78 - mangle_from_ = False - message_factory = None -+ verify_generated_headers = True - - def handle_defect(self, obj, defect): - """Based on policy, either raise defect or call register_defect. -diff --git a/Lib/email/errors.py b/Lib/email/errors.py -index d28a680010..1a0d5c63e6 100644 ---- a/Lib/email/errors.py -+++ b/Lib/email/errors.py -@@ -29,6 +29,10 @@ class CharsetError(MessageError): - """An illegal charset was given.""" - - -+class HeaderWriteError(MessageError): -+ """Error while writing headers.""" -+ -+ - # These are parsing defects which the parser was able to work around. - class MessageDefect(ValueError): - """Base class for a message defect.""" -diff --git a/Lib/email/generator.py b/Lib/email/generator.py -index c9b121624e..89224ae41c 100644 ---- a/Lib/email/generator.py -+++ b/Lib/email/generator.py -@@ -14,12 +14,14 @@ import random - from copy import deepcopy - from io import StringIO, BytesIO - from email.utils import _has_surrogates -+from email.errors import HeaderWriteError - - UNDERSCORE = '_' - NL = '\n' # XXX: no longer used by the code below. - - NLCRE = re.compile(r'\r\n|\r|\n') - fcre = re.compile(r'^From ', re.MULTILINE) -+NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]') - - - -@@ -223,7 +225,16 @@ class Generator: - - def _write_headers(self, msg): - for h, v in msg.raw_items(): -- self.write(self.policy.fold(h, v)) -+ folded = self.policy.fold(h, v) -+ if self.policy.verify_generated_headers: -+ linesep = self.policy.linesep -+ if not folded.endswith(self.policy.linesep): -+ raise HeaderWriteError( -+ f'folded header does not end with {linesep!r}: {folded!r}') -+ if NEWLINE_WITHOUT_FWSP.search(folded.removesuffix(linesep)): -+ raise HeaderWriteError( -+ f'folded header contains newline: {folded!r}') -+ self.write(folded) - # A blank line always separates headers from body - self.write(self._NL) - -diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py -index 89e7edeb63..d29400f0ed 100644 ---- a/Lib/test/test_email/test_generator.py -+++ b/Lib/test/test_email/test_generator.py -@@ -6,6 +6,7 @@ from email.message import EmailMessage - from email.generator import Generator, BytesGenerator - from email.headerregistry import Address - from email import policy -+import email.errors - from test.test_email import TestEmailBase, parameterize - - -@@ -216,6 +217,44 @@ class TestGeneratorBase: - g.flatten(msg) - self.assertEqual(s.getvalue(), self.typ(expected)) - -+ def test_keep_encoded_newlines(self): -+ msg = self.msgmaker(self.typ(textwrap.dedent("""\ -+ To: nobody -+ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com -+ -+ None -+ """))) -+ expected = textwrap.dedent("""\ -+ To: nobody -+ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com -+ -+ None -+ """) -+ s = self.ioclass() -+ g = self.genclass(s, policy=self.policy.clone(max_line_length=80)) -+ g.flatten(msg) -+ self.assertEqual(s.getvalue(), self.typ(expected)) -+ -+ def test_keep_long_encoded_newlines(self): -+ msg = self.msgmaker(self.typ(textwrap.dedent("""\ -+ To: nobody -+ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com -+ -+ None -+ """))) -+ expected = textwrap.dedent("""\ -+ To: nobody -+ Subject: Bad subject -+ =?utf-8?q?=0A?=Bcc: -+ injection@example.com -+ -+ None -+ """) -+ s = self.ioclass() -+ g = self.genclass(s, policy=self.policy.clone(max_line_length=30)) -+ g.flatten(msg) -+ self.assertEqual(s.getvalue(), self.typ(expected)) -+ - - class TestGenerator(TestGeneratorBase, TestEmailBase): - -@@ -224,6 +263,29 @@ class TestGenerator(TestGeneratorBase, TestEmailBase): - ioclass = io.StringIO - typ = str - -+ def test_verify_generated_headers(self): -+ """gh-121650: by default the generator prevents header injection""" -+ class LiteralHeader(str): -+ name = 'Header' -+ def fold(self, **kwargs): -+ return self -+ -+ for text in ( -+ 'Value\r\nBad Injection\r\n', -+ 'NoNewLine' -+ ): -+ with self.subTest(text=text): -+ message = message_from_string( -+ "Header: Value\r\n\r\nBody", -+ policy=self.policy, -+ ) -+ -+ del message['Header'] -+ message['Header'] = LiteralHeader(text) -+ -+ with self.assertRaises(email.errors.HeaderWriteError): -+ message.as_string() -+ - - class TestBytesGenerator(TestGeneratorBase, TestEmailBase): - -diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py -index e87c275549..ff1ddf7d7a 100644 ---- a/Lib/test/test_email/test_policy.py -+++ b/Lib/test/test_email/test_policy.py -@@ -26,6 +26,7 @@ class PolicyAPITests(unittest.TestCase): - 'raise_on_defect': False, - 'mangle_from_': True, - 'message_factory': None, -+ 'verify_generated_headers': True, - } - # These default values are the ones set on email.policy.default. - # If any of these defaults change, the docs must be updated. -@@ -277,6 +278,31 @@ class PolicyAPITests(unittest.TestCase): - with self.assertRaises(email.errors.HeaderParseError): - policy.fold("Subject", subject) - -+ def test_verify_generated_headers(self): -+ """Turning protection off allows header injection""" -+ policy = email.policy.default.clone(verify_generated_headers=False) -+ for text in ( -+ 'Header: Value\r\nBad: Injection\r\n', -+ 'Header: NoNewLine' -+ ): -+ with self.subTest(text=text): -+ message = email.message_from_string( -+ "Header: Value\r\n\r\nBody", -+ policy=policy, -+ ) -+ class LiteralHeader(str): -+ name = 'Header' -+ def fold(self, **kwargs): -+ return self -+ -+ del message['Header'] -+ message['Header'] = LiteralHeader(text) -+ -+ self.assertEqual( -+ message.as_string(), -+ f"{text}\nBody", -+ ) -+ - # XXX: Need subclassing tests. - # For adding subclassed objects, make sure the usual rules apply (subclass - # wins), but that the order still works (right overrides left). -diff --git a/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst b/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst -new file mode 100644 -index 0000000000..83dd28d4ac ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst -@@ -0,0 +1,5 @@ -+:mod:`email` headers with embedded newlines are now quoted on output. The -+:mod:`~email.generator` will now refuse to serialize (write) headers that -+are unsafely folded or delimited; see -+:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas -+Bloemsaat and Petr Viktorin in :gh:`121650`.) diff --git a/00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch b/00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch deleted file mode 100644 index fed0497..0000000 --- a/00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Jason R. Coombs" -Date: Mon, 19 Aug 2024 19:28:20 -0400 -Subject: [PATCH] 00436: [CVE-2024-8088] gh-122905: Sanitize names in - zipfile.Path. - -Co-authored-by: Jason R. Coombs ---- - Lib/test/test_zipfile.py | 17 ++++++ - Lib/zipfile.py | 61 ++++++++++++++++++- - ...-08-11-14-08-04.gh-issue-122905.7tDsxA.rst | 1 + - 3 files changed, 78 insertions(+), 1 deletion(-) - create mode 100644 Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst - -diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py -index 17e95eb862..9a72152357 100644 ---- a/Lib/test/test_zipfile.py -+++ b/Lib/test/test_zipfile.py -@@ -3054,6 +3054,23 @@ class TestPath(unittest.TestCase): - data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)] - zipfile.CompleteDirs._implied_dirs(data) - -+ def test_malformed_paths(self): -+ """ -+ Path should handle malformed paths. -+ """ -+ data = io.BytesIO() -+ zf = zipfile.ZipFile(data, "w") -+ zf.writestr("/one-slash.txt", b"content") -+ zf.writestr("//two-slash.txt", b"content") -+ zf.writestr("../parent.txt", b"content") -+ zf.filename = '' -+ root = zipfile.Path(zf) -+ assert list(map(str, root.iterdir())) == [ -+ 'one-slash.txt', -+ 'two-slash.txt', -+ 'parent.txt', -+ ] -+ - - if __name__ == "__main__": - unittest.main() -diff --git a/Lib/zipfile.py b/Lib/zipfile.py -index 95f95ee112..2e9b2868cd 100644 ---- a/Lib/zipfile.py -+++ b/Lib/zipfile.py -@@ -9,6 +9,7 @@ import io - import itertools - import os - import posixpath -+import re - import shutil - import stat - import struct -@@ -2177,7 +2178,65 @@ def _difference(minuend, subtrahend): - return itertools.filterfalse(set(subtrahend).__contains__, minuend) - - --class CompleteDirs(ZipFile): -+class SanitizedNames: -+ """ -+ ZipFile mix-in to ensure names are sanitized. -+ """ -+ -+ def namelist(self): -+ return list(map(self._sanitize, super().namelist())) -+ -+ @staticmethod -+ def _sanitize(name): -+ r""" -+ Ensure a relative path with posix separators and no dot names. -+ Modeled after -+ https://github.com/python/cpython/blob/bcc1be39cb1d04ad9fc0bd1b9193d3972835a57c/Lib/zipfile/__init__.py#L1799-L1813 -+ but provides consistent cross-platform behavior. -+ >>> san = SanitizedNames._sanitize -+ >>> san('/foo/bar') -+ 'foo/bar' -+ >>> san('//foo.txt') -+ 'foo.txt' -+ >>> san('foo/.././bar.txt') -+ 'foo/bar.txt' -+ >>> san('foo../.bar.txt') -+ 'foo../.bar.txt' -+ >>> san('\\foo\\bar.txt') -+ 'foo/bar.txt' -+ >>> san('D:\\foo.txt') -+ 'D/foo.txt' -+ >>> san('\\\\server\\share\\file.txt') -+ 'server/share/file.txt' -+ >>> san('\\\\?\\GLOBALROOT\\Volume3') -+ '?/GLOBALROOT/Volume3' -+ >>> san('\\\\.\\PhysicalDrive1\\root') -+ 'PhysicalDrive1/root' -+ Retain any trailing slash. -+ >>> san('abc/') -+ 'abc/' -+ Raises a ValueError if the result is empty. -+ >>> san('../..') -+ Traceback (most recent call last): -+ ... -+ ValueError: Empty filename -+ """ -+ -+ def allowed(part): -+ return part and part not in {'..', '.'} -+ -+ # Remove the drive letter. -+ # Don't use ntpath.splitdrive, because that also strips UNC paths -+ bare = re.sub('^([A-Z]):', r'\1', name, flags=re.IGNORECASE) -+ clean = bare.replace('\\', '/') -+ parts = clean.split('/') -+ joined = '/'.join(filter(allowed, parts)) -+ if not joined: -+ raise ValueError("Empty filename") -+ return joined + '/' * name.endswith('/') -+ -+ -+class CompleteDirs(SanitizedNames, ZipFile): - """ - A ZipFile subclass that ensures that implied directories - are always included in the namelist. -diff --git a/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst b/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst -new file mode 100644 -index 0000000000..1be44c906c ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst -@@ -0,0 +1 @@ -+:class:`zipfile.Path` objects now sanitize names from the zipfile. diff --git a/python3.9.spec b/python3.9.spec index 6cc8bc9..e3df36c 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.19 +%global general_version %{pybasever}.20 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 6%{?dist} +Release: 1%{?dist} License: Python @@ -385,74 +385,6 @@ Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-g # gh-99086: Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch -# 00415 # 512c60eb23a8d7b26d74824a6d7bbefb6feefb65 -# [CVE-2023-27043] gh-102988: Reject malformed addresses in email.parseaddr() (#111116) -# -# Detect email address parsing errors and return empty tuple to -# indicate the parsing error (old API). Add an optional 'strict' -# parameter to getaddresses() and parseaddr() functions. Patch by -# Thomas Dwyer. -Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch - -# 00419 # f13682530cc7e4daec2e40acd56508846fdd3aad -# gh-112769: test_zlib: Fix comparison of ZLIB_RUNTIME_VERSION with non-int suffix (GH-112771) (GH-112774) -# -# zlib-ng defines the version as "1.3.0.zlib-ng". -Patch419: 00419-gh-112769-test_zlib-fix-comparison-of-zlib_runtime_version-with-non-int-suffix-gh-112771-gh-112774.patch - -# 00431 # 1216ca6d2f3d6fc7ef7bf33b78b7a887be02e467 -# gh-113171: gh-65056: Fix "private" (non-global) IP address ranges (GH-113179) (GH-113186) (GH-118177) (GH-118472) -# -# The _private_networks variables, used by various is_private -# implementations, were missing some ranges and at the same time had -# overly strict ranges (where there are more specific ranges considered -# globally reachable by the IANA registries). -# -# This patch updates the ranges with what was missing or otherwise -# incorrect. -# -# 100.64.0.0/10 is left alone, for now, as it's been made special in [1]. -# -# The _address_exclude_many() call returns 8 networks for IPv4, 121 -# networks for IPv6. -# -# [1] https://github.com/python/cpython/issues/61602 -# -# In 3.10 and below, is_private checks whether the network and broadcast -# address are both private. -# In later versions (where the test wss backported from), it checks -# whether they both are in the same private network. -# -# For 0.0.0.0/0, both 0.0.0.0 and 255.225.255.255 are private, -# but one is in 0.0.0.0/8 ("This network") and the other in -# 255.255.255.255/32 ("Limited broadcast"). -# -# --------- -Patch431: 00431-gh-113171-gh-65056-fix-private-non-global-ip-address-ranges-gh-113179-gh-113186-gh-118177-gh-118472.patch - -# 00435 # f2924d30f4dd44804219c10410a57dd96764d297 -# gh-121650: Encode newlines in headers, and verify headers are sound (GH-122233) -# -# Per RFC 2047: -# -# > [...] these encoding schemes allow the -# > encoding of arbitrary octet values, mail readers that implement this -# > decoding should also ensure that display of the decoded data on the -# > recipient's terminal will not cause unwanted side-effects -# -# It seems that the "quoted-word" scheme is a valid way to include -# a newline character in a header value, just like we already allow -# undecodable bytes or control characters. -# They do need to be properly quoted when serialized to text, though. -# -# This should fail for custom fold() implementations that aren't careful -# about newlines. -Patch435: 00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch - -# 00436 # 506dd77b7132f69ada7185b8bb91eba0e1296aa8 -# [CVE-2024-8088] gh-122905: Sanitize names in zipfile.Path. -Patch436: 00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1900,6 +1832,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Sep 09 2024 Tomáš Hrnčiar - 3.9.20-1 +- Update to 3.9.20 + * Fri Aug 23 2024 Charalampos Stratakis - 3.9.19-6 - Security fix for CVE-2024-8088 - Fixes: rhbz#2307466 diff --git a/sources b/sources index be10285..b5a8526 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.19.tar.xz) = 5577830c734e63a70bbc62cd33d263b9aa87c4381b49cb694c3559067c4c682a55506b65ec5514a8e0a5abf6294dc728e909385d449ae1c388e62f83cea9bb89 -SHA512 (Python-3.9.19.tar.xz.asc) = f7f4946243dfc56de2c84f50276b088d347f17054f50e3331d1e312e2a8e2c6ed1b4b4a807202b51137fd2af3fc9218cafa42ed348a954ace896d9a432e2defd +SHA512 (Python-3.9.20.tar.xz) = c828f33edf1704e3149499d6d34e89264cb5cdb2b09ff05561641b359716d7996f0fe928629e09f006b1fd7850fdaf937275919c7fdd83f5efc32707c64d814b +SHA512 (Python-3.9.20.tar.xz.asc) = f21c012f4f642542479ba329da9654589e5a7f7305c39fb1b6f136b578316bdb115cef9773c9a9fe4e195677af01cb80af05780613cca83f42fae131862a9584 From 2fef19cb00dac73c4b5bd2e61c55a7ec911283db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 11 Sep 2024 20:17:24 +0200 Subject: [PATCH 70/89] Fix ThreadedVSOCKSocketStreamTest --- ...treamtest-gh-119465-gh-119479-119484.patch | 66 +++++++++++++++++++ python3.9.spec | 11 ++++ 2 files changed, 77 insertions(+) create mode 100644 00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch diff --git a/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch b/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch new file mode 100644 index 0000000..5467db7 --- /dev/null +++ b/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Fri, 24 May 2024 01:23:55 +0200 +Subject: [PATCH] 00438: Fix ThreadedVSOCKSocketStreamTest (GH-119465) + (GH-119479) (#119484) + +Fix ThreadedVSOCKSocketStreamTest: if get_cid() returns the host +address or the "any" address, use the local communication address +(loopback): VMADDR_CID_LOCAL. + +On Linux 6.9, apparently, the /dev/vsock device is now available but +get_cid() returns VMADDR_CID_ANY (-1). + +(cherry picked from commit c750061047ee520d8299334df4b112fd983d7e48) + +Co-authored-by: Victor Stinner +(cherry picked from commit e94dbe4ed83460f18bd72563c5f09f6cdc71f604) + +Co-authored-by: Victor Stinner +--- + Lib/test/test_socket.py | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py +index b36cb5beae..2f73ec24c3 100755 +--- a/Lib/test/test_socket.py ++++ b/Lib/test/test_socket.py +@@ -39,6 +39,7 @@ HOST = socket_helper.HOST + # test unicode string and carriage return + MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') + ++VMADDR_CID_LOCAL = 1 + VSOCKPORT = 1234 + AIX = platform.system() == "AIX" + +@@ -122,8 +123,8 @@ def _have_socket_qipcrtr(): + + def _have_socket_vsock(): + """Check whether AF_VSOCK sockets are supported on this host.""" +- ret = get_cid() is not None +- return ret ++ cid = get_cid() ++ return (cid is not None) + + + def _have_socket_bluetooth(): +@@ -485,8 +486,6 @@ class ThreadedRDSSocketTest(SocketRDSTest, ThreadableTest): + @unittest.skipIf(fcntl is None, "need fcntl") + @unittest.skipUnless(HAVE_SOCKET_VSOCK, + 'VSOCK sockets required for this test.') +-@unittest.skipUnless(get_cid() != 2, +- "This test can only be run on a virtual guest.") + class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest): + + def __init__(self, methodName='runTest'): +@@ -507,6 +506,9 @@ class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest): + self.cli = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) + self.addCleanup(self.cli.close) + cid = get_cid() ++ if cid in (socket.VMADDR_CID_HOST, socket.VMADDR_CID_ANY): ++ # gh-119461: Use the local communication address (loopback) ++ cid = VMADDR_CID_LOCAL + self.cli.connect((cid, VSOCKPORT)) + + def testStream(self): diff --git a/python3.9.spec b/python3.9.spec index e3df36c..2b98d86 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -385,6 +385,17 @@ Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-g # gh-99086: Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch +# 00438 # 640f507108d102da99fa2f39d268a43f86c97acb +# Fix ThreadedVSOCKSocketStreamTest (GH-119465) (GH-119479) (#119484) +# +# Fix ThreadedVSOCKSocketStreamTest: if get_cid() returns the host +# address or the "any" address, use the local communication address +# (loopback): VMADDR_CID_LOCAL. +# +# On Linux 6.9, apparently, the /dev/vsock device is now available but +# get_cid() returns VMADDR_CID_ANY (-1). +Patch438: 00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., From 0a29aebca7985daea839d2c1cd71cedfe878b146 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Tue, 3 Dec 2024 20:46:20 +0100 Subject: [PATCH 71/89] Update to 3.9.21 Fixes: rhbz#2321662 --- ...edvsocksocketstreamtest-gh-119465-gh-119479-119484.patch | 2 +- python3.9.spec | 6 +++++- sources | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch b/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch index 5467db7..19c7a5f 100644 --- a/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch +++ b/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch @@ -23,7 +23,7 @@ Co-authored-by: Victor Stinner 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py -index b36cb5beae..2f73ec24c3 100755 +index 1957149cac..e76701d1bc 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -39,6 +39,7 @@ HOST = socket_helper.HOST diff --git a/python3.9.spec b/python3.9.spec index 2b98d86..21da409 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,7 +13,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.20 +%global general_version %{pybasever}.21 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} @@ -1843,6 +1843,10 @@ CheckPython optimized # ====================================================== %changelog +* Tue Dec 03 2024 Lumír Balhar - 3.9.21-1 +- Update to 3.9.21 +- Fixes: rhbz#2321662 + * Mon Sep 09 2024 Tomáš Hrnčiar - 3.9.20-1 - Update to 3.9.20 diff --git a/sources b/sources index b5a8526..0fce215 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.20.tar.xz) = c828f33edf1704e3149499d6d34e89264cb5cdb2b09ff05561641b359716d7996f0fe928629e09f006b1fd7850fdaf937275919c7fdd83f5efc32707c64d814b -SHA512 (Python-3.9.20.tar.xz.asc) = f21c012f4f642542479ba329da9654589e5a7f7305c39fb1b6f136b578316bdb115cef9773c9a9fe4e195677af01cb80af05780613cca83f42fae131862a9584 +SHA512 (Python-3.9.21.tar.xz) = cc84c967cd7a05361ec144d87ca044bd416032ee92dfb78658758d4e1274971f5fb288876d9c599a729bb21258974a786089341bce6bdcffd9c30ebd69b7ca58 +SHA512 (Python-3.9.21.tar.xz.asc) = 1e5e5a5db8074a7ee5eb51e6c789d6e46467165d72d2d636d1fc0d3e15d4355051f9f7ad3063ba43b37b611095765c9d654ed890067c201c087da1eecb620ef9 From 603a075b8814eda6fc7f0b3b16ab37fb91adfc68 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 18 Jan 2025 21:09:49 +0000 Subject: [PATCH 72/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 21da409..6359407 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -1843,6 +1843,9 @@ CheckPython optimized # ====================================================== %changelog +* Sat Jan 18 2025 Fedora Release Engineering - 3.9.21-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Tue Dec 03 2024 Lumír Balhar - 3.9.21-1 - Update to 3.9.21 - Fixes: rhbz#2321662 From f400b226ef8d7a5f43dfd27cb071ac3a3924f298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sat, 1 Feb 2025 19:57:05 +0100 Subject: [PATCH 73/89] Add explicit BR: libxcrypt-devel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- python3.9.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 6359407..4a68789 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -237,6 +237,7 @@ BuildRequires: libnsl2-devel BuildRequires: libtirpc-devel BuildRequires: libGL-devel BuildRequires: libuuid-devel +BuildRequires: libxcrypt-devel BuildRequires: libX11-devel BuildRequires: make BuildRequires: ncurses-devel @@ -1843,6 +1844,9 @@ CheckPython optimized # ====================================================== %changelog +* Sat Feb 01 2025 Björn Esser - 3.9.21-3 +- Add explicit BR: libxcrypt-devel + * Sat Jan 18 2025 Fedora Release Engineering - 3.9.21-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From eeac858b096a6df2963332c57664f5a732883efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 3 Feb 2025 11:13:44 +0000 Subject: [PATCH 74/89] Ensure this package is built with Tk 8 - Fixes: rhbz#2337764 --- python3.9.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index 4a68789..0b23613 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -250,9 +250,9 @@ BuildRequires: sqlite-devel BuildRequires: gdb BuildRequires: tar -BuildRequires: tcl-devel +BuildRequires: tcl-devel < 1:9 BuildRequires: tix-devel -BuildRequires: tk-devel +BuildRequires: tk-devel < 1:9 BuildRequires: tzdata %if %{with valgrind} From e575a4e5ce86c36b426e00b1414e7a236f199fed Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Mon, 10 Feb 2025 23:59:20 +0100 Subject: [PATCH 75/89] Security fix for CVE-2025-0938 Fixes: rhbz#2343278 --- ...-and-in-domain-names-for-parsed-urls.patch | 119 ++++++++++++++++++ python3.9.spec | 10 +- 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch diff --git a/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch b/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch new file mode 100644 index 0000000..a96f8e6 --- /dev/null +++ b/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch @@ -0,0 +1,119 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Fri, 31 Jan 2025 11:41:34 -0600 +Subject: [PATCH] 00450: CVE-2025-0938: Disallow square brackets ([ and ]) in + domain names for parsed URLs + +Co-authored-by: Peter Bierma +--- + Lib/test/test_urlparse.py | 37 ++++++++++++++++++- + Lib/urllib/parse.py | 20 +++++++++- + ...-01-28-14-08-03.gh-issue-105704.EnhHxu.rst | 4 ++ + 3 files changed, 58 insertions(+), 3 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst + +diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py +index 6f7d40c212..083d08b22e 100644 +--- a/Lib/test/test_urlparse.py ++++ b/Lib/test/test_urlparse.py +@@ -1146,16 +1146,51 @@ class UrlParseTestCase(unittest.TestCase): + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a1') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a1') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:1a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:1a') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:/') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:?') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@prefix.[v6a.ip]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@[v6a.ip].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip]') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip[') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip].suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip[suffix') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip') ++ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[suffix') + + def test_splitting_bracketed_hosts(self): +- p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query') ++ p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]:1234/path?query') + self.assertEqual(p1.hostname, 'v6a.ip') + self.assertEqual(p1.username, 'user') + self.assertEqual(p1.path, '/path') ++ self.assertEqual(p1.port, 1234) + p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query') + self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test') + self.assertEqual(p2.username, 'user') + self.assertEqual(p2.path, '/path') ++ self.assertIs(p2.port, None) + p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query') + self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test') + self.assertEqual(p3.username, 'user') +diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py +index 9d37dcaa90..fb8f7f1ea8 100644 +--- a/Lib/urllib/parse.py ++++ b/Lib/urllib/parse.py +@@ -443,6 +443,23 @@ def _checknetloc(netloc): + raise ValueError("netloc '" + netloc + "' contains invalid " + + "characters under NFKC normalization") + ++def _check_bracketed_netloc(netloc): ++ # Note that this function must mirror the splitting ++ # done in NetlocResultMixins._hostinfo(). ++ hostname_and_port = netloc.rpartition('@')[2] ++ before_bracket, have_open_br, bracketed = hostname_and_port.partition('[') ++ if have_open_br: ++ # No data is allowed before a bracket. ++ if before_bracket: ++ raise ValueError("Invalid IPv6 URL") ++ hostname, _, port = bracketed.partition(']') ++ # No data is allowed after the bracket but before the port delimiter. ++ if port and not port.startswith(":"): ++ raise ValueError("Invalid IPv6 URL") ++ else: ++ hostname, _, port = hostname_and_port.partition(':') ++ _check_bracketed_host(hostname) ++ + # Valid bracketed hosts are defined in + # https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/ + def _check_bracketed_host(hostname): +@@ -506,8 +523,7 @@ def urlsplit(url, scheme='', allow_fragments=True): + (']' in netloc and '[' not in netloc)): + raise ValueError("Invalid IPv6 URL") + if '[' in netloc and ']' in netloc: +- bracketed_host = netloc.partition('[')[2].partition(']')[0] +- _check_bracketed_host(bracketed_host) ++ _check_bracketed_netloc(netloc) + if allow_fragments and '#' in url: + url, fragment = url.split('#', 1) + if '?' in url: +diff --git a/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst +new file mode 100644 +index 0000000000..bff1bc6b0d +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst +@@ -0,0 +1,4 @@ ++When using :func:`urllib.parse.urlsplit` and :func:`urllib.parse.urlparse` host ++parsing would not reject domain names containing square brackets (``[`` and ++``]``). Square brackets are only valid for IPv6 and IPvFuture hosts according to ++`RFC 3986 Section 3.2.2 `__. diff --git a/python3.9.spec b/python3.9.spec index 0b23613..64e3607 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 3%{?dist} +Release: 4%{?dist} License: Python @@ -397,6 +397,10 @@ Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-fo # get_cid() returns VMADDR_CID_ANY (-1). Patch438: 00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch +# 00450 # 4ab8663661748eb994c09e4ae89f59eb84c5d3ea +# CVE-2025-0938: Disallow square brackets ([ and ]) in domain names for parsed URLs +Patch450: 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1844,6 +1848,10 @@ CheckPython optimized # ====================================================== %changelog +* Mon Feb 10 2025 Charalampos Stratakis - 3.9.21-4 +- Security fix for CVE-2025-0938 +- Fixes: rhbz#2343278 + * Sat Feb 01 2025 Björn Esser - 3.9.21-3 - Add explicit BR: libxcrypt-devel From b696aebe3d8a14f0e334088bf4d7208a10bda83a Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Tue, 1 Apr 2025 01:52:07 +0200 Subject: [PATCH 76/89] Properly apply exported CFLAGS for dtrace/systemtap builds Fixes: rhbz#2356304 --- ...d-cflags-for-dtrace-systemtap-builds.patch | 52 +++++++++++++++++++ python3.9.spec | 18 ++++++- 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch diff --git a/00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch b/00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch new file mode 100644 index 0000000..edcdacb --- /dev/null +++ b/00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Mon, 31 Mar 2025 20:29:04 +0200 +Subject: [PATCH] 00452: Properly apply exported CFLAGS for dtrace/systemtap + builds + +When using --with-dtrace the resulting object file could be missing +specific CFLAGS exported by the build system due to the systemtap +script using specific defaults. + +Exporting the CC and CFLAGS variables before the dtrace invocation +allows us to properly apply CFLAGS exported by the build system +even when cross-compiling. + +Co-authored-by: stratakis +--- + Makefile.pre.in | 4 ++-- + .../next/Build/2025-03-31-19-22-41.gh-issue-131865.PIJy7X.rst | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + create mode 100644 Misc/NEWS.d/next/Build/2025-03-31-19-22-41.gh-issue-131865.PIJy7X.rst + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 568018827b..b401724d92 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -989,7 +989,7 @@ Python/frozen.o: $(srcdir)/Python/importlib.h $(srcdir)/Python/importlib_externa + # an include guard, so we can't use a pipeline to transform its output. + Include/pydtrace_probes.h: $(srcdir)/Include/pydtrace.d + $(MKDIR_P) Include +- $(DTRACE) $(DFLAGS) -o $@ -h -s $< ++ CC="$(CC)" CFLAGS="$(CFLAGS)" $(DTRACE) $(DFLAGS) -o $@ -h -s $< + : sed in-place edit with POSIX-only tools + sed 's/PYTHON_/PyDTrace_/' $@ > $@.tmp + mv $@.tmp $@ +@@ -999,7 +999,7 @@ Python/import.o: $(srcdir)/Include/pydtrace.h + Modules/gcmodule.o: $(srcdir)/Include/pydtrace.h + + Python/pydtrace.o: $(srcdir)/Include/pydtrace.d $(DTRACE_DEPS) +- $(DTRACE) $(DFLAGS) -o $@ -G -s $< $(DTRACE_DEPS) ++ CC="$(CC)" CFLAGS="$(CFLAGS)" $(DTRACE) $(DFLAGS) -o $@ -G -s $< $(DTRACE_DEPS) + + Objects/typeobject.o: Objects/typeslots.inc + +diff --git a/Misc/NEWS.d/next/Build/2025-03-31-19-22-41.gh-issue-131865.PIJy7X.rst b/Misc/NEWS.d/next/Build/2025-03-31-19-22-41.gh-issue-131865.PIJy7X.rst +new file mode 100644 +index 0000000000..a287e0b228 +--- /dev/null ++++ b/Misc/NEWS.d/next/Build/2025-03-31-19-22-41.gh-issue-131865.PIJy7X.rst +@@ -0,0 +1,2 @@ ++The DTrace build now properly passes the ``CC`` and ``CFLAGS`` variables ++to the ``dtrace`` command when utilizing SystemTap on Linux. diff --git a/python3.9.spec b/python3.9.spec index 64e3607..ec46f98 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 4%{?dist} +Release: 5%{?dist} License: Python @@ -401,6 +401,18 @@ Patch438: 00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.pat # CVE-2025-0938: Disallow square brackets ([ and ]) in domain names for parsed URLs Patch450: 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch +# 00452 # eb11d070c5af7d1b5e47f4e02186152d08eaf793 +# Properly apply exported CFLAGS for dtrace/systemtap builds +# +# When using --with-dtrace the resulting object file could be missing +# specific CFLAGS exported by the build system due to the systemtap +# script using specific defaults. +# +# Exporting the CC and CFLAGS variables before the dtrace invocation +# allows us to properly apply CFLAGS exported by the build system +# even when cross-compiling. +Patch452: 00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1848,6 +1860,10 @@ CheckPython optimized # ====================================================== %changelog +* Mon Mar 31 2025 Charalampos Stratakis - 3.9.21-5 +- Properly apply exported CFLAGS for dtrace/systemtap builds +- Fixes: rhbz#2356304 + * Mon Feb 10 2025 Charalampos Stratakis - 3.9.21-4 - Security fix for CVE-2025-0938 - Fixes: rhbz#2343278 From 6f034960f57b9505efe1e98a1a9089af7b23cc16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 9 Apr 2025 10:21:52 +0200 Subject: [PATCH 77/89] Update to 3.9.22 --- ...treamtest-gh-119465-gh-119479-119484.patch | 66 ---------- ...-and-in-domain-names-for-parsed-urls.patch | 119 ------------------ python3.9.spec | 22 +--- sources | 4 +- 4 files changed, 7 insertions(+), 204 deletions(-) delete mode 100644 00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch delete mode 100644 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch diff --git a/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch b/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch deleted file mode 100644 index 19c7a5f..0000000 --- a/00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Fri, 24 May 2024 01:23:55 +0200 -Subject: [PATCH] 00438: Fix ThreadedVSOCKSocketStreamTest (GH-119465) - (GH-119479) (#119484) - -Fix ThreadedVSOCKSocketStreamTest: if get_cid() returns the host -address or the "any" address, use the local communication address -(loopback): VMADDR_CID_LOCAL. - -On Linux 6.9, apparently, the /dev/vsock device is now available but -get_cid() returns VMADDR_CID_ANY (-1). - -(cherry picked from commit c750061047ee520d8299334df4b112fd983d7e48) - -Co-authored-by: Victor Stinner -(cherry picked from commit e94dbe4ed83460f18bd72563c5f09f6cdc71f604) - -Co-authored-by: Victor Stinner ---- - Lib/test/test_socket.py | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py -index 1957149cac..e76701d1bc 100755 ---- a/Lib/test/test_socket.py -+++ b/Lib/test/test_socket.py -@@ -39,6 +39,7 @@ HOST = socket_helper.HOST - # test unicode string and carriage return - MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') - -+VMADDR_CID_LOCAL = 1 - VSOCKPORT = 1234 - AIX = platform.system() == "AIX" - -@@ -122,8 +123,8 @@ def _have_socket_qipcrtr(): - - def _have_socket_vsock(): - """Check whether AF_VSOCK sockets are supported on this host.""" -- ret = get_cid() is not None -- return ret -+ cid = get_cid() -+ return (cid is not None) - - - def _have_socket_bluetooth(): -@@ -485,8 +486,6 @@ class ThreadedRDSSocketTest(SocketRDSTest, ThreadableTest): - @unittest.skipIf(fcntl is None, "need fcntl") - @unittest.skipUnless(HAVE_SOCKET_VSOCK, - 'VSOCK sockets required for this test.') --@unittest.skipUnless(get_cid() != 2, -- "This test can only be run on a virtual guest.") - class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest): - - def __init__(self, methodName='runTest'): -@@ -507,6 +506,9 @@ class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest): - self.cli = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) - self.addCleanup(self.cli.close) - cid = get_cid() -+ if cid in (socket.VMADDR_CID_HOST, socket.VMADDR_CID_ANY): -+ # gh-119461: Use the local communication address (loopback) -+ cid = VMADDR_CID_LOCAL - self.cli.connect((cid, VSOCKPORT)) - - def testStream(self): diff --git a/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch b/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch deleted file mode 100644 index a96f8e6..0000000 --- a/00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Fri, 31 Jan 2025 11:41:34 -0600 -Subject: [PATCH] 00450: CVE-2025-0938: Disallow square brackets ([ and ]) in - domain names for parsed URLs - -Co-authored-by: Peter Bierma ---- - Lib/test/test_urlparse.py | 37 ++++++++++++++++++- - Lib/urllib/parse.py | 20 +++++++++- - ...-01-28-14-08-03.gh-issue-105704.EnhHxu.rst | 4 ++ - 3 files changed, 58 insertions(+), 3 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst - -diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py -index 6f7d40c212..083d08b22e 100644 ---- a/Lib/test/test_urlparse.py -+++ b/Lib/test/test_urlparse.py -@@ -1146,16 +1146,51 @@ class UrlParseTestCase(unittest.TestCase): - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a1') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a1') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:1a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:1a') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:/') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:?') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@prefix.[v6a.ip]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@[v6a.ip].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip]') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip[') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip].suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip[suffix') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip') -+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[suffix') - - def test_splitting_bracketed_hosts(self): -- p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query') -+ p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]:1234/path?query') - self.assertEqual(p1.hostname, 'v6a.ip') - self.assertEqual(p1.username, 'user') - self.assertEqual(p1.path, '/path') -+ self.assertEqual(p1.port, 1234) - p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query') - self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test') - self.assertEqual(p2.username, 'user') - self.assertEqual(p2.path, '/path') -+ self.assertIs(p2.port, None) - p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query') - self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test') - self.assertEqual(p3.username, 'user') -diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py -index 9d37dcaa90..fb8f7f1ea8 100644 ---- a/Lib/urllib/parse.py -+++ b/Lib/urllib/parse.py -@@ -443,6 +443,23 @@ def _checknetloc(netloc): - raise ValueError("netloc '" + netloc + "' contains invalid " + - "characters under NFKC normalization") - -+def _check_bracketed_netloc(netloc): -+ # Note that this function must mirror the splitting -+ # done in NetlocResultMixins._hostinfo(). -+ hostname_and_port = netloc.rpartition('@')[2] -+ before_bracket, have_open_br, bracketed = hostname_and_port.partition('[') -+ if have_open_br: -+ # No data is allowed before a bracket. -+ if before_bracket: -+ raise ValueError("Invalid IPv6 URL") -+ hostname, _, port = bracketed.partition(']') -+ # No data is allowed after the bracket but before the port delimiter. -+ if port and not port.startswith(":"): -+ raise ValueError("Invalid IPv6 URL") -+ else: -+ hostname, _, port = hostname_and_port.partition(':') -+ _check_bracketed_host(hostname) -+ - # Valid bracketed hosts are defined in - # https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/ - def _check_bracketed_host(hostname): -@@ -506,8 +523,7 @@ def urlsplit(url, scheme='', allow_fragments=True): - (']' in netloc and '[' not in netloc)): - raise ValueError("Invalid IPv6 URL") - if '[' in netloc and ']' in netloc: -- bracketed_host = netloc.partition('[')[2].partition(']')[0] -- _check_bracketed_host(bracketed_host) -+ _check_bracketed_netloc(netloc) - if allow_fragments and '#' in url: - url, fragment = url.split('#', 1) - if '?' in url: -diff --git a/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst -new file mode 100644 -index 0000000000..bff1bc6b0d ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2025-01-28-14-08-03.gh-issue-105704.EnhHxu.rst -@@ -0,0 +1,4 @@ -+When using :func:`urllib.parse.urlsplit` and :func:`urllib.parse.urlparse` host -+parsing would not reject domain names containing square brackets (``[`` and -+``]``). Square brackets are only valid for IPv6 and IPvFuture hosts according to -+`RFC 3986 Section 3.2.2 `__. diff --git a/python3.9.spec b/python3.9.spec index ec46f98..be59027 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.21 +%global general_version %{pybasever}.22 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 5%{?dist} +Release: 1%{?dist} License: Python @@ -386,21 +386,6 @@ Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-g # gh-99086: Fix implicit int compiler warning in configure check for PTHREAD_SCOPE_SYSTEM Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch -# 00438 # 640f507108d102da99fa2f39d268a43f86c97acb -# Fix ThreadedVSOCKSocketStreamTest (GH-119465) (GH-119479) (#119484) -# -# Fix ThreadedVSOCKSocketStreamTest: if get_cid() returns the host -# address or the "any" address, use the local communication address -# (loopback): VMADDR_CID_LOCAL. -# -# On Linux 6.9, apparently, the /dev/vsock device is now available but -# get_cid() returns VMADDR_CID_ANY (-1). -Patch438: 00438-fix-threadedvsocksocketstreamtest-gh-119465-gh-119479-119484.patch - -# 00450 # 4ab8663661748eb994c09e4ae89f59eb84c5d3ea -# CVE-2025-0938: Disallow square brackets ([ and ]) in domain names for parsed URLs -Patch450: 00450-cve-2025-0938-disallow-square-brackets-and-in-domain-names-for-parsed-urls.patch - # 00452 # eb11d070c5af7d1b5e47f4e02186152d08eaf793 # Properly apply exported CFLAGS for dtrace/systemtap builds # @@ -1860,6 +1845,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Apr 09 2025 Tomáš Hrnčiar - 3.9.22-1 +- Update to 3.9.22 + * Mon Mar 31 2025 Charalampos Stratakis - 3.9.21-5 - Properly apply exported CFLAGS for dtrace/systemtap builds - Fixes: rhbz#2356304 diff --git a/sources b/sources index 0fce215..8dcd229 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.21.tar.xz) = cc84c967cd7a05361ec144d87ca044bd416032ee92dfb78658758d4e1274971f5fb288876d9c599a729bb21258974a786089341bce6bdcffd9c30ebd69b7ca58 -SHA512 (Python-3.9.21.tar.xz.asc) = 1e5e5a5db8074a7ee5eb51e6c789d6e46467165d72d2d636d1fc0d3e15d4355051f9f7ad3063ba43b37b611095765c9d654ed890067c201c087da1eecb620ef9 +SHA512 (Python-3.9.22.tar.xz) = c5a76c579455626bf40bb41ee99cab6e444aa5d5085dab7cf622c70ded750e31710c2c30f032917f0d4069350c01a889ed9831d77fcc2d52fcec54055dd07496 +SHA512 (Python-3.9.22.tar.xz.asc) = 9a04fcf7d7fc0521873d29efad3a80a9ff63df4fc4fe4108059246db6517b22d967f4d4e0eebb32c79417f66ee3b60fe00428be155fc1cbea163aa36c1a3ddee From d5085b58ccf5b13f7e69aa5a6af25c1c489b74d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Thu, 17 Apr 2025 11:37:56 +0200 Subject: [PATCH 78/89] Regenerate patches with updated importpatches script --- 00001-rpath.patch | 5 +++-- 00111-no-static-lib.patch | 2 +- 00189-use-rpm-wheels.patch | 4 ++-- 00251-change-user-install-location.patch | 6 +++--- 00353-architecture-names-upstream-downstream.patch | 2 +- ...ng-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch | 6 +++--- ...arning-in-configure-check-for-pthread_scope_system.patch | 4 ++-- ...-apply-exported-cflags-for-dtrace-systemtap-builds.patch | 3 +-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/00001-rpath.patch b/00001-rpath.patch index 778c077..58e0d8f 100644 --- a/00001-rpath.patch +++ b/00001-rpath.patch @@ -1,8 +1,9 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 13 Jan 2010 21:25:18 +0000 -Subject: [PATCH] 00001: Fixup distutils/unixccompiler.py to remove standard - library path from rpath Was Patch0 in ivazquez' python3000 specfile +Subject: =?UTF-8?q?00001:=20Fixup=20distutils/unixccompiler.py=20to=20remo?= + =?UTF-8?q?ve=20standard=20library=20path=20from=20rpath=0AWas=20Patch0=20?= + =?UTF-8?q?in=20ivazquez'=20python3000=20specfile?= --- Lib/distutils/unixccompiler.py | 9 +++++++++ diff --git a/00111-no-static-lib.patch b/00111-no-static-lib.patch index 37966be..bdabed8 100644 --- a/00111-no-static-lib.patch +++ b/00111-no-static-lib.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 18 Jan 2010 17:59:07 +0000 -Subject: [PATCH] 00111: Don't try to build a libpythonMAJOR.MINOR.a +Subject: 00111: Don't try to build a libpythonMAJOR.MINOR.a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index dfb47f4..d2aa096 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 15 Aug 2018 15:36:29 +0200 -Subject: [PATCH] 00189: Instead of bundled wheels, use our RPM packaged wheels +Subject: 00189: Instead of bundled wheels, use our RPM packaged wheels We keep them in /usr/share/python-wheels @@ -21,7 +21,7 @@ index 07065c3cb7..77d7ec5a65 100644 import os import os.path import sys -@@ -6,13 +8,29 @@ import tempfile +@@ -6,13 +8,29 @@ import subprocess from importlib import resources diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index f961419..24c4fcc 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Michal Cyprian Date: Mon, 26 Jun 2017 16:32:56 +0200 -Subject: [PATCH] 00251: Change user install location +Subject: 00251: Change user install location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -47,7 +47,7 @@ index aaa300efa9..18f01f10d4 100644 def initialize_options(self): """Initializes options.""" -@@ -419,8 +422,10 @@ class install(Command): +@@ -419,8 +422,10 @@ def finalize_unix(self): raise DistutilsOptionError( "must not supply exec-prefix without prefix") @@ -84,7 +84,7 @@ diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index e3f79bfde5..e124104876 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py -@@ -86,6 +86,23 @@ _INSTALL_SCHEMES = { +@@ -86,6 +86,23 @@ }, } diff --git a/00353-architecture-names-upstream-downstream.patch b/00353-architecture-names-upstream-downstream.patch index b0b955c..343ff96 100644 --- a/00353-architecture-names-upstream-downstream.patch +++ b/00353-architecture-names-upstream-downstream.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Tue, 4 Aug 2020 12:04:03 +0200 -Subject: [PATCH] 00353: Original names for architectures with different names +Subject: 00353: Original names for architectures with different names downstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch index c089771..b32ff14 100644 --- a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -1,8 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Fri, 19 Nov 2021 13:37:16 +0100 -Subject: [PATCH] 00371: Revert "bpo-1596321: Fix threading._shutdown() for the - main thread (GH-28549) (GH-28589)" +Subject: 00371: Revert "bpo-1596321: Fix threading._shutdown() for the main + thread (GH-28549) (GH-28589)" This reverts commit 94d19f606fa18a1c4d2faca1caf2f470a8ce6d46. It introduced regression causing FreeIPA's tests to fail. @@ -19,7 +19,7 @@ diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index af480b9014..a57085b75d 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py -@@ -814,39 +814,6 @@ class ThreadTests(BaseTestCase): +@@ -814,39 +814,6 @@ def noop(): pass threading.Thread(target=noop).start() # Thread.join() is not called diff --git a/00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch b/00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch index 0c63a32..4df365e 100644 --- a/00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch +++ b/00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-for-pthread_scope_system.patch @@ -1,8 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 6 Nov 2022 22:39:34 +0100 -Subject: [PATCH] 00407: gh-99086: Fix implicit int compiler warning in - configure check for PTHREAD_SCOPE_SYSTEM +Subject: 00407: gh-99086: Fix implicit int compiler warning in configure check + for PTHREAD_SCOPE_SYSTEM Co-authored-by: Sam James --- diff --git a/00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch b/00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch index edcdacb..a8e849e 100644 --- a/00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch +++ b/00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch @@ -2,8 +2,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 31 Mar 2025 20:29:04 +0200 -Subject: [PATCH] 00452: Properly apply exported CFLAGS for dtrace/systemtap - builds +Subject: 00452: Properly apply exported CFLAGS for dtrace/systemtap builds When using --with-dtrace the resulting object file could be missing specific CFLAGS exported by the build system due to the systemtap From 38f74ff6f93d5269fa9c51dac23500daa6773cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 23 Apr 2025 13:44:23 +0200 Subject: [PATCH 79/89] Add RPM Provides for python3.9-libs, python3.9-devel, python3.9-idle, python3.9-tkinter, python3.9-test This is a first step to switch the flatpackage bcond in order to maintain the same structure as Python 3.10+. --- python3.9.spec | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index be59027..e4e1459 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -771,6 +771,16 @@ Requires: tzdata # Other subpackages (like -debug) also need this, but they all depend on -libs. Requires: expat >= 2.6 +# Provides of the subpackages contained in flatpackage +Provides: %{pkgname}-libs = %{version}-%{release} +Provides: %{pkgname}-devel = %{version}-%{release} +Provides: %{pkgname}-idle = %{version}-%{release} +Provides: %{pkgname}-tkinter = %{version}-%{release} +Provides: %{pkgname}-test = %{version}-%{release} +%if %{with debug_build} +Provides: %{pkgname}-debug = %{version}-%{release} +%endif + # The description for the flat package (SRPM and built) %description Python %{pybasever} package for developers. @@ -1845,6 +1855,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Apr 23 2025 Miro Hrončok - 3.9.22-2 +- Add RPM Provides for python3.9-libs, python3.9-devel, python3.9-idle, python3.9-tkinter, python3.9-test + * Wed Apr 09 2025 Tomáš Hrnčiar - 3.9.22-1 - Update to 3.9.22 From ce0a8a4ce5602de1f22e986f5f628cc2f144cee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Wed, 4 Jun 2025 10:01:22 +0200 Subject: [PATCH 80/89] Update to 3.9.23 --- 00001-rpath.patch | 5 ++--- 00189-use-rpm-wheels.patch | 2 +- 00251-change-user-install-location.patch | 4 ++-- ...hutdown-for-the-main-thread-gh-28549-gh-28589.patch | 2 +- python3.9.spec | 10 ++++++---- sources | 4 ++-- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/00001-rpath.patch b/00001-rpath.patch index 58e0d8f..9498516 100644 --- a/00001-rpath.patch +++ b/00001-rpath.patch @@ -1,9 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 13 Jan 2010 21:25:18 +0000 -Subject: =?UTF-8?q?00001:=20Fixup=20distutils/unixccompiler.py=20to=20remo?= - =?UTF-8?q?ve=20standard=20library=20path=20from=20rpath=0AWas=20Patch0=20?= - =?UTF-8?q?in=20ivazquez'=20python3000=20specfile?= +Subject: 00001: Fixup distutils/unixccompiler.py to remove standard library + path from rpath Was Patch0 in ivazquez' python3000 specfile --- Lib/distutils/unixccompiler.py | 9 +++++++++ diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index d2aa096..8e0e55d 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -21,7 +21,7 @@ index 07065c3cb7..77d7ec5a65 100644 import os import os.path import sys -@@ -6,13 +8,29 @@ +@@ -6,13 +8,29 @@ import tempfile import subprocess from importlib import resources diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index 24c4fcc..ecceb6c 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -47,7 +47,7 @@ index aaa300efa9..18f01f10d4 100644 def initialize_options(self): """Initializes options.""" -@@ -419,8 +422,10 @@ def finalize_unix(self): +@@ -419,8 +422,10 @@ class install(Command): raise DistutilsOptionError( "must not supply exec-prefix without prefix") @@ -84,7 +84,7 @@ diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index e3f79bfde5..e124104876 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py -@@ -86,6 +86,23 @@ +@@ -86,6 +86,23 @@ _INSTALL_SCHEMES = { }, } diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch index b32ff14..747e55d 100644 --- a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -19,7 +19,7 @@ diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index af480b9014..a57085b75d 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py -@@ -814,39 +814,6 @@ def noop(): pass +@@ -814,39 +814,6 @@ class ThreadTests(BaseTestCase): threading.Thread(target=noop).start() # Thread.join() is not called diff --git a/python3.9.spec b/python3.9.spec index e4e1459..c4b4a12 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.22 +%global general_version %{pybasever}.23 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python @@ -302,8 +302,7 @@ Source11: idle3.appdata.xml # (Patches taken from github.com/fedora-python/cpython) # 00001 # d06a8853cf4bae9e115f45e1d531d2dc152c5cc8 -# Fixup distutils/unixccompiler.py to remove standard library path from rpath -# Was Patch0 in ivazquez' python3000 specfile +# Fixup distutils/unixccompiler.py to remove standard library path from rpath Was Patch0 in ivazquez' python3000 specfile Patch1: 00001-rpath.patch # 00111 # 93b40d73360053ca68b0aeec33b6a8ca167e33e2 @@ -1855,6 +1854,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Jun 04 2025 Tomáš Hrnčiar - 3.9.23-1 +- Update to 3.9.23 + * Wed Apr 23 2025 Miro Hrončok - 3.9.22-2 - Add RPM Provides for python3.9-libs, python3.9-devel, python3.9-idle, python3.9-tkinter, python3.9-test diff --git a/sources b/sources index 8dcd229..f21fbda 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.22.tar.xz) = c5a76c579455626bf40bb41ee99cab6e444aa5d5085dab7cf622c70ded750e31710c2c30f032917f0d4069350c01a889ed9831d77fcc2d52fcec54055dd07496 -SHA512 (Python-3.9.22.tar.xz.asc) = 9a04fcf7d7fc0521873d29efad3a80a9ff63df4fc4fe4108059246db6517b22d967f4d4e0eebb32c79417f66ee3b60fe00428be155fc1cbea163aa36c1a3ddee +SHA512 (Python-3.9.23.tar.xz) = ad2eb2eebff286a16ad631339bc0890b0686cf5e669d28905a98f96e9b1af6673d255f36bf19e146aa4de8d012587dc6b3193e903718f9cdba4b97041318f418 +SHA512 (Python-3.9.23.tar.xz.asc) = 10187b0df66743308548780f82872d032530f8233f539cf66a2cfbdef1095b760f81f2fcc1759f003cc6f20752be91bdef71e4d821e76a75c0c85df112335698 From 218a51625a9d6323073473bdaa66cbc9f1d02895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 26 Jun 2025 13:15:55 +0200 Subject: [PATCH 81/89] Fixup the patch 1 commit message after the importpatches/exportpatches change This fixes up d5085b58ccf5b13f7e69aa5a6af25c1c489b74d5 + ce0a8a4ce5602de1f22e986f5f628cc2f144cee3. --- 00001-rpath.patch | 3 ++- python3.9.spec | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/00001-rpath.patch b/00001-rpath.patch index 9498516..cd063e5 100644 --- a/00001-rpath.patch +++ b/00001-rpath.patch @@ -2,8 +2,9 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 13 Jan 2010 21:25:18 +0000 Subject: 00001: Fixup distutils/unixccompiler.py to remove standard library - path from rpath Was Patch0 in ivazquez' python3000 specfile + path from rpath +Was Patch0 in ivazquez' python3000 specfile --- Lib/distutils/unixccompiler.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python3.9.spec b/python3.9.spec index c4b4a12..7657374 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -302,7 +302,9 @@ Source11: idle3.appdata.xml # (Patches taken from github.com/fedora-python/cpython) # 00001 # d06a8853cf4bae9e115f45e1d531d2dc152c5cc8 -# Fixup distutils/unixccompiler.py to remove standard library path from rpath Was Patch0 in ivazquez' python3000 specfile +# Fixup distutils/unixccompiler.py to remove standard library path from rpath +# +# Was Patch0 in ivazquez' python3000 specfile Patch1: 00001-rpath.patch # 00111 # 93b40d73360053ca68b0aeec33b6a8ca167e33e2 From 85baa2650da9671e73e794238c803c68934e7a1d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 25 Jul 2025 11:19:42 +0000 Subject: [PATCH 82/89] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- python3.9.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index 7657374..679fa92 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -1856,6 +1856,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jul 25 2025 Fedora Release Engineering - 3.9.23-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Wed Jun 04 2025 Tomáš Hrnčiar - 3.9.23-1 - Update to 3.9.23 From a718540a1c34fc64dbb357b4eb1fb617b46d7107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zachar?= Date: Mon, 28 Jul 2025 13:45:10 +0200 Subject: [PATCH 83/89] Drop STI and use tmt instead Resolves: rhbz#2383062 --- {tests/.fmf => .fmf}/version | 0 plan.fmf | 41 ++++++++++++++++++++++++++++++++++++ tests/provision.fmf | 4 ---- tests/tests.yml | 37 -------------------------------- 4 files changed, 41 insertions(+), 41 deletions(-) rename {tests/.fmf => .fmf}/version (100%) create mode 100644 plan.fmf delete mode 100644 tests/provision.fmf delete mode 100644 tests/tests.yml diff --git a/tests/.fmf/version b/.fmf/version similarity index 100% rename from tests/.fmf/version rename to .fmf/version diff --git a/plan.fmf b/plan.fmf new file mode 100644 index 0000000..ea4635e --- /dev/null +++ b/plan.fmf @@ -0,0 +1,41 @@ +execute: + how: tmt + +provision: + hardware: + memory: '>= 3 GB' + +discover: + - name: tests_python + how: shell + url: https://src.fedoraproject.org/tests/python.git + tests: + - name: smoke + path: /smoke + test: "VERSION=3.9 ./venv.sh" + - name: selftest + path: /selftest + test: VERSION=3.9 X="-x test_wsgiref" ./parallel.sh + - name: marshalparser + path: /marshalparser + test: "VERSION=3.9 SAMPLE=10 ./test_marshalparser_compatibility.sh" + +prepare: + - name: Install dependencies + how: install + package: + - gcc # for extension building in venv and selftest + - gdb # for test_gdb + - python3.9 # the test subject + - python3-tox # for venv tests + - glibc-all-langpacks # for locale tests + - marshalparser # for testing compatibility (magic numbers) with marshalparser + - rpm # for debugging marshalparser + - dnf # for upgrade + - name: Update packages + how: shell + script: dnf upgrade -y + - name: rpm_qa + order: 100 + how: shell + script: rpm -qa | sort | tee $TMT_PLAN_DATA/rpmqa.txt diff --git a/tests/provision.fmf b/tests/provision.fmf deleted file mode 100644 index 1a4f0f0..0000000 --- a/tests/provision.fmf +++ /dev/null @@ -1,4 +0,0 @@ ---- -standard-inventory-qcow2: - qemu: - m: 3G # Amount of VM memory diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 027091f..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -- hosts: localhost - tags: - - classic - tasks: - - dnf: - name: "*" - state: latest - -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - repositories: - - repo: "https://src.fedoraproject.org/tests/python.git" - dest: "python" - tests: - - rpm_qa: - run: rpm -qa - - smoke: - dir: python/smoke - run: VERSION=3.9 ./venv.sh - - selftest: - dir: python/selftest - run: VERSION=3.9 X="-x test_wsgiref" ./parallel.sh - - marshalparser: - dir: python/marshalparser - run: VERSION=3.9 SAMPLE=10 test_marshalparser_compatibility.sh - required_packages: - - gcc # for extension building in venv and selftest - - gdb # for test_gdb - - python3.9 # the test subject - - python3-tox # for venv tests - - glibc-all-langpacks # for locale tests - - marshalparser # for testing compatibility (magic numbers) with marshalparser - - rpm # for debugging From 5d32305ea386e92a9ac1b01d5e8dfd50a9a0d6f9 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Fri, 10 Oct 2025 15:35:04 +0200 Subject: [PATCH 84/89] Update to Python 3.9.24 --- 00189-use-rpm-wheels.patch | 4 ++-- python3.9.spec | 11 +++++++---- sources | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/00189-use-rpm-wheels.patch b/00189-use-rpm-wheels.patch index 8e0e55d..322da15 100644 --- a/00189-use-rpm-wheels.patch +++ b/00189-use-rpm-wheels.patch @@ -12,7 +12,7 @@ We might eventually pursuit upstream support, but it's low prio 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py -index 07065c3cb7..77d7ec5a65 100644 +index d61bb089e3..77d7ec5a65 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -1,3 +1,5 @@ @@ -30,7 +30,7 @@ index 07065c3cb7..77d7ec5a65 100644 __all__ = ["version", "bootstrap"] --_SETUPTOOLS_VERSION = "58.1.0" +-_SETUPTOOLS_VERSION = "79.0.1" -_PIP_VERSION = "23.0.1" + +_WHEEL_DIR = "/usr/share/python-wheels/" diff --git a/python3.9.spec b/python3.9.spec index 679fa92..81fa742 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.23 +%global general_version %{pybasever}.24 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python @@ -315,7 +315,7 @@ Patch1: 00001-rpath.patch # See https://bugzilla.redhat.com/show_bug.cgi?id=556092 Patch111: 00111-no-static-lib.patch -# 00189 # 60517f098bd1525ad454adf7252b60a3d6b0f8ba +# 00189 # 0c6dd5d318a22bbe89e09e1cd5513eaaca549aa5 # Instead of bundled wheels, use our RPM packaged wheels # # We keep them in /usr/share/python-wheels @@ -328,7 +328,7 @@ Patch189: 00189-use-rpm-wheels.patch # When the bundled setuptools/pip wheel is updated, the patch no longer applies cleanly. # In such cases, the patch needs to be amended and the versions updated here: %global pip_version 23.0.1 -%global setuptools_version 58.1.0 +%global setuptools_version 79.0.1 # 00251 # 1b1047c14ff98eae6d355b4aac4df3e388813f62 # Change user install location @@ -1856,6 +1856,9 @@ CheckPython optimized # ====================================================== %changelog +* Fri Oct 10 2025 Karolina Surma - 3.9.24-1 +- Update to Python 3.9.24 + * Fri Jul 25 2025 Fedora Release Engineering - 3.9.23-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index f21fbda..199b8fb 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.23.tar.xz) = ad2eb2eebff286a16ad631339bc0890b0686cf5e669d28905a98f96e9b1af6673d255f36bf19e146aa4de8d012587dc6b3193e903718f9cdba4b97041318f418 -SHA512 (Python-3.9.23.tar.xz.asc) = 10187b0df66743308548780f82872d032530f8233f539cf66a2cfbdef1095b760f81f2fcc1759f003cc6f20752be91bdef71e4d821e76a75c0c85df112335698 +SHA512 (Python-3.9.24.tar.xz) = 54be1c0805e66aa68b4c71e07a4234176203868ecdb6dfdc1859b04b95858bde26990dd1c5ac1001ce4b55513c05cd63310155c6c6666707e27fb79c159870bb +SHA512 (Python-3.9.24.tar.xz.asc) = 50459b5a540e5e699ee2dffd8988369c0a15bd00cfa76d8b148ea7ad648205b8454521bd0a30dc39d6497b0ebcb85a037aedd56d8188c854d1d4409859aeead2 From 7a81f94ccc77cd2dcfb42df17d881e53bb5da3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 6 Oct 2025 23:53:41 +0200 Subject: [PATCH 85/89] On Fedora 44+, split this package into multiple subpackages python3.9 and python3.6 are the only remaining Pythons that are "flatpackaged". As they are likely to stay around for a while, it makes no sense to wait this out (like we did with e.g. 3.7 and 3.8). This (together with similar change in python3.6) will make all the packaged Pythons packaged in the same way. Additionally, this also enables the debug build, which was added to CI. --- plan.fmf | 17 +++++++++++++---- python3.9.spec | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/plan.fmf b/plan.fmf index ea4635e..f5f58a3 100644 --- a/plan.fmf +++ b/plan.fmf @@ -5,6 +5,9 @@ provision: hardware: memory: '>= 3 GB' +environment: + pybasever: '3.9' + discover: - name: tests_python how: shell @@ -12,13 +15,16 @@ discover: tests: - name: smoke path: /smoke - test: "VERSION=3.9 ./venv.sh" + test: "VERSION=${pybasever} ./venv.sh" + - name: debugsmoke + path: /smoke + test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} INSTALL_OR_SKIP=true ./venv.sh" - name: selftest path: /selftest - test: VERSION=3.9 X="-x test_wsgiref" ./parallel.sh + test: VERSION=${pybasever} X="-x test_wsgiref" ./parallel.sh - name: marshalparser path: /marshalparser - test: "VERSION=3.9 SAMPLE=10 ./test_marshalparser_compatibility.sh" + test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh" prepare: - name: Install dependencies @@ -26,7 +32,10 @@ prepare: package: - gcc # for extension building in venv and selftest - gdb # for test_gdb - - python3.9 # the test subject + - "python${pybasever}" # the test subject + - "python${pybasever}-devel" # for extension building in venv and selftest + - "python${pybasever}-tkinter" # for selftest + - "python${pybasever}-test" # for selftest - python3-tox # for venv tests - glibc-all-langpacks # for locale tests - marshalparser # for testing compatibility (magic numbers) with marshalparser diff --git a/python3.9.spec b/python3.9.spec index 81fa742..c25eab2 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -40,9 +40,10 @@ License: Python %endif # Flat package, i.e. no separate subpackages -# Default (in Fedora): if this is a main Python, it is not a flatpackage +# Default (in Fedora >= 44): disabled +# Default (in Fedora < 44): enabled when this is not the main Python # Not supported: Combination of flatpackage enabled and main_python enabled -%if %{with main_python} +%if %{with main_python} || 0%{?fedora} >= 44 %bcond_with flatpackage %else %bcond_without flatpackage @@ -467,9 +468,18 @@ Obsoletes: platform-python < %{pybasever} Provides: python%{pyshortver} = %{version}-%{release} Obsoletes: python%{pyshortver} < %{version}-%{release} +# https://docs.fedoraproject.org/en-US/packaging-guidelines/#_one_to_many_replacement +Obsoletes: %{pkgname} < 3.9.24-2 + +%if %{with main_python} # Packages with Python modules in standard locations automatically # depend on python(abi). Provide that here. Provides: python(abi) = %{pybasever} +%else +# We exclude the `python(abi)` Provides +%global __requires_exclude ^python\\(abi\\) = 3\\..+ +%global __provides_exclude ^python\\(abi\\) = 3\\..+ +%endif Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} @@ -584,6 +594,8 @@ Conflicts: python-libs < 3 # (We explicitly conflict with python-libs and not python2-libs, so only the # old Python 2 builds that still provided unversioned Python are handled.) +# https://docs.fedoraproject.org/en-US/packaging-guidelines/#_one_to_many_replacement +Obsoletes: %{pkgname} < 3.9.24-2 %description -n %{pkgname}-libs This package contains runtime libraries for use by Python: @@ -603,6 +615,7 @@ Requires: (python3-rpm-macros if rpm-build) Requires: (pyproject-rpm-macros if rpm-build) %if %{without bootstrap} +%if %{with main_python} # This is not "API" (packages that need setuptools should still BuildRequire it) # However some packages apparently can build both with and without setuptools # producing egg-info as file or directory (depending on setuptools presence). @@ -611,6 +624,7 @@ Requires: (pyproject-rpm-macros if rpm-build) # See https://bugzilla.redhat.com/show_bug.cgi?id=1623914 # See https://fedoraproject.org/wiki/Packaging:Directory_Replacement Requires: (%{pkgname}-setuptools if rpm-build) +%endif Requires: (python3-rpm-generators if rpm-build) %endif @@ -630,6 +644,9 @@ Provides: platform-python-devel%{?_isa} = %{version}-%{release} Obsoletes: platform-python-devel < %{pybasever} %endif +# https://docs.fedoraproject.org/en-US/packaging-guidelines/#_one_to_many_replacement +Obsoletes: %{pkgname} < 3.9.24-2 + %description -n %{pkgname}-devel This package contains the header files and configuration needed to compile Python extension modules (typically written in C or C++), to embed Python @@ -654,6 +671,9 @@ Obsoletes: %{pkgname}-tools < %{version}-%{release} # In Fedora 31, /usr/bin/idle was moved here from Python 2. Conflicts: python-tools < 3 +# https://docs.fedoraproject.org/en-US/packaging-guidelines/#_one_to_many_replacement +Obsoletes: %{pkgname} < 3.9.24-2 + %description -n %{pkgname}-idle IDLE is Python’s Integrated Development and Learning Environment. @@ -675,6 +695,9 @@ Requires: %{pkgname} = %{version}-%{release} # (We don't provide python3-turtledemo, that's not too useful when imported.) %py_provides %{pkgname}-turtle +# https://docs.fedoraproject.org/en-US/packaging-guidelines/#_one_to_many_replacement +Obsoletes: %{pkgname} < 3.9.24-2 + %description -n %{pkgname}-tkinter The Tkinter (Tk interface) library is a graphical user interface toolkit for the Python programming language. @@ -685,6 +708,9 @@ Summary: The self-test suite for the main python3 package Requires: %{pkgname} = %{version}-%{release} Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} +# https://docs.fedoraproject.org/en-US/packaging-guidelines/#_one_to_many_replacement +Obsoletes: %{pkgname} < 3.9.24-2 + %description -n %{pkgname}-test The self-test suite for the Python interpreter. @@ -735,11 +761,6 @@ The debug runtime additionally supports debug builds of C-API extensions %else # with flatpackage -# We'll not provide this, on purpose -# No package in Fedora shall ever depend on flatpackage via this -%global __requires_exclude ^python\\(abi\\) = 3\\..$ -%global __provides_exclude ^python\\(abi\\) = 3\\..$ - # Python interpreter packages used to be named (or provide) name pythonXY (e.g. # python39). However, to align it with the executable names and to prepare for # Python 3.10, they were renamed to pythonX.Y (e.g. python3.9, python3.10). We @@ -1856,6 +1877,10 @@ CheckPython optimized # ====================================================== %changelog +* Wed Oct 15 2025 Miro Hrončok - 3.9.24-2 +- On Fedora 44+, split this package into multiple subpackages +- This mimics newer Python versions + * Fri Oct 10 2025 Karolina Surma - 3.9.24-1 - Update to Python 3.9.24 From 849638dd21aac3e541aaa78077aeefc9b72353b0 Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Mon, 3 Nov 2025 09:30:56 +0100 Subject: [PATCH 86/89] Update to Python 3.9.25 --- python3.9.spec | 7 +++++-- sources | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/python3.9.spec b/python3.9.spec index c25eab2..d1de4aa 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.24 +%global general_version %{pybasever}.25 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python @@ -1877,6 +1877,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Nov 03 2025 Karolina Surma - 3.9.25-1 +- Update to Python 3.9.25 + * Wed Oct 15 2025 Miro Hrončok - 3.9.24-2 - On Fedora 44+, split this package into multiple subpackages - This mimics newer Python versions diff --git a/sources b/sources index 199b8fb..8a5f37e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.9.24.tar.xz) = 54be1c0805e66aa68b4c71e07a4234176203868ecdb6dfdc1859b04b95858bde26990dd1c5ac1001ce4b55513c05cd63310155c6c6666707e27fb79c159870bb -SHA512 (Python-3.9.24.tar.xz.asc) = 50459b5a540e5e699ee2dffd8988369c0a15bd00cfa76d8b148ea7ad648205b8454521bd0a30dc39d6497b0ebcb85a037aedd56d8188c854d1d4409859aeead2 +SHA512 (Python-3.9.25.tar.xz) = 33fd65952cc3ce5df83825aa32a103935815bdd5a016e5fd9896cafb068a3f89b3a6134458a2694e4f0f4f8a9fbe84739b53116264728b32cde0f03ab210cb19 +SHA512 (Python-3.9.25.tar.xz.asc) = 83f0a0e558aa89a106bdffeeb9b0fa2685fbd7be5c5954f9176c59c6c7023716207b07239f202b3508cbb98ca34572161955f0bfd3732fdb9265721cd6723dbe From d76398c8f94be7ab2d44a3f6c78d10d3fac5dec6 Mon Sep 17 00:00:00 2001 From: Tomas Orsava Date: Fri, 29 Apr 2022 10:24:01 +0000 Subject: [PATCH 87/89] Move _sysconfigdata_d_linux*.py to the debug subpackage (cherry picked from python3.10 commit 55d25b67d6153038b462d312e40c083d965ed5dc) --- python3.9.spec | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/python3.9.spec b/python3.9.spec index d1de4aa..a29ebac 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} License: Python @@ -1526,6 +1526,10 @@ CheckPython optimized %dir %{pylibdir}/site-packages/ %dir %{pylibdir}/site-packages/__pycache__/ %{pylibdir}/site-packages/README.txt + +%exclude %{pylibdir}/_sysconfigdata_d_linux_%{platform_triplet}.py +%exclude %{pylibdir}/__pycache__/_sysconfigdata_d_linux_%{platform_triplet}%{bytecode_suffixes} + %{pylibdir}/*.py %dir %{pylibdir}/__pycache__/ %{pylibdir}/__pycache__/*%{bytecode_suffixes} @@ -1854,6 +1858,9 @@ CheckPython optimized %{dynload_dir}/_testinternalcapi.%{SOABI_debug}.so %{dynload_dir}/_testmultiphase.%{SOABI_debug}.so +%{pylibdir}/_sysconfigdata_d_linux_%{platform_triplet}.py +%{pylibdir}/__pycache__/_sysconfigdata_d_linux_%{platform_triplet}%{bytecode_suffixes} + %endif # with debug_build # We put the debug-gdb.py file inside /usr/lib/debug to avoid noise from ldconfig @@ -1877,6 +1884,9 @@ CheckPython optimized # ====================================================== %changelog +* Mon Nov 10 2025 Tomas Orsava - 3.9.25-2 +- Move _sysconfigdata_d_linux*.py to the debug subpackage + * Mon Nov 03 2025 Karolina Surma - 3.9.25-1 - Update to Python 3.9.25 From 300b96687aee3b2c6c3397b09f85e9f4cfb9e5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 5 Sep 2025 11:30:22 +0000 Subject: [PATCH 88/89] Inject SBOM into the installed wheels (when using the bundled ones) --- python3.9.spec | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python3.9.spec b/python3.9.spec index a29ebac..97d3fe0 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -272,6 +272,9 @@ BuildRequires: /usr/sbin/ifconfig %if %{with rpmwheels} BuildRequires: python-setuptools-wheel BuildRequires: python-pip-wheel +%else +# For %%python_wheel_inject_sbom +BuildRequires: python-rpm-macros %endif %if %{without bootstrap} @@ -1259,6 +1262,11 @@ for file in %{buildroot}%{pylibdir}/pydoc_data/topics.py $(grep --include='*.py' rm ${directory}/{__pycache__/${module}.cpython-%{pyshortver}.opt-?.pyc,${module}.py} done +%if %{without rpmwheels} +# Inject SBOM into the installed wheels (if the macro is available) +%{?python_wheel_inject_sbom:%python_wheel_inject_sbom %{buildroot}%{pylibdir}/ensurepip/_bundled/*.whl} +%endif + # ====================================================== # Checks for packaging issues # ====================================================== From f82d8070ea81e7e847da888075b4e309f054b0d3 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Wed, 14 Jan 2026 07:09:06 +0100 Subject: [PATCH 89/89] Security fix for CVE-2025-12084 --- 00471-cve-2025-12084.patch | 140 +++++++++++++++++++++++++++++++++++++ python3.9.spec | 12 +++- 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 00471-cve-2025-12084.patch diff --git a/00471-cve-2025-12084.patch b/00471-cve-2025-12084.patch new file mode 100644 index 0000000..78c49fd --- /dev/null +++ b/00471-cve-2025-12084.patch @@ -0,0 +1,140 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Mon, 22 Dec 2025 14:48:49 +0100 +Subject: 00471: CVE-2025-12084 + +* gh-142145: Remove quadratic behavior in node ID cache clearing (GH-142146) +* gh-142754: Ensure that Element & Attr instances have the ownerDocument attribute (GH-142794) +(cherry picked from commit 1cc7551b3f9f71efbc88d96dce90f82de98b2454) +(cherry picked from commit 08d8e18ad81cd45bc4a27d6da478b51ea49486e4) +(cherry picked from commit 8d2d7bb2e754f8649a68ce4116271a4932f76907) + +Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com> +Co-authored-by: Seth Michael Larson +Co-authored-by: Petr Viktorin +Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> +Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com> +Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> +Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com> +Co-authored-by: Gregory P. Smith +--- + Lib/test/test_minidom.py | 33 ++++++++++++++++++- + Lib/xml/dom/minidom.py | 11 ++----- + ...-12-01-09-36-45.gh-issue-142145.tcAUhg.rst | 6 ++++ + 3 files changed, 41 insertions(+), 9 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst + +diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py +index 97620258d8..9f7f5b240e 100644 +--- a/Lib/test/test_minidom.py ++++ b/Lib/test/test_minidom.py +@@ -2,6 +2,7 @@ + + import copy + import pickle ++import time + import io + from test import support + import unittest +@@ -9,7 +10,7 @@ import unittest + import pyexpat + import xml.dom.minidom + +-from xml.dom.minidom import parse, Node, Document, parseString ++from xml.dom.minidom import parse, Attr, Node, Document, Element, parseString + from xml.dom.minidom import getDOMImplementation + from xml.parsers.expat import ExpatError + +@@ -163,6 +164,36 @@ class MinidomTest(unittest.TestCase): + self.confirm(dom.documentElement.childNodes[-1].data == "Hello") + dom.unlink() + ++ @support.requires_resource('cpu') ++ def testAppendChildNoQuadraticComplexity(self): ++ impl = getDOMImplementation() ++ ++ newdoc = impl.createDocument(None, "some_tag", None) ++ top_element = newdoc.documentElement ++ children = [newdoc.createElement(f"child-{i}") for i in range(1, 2 ** 15 + 1)] ++ element = top_element ++ ++ start = time.monotonic() ++ for child in children: ++ element.appendChild(child) ++ element = child ++ end = time.monotonic() ++ ++ # This example used to take at least 30 seconds. ++ # Conservative assertion due to the wide variety of systems and ++ # build configs timing based tests wind up run under. ++ # A --with-address-sanitizer --with-pydebug build on a rpi5 still ++ # completes this loop in <0.5 seconds. ++ self.assertLess(end - start, 4) ++ ++ def testSetAttributeNodeWithoutOwnerDocument(self): ++ # regression test for gh-142754 ++ elem = Element("test") ++ attr = Attr("id") ++ attr.value = "test-id" ++ elem.setAttributeNode(attr) ++ self.assertEqual(elem.getAttribute("id"), "test-id") ++ + def testAppendChildFragment(self): + dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes() + dom.documentElement.appendChild(frag) +diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py +index d09ef5e7d0..e4e8b42996 100644 +--- a/Lib/xml/dom/minidom.py ++++ b/Lib/xml/dom/minidom.py +@@ -292,13 +292,6 @@ def _append_child(self, node): + childNodes.append(node) + node.parentNode = self + +-def _in_document(node): +- # return True iff node is part of a document tree +- while node is not None: +- if node.nodeType == Node.DOCUMENT_NODE: +- return True +- node = node.parentNode +- return False + + def _write_data(writer, data): + "Writes datachars to writer." +@@ -355,6 +348,7 @@ class Attr(Node): + def __init__(self, qName, namespaceURI=EMPTY_NAMESPACE, localName=None, + prefix=None): + self.ownerElement = None ++ self.ownerDocument = None + self._name = qName + self.namespaceURI = namespaceURI + self._prefix = prefix +@@ -678,6 +672,7 @@ class Element(Node): + + def __init__(self, tagName, namespaceURI=EMPTY_NAMESPACE, prefix=None, + localName=None): ++ self.ownerDocument = None + self.parentNode = None + self.tagName = self.nodeName = tagName + self.prefix = prefix +@@ -1537,7 +1532,7 @@ def _clear_id_cache(node): + if node.nodeType == Node.DOCUMENT_NODE: + node._id_cache.clear() + node._id_search_stack = None +- elif _in_document(node): ++ elif node.ownerDocument: + node.ownerDocument._id_cache.clear() + node.ownerDocument._id_search_stack= None + +diff --git a/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst b/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst +new file mode 100644 +index 0000000000..05c7df35d1 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst +@@ -0,0 +1,6 @@ ++Remove quadratic behavior in ``xml.minidom`` node ID cache clearing. In order ++to do this without breaking existing users, we also add the *ownerDocument* ++attribute to :mod:`xml.dom.minidom` elements and attributes created by directly ++instantiating the ``Element`` or ``Attr`` class. Note that this way of creating ++nodes is not supported; creator functions like ++:py:meth:`xml.dom.Document.documentElement` should be used instead. diff --git a/python3.9.spec b/python3.9.spec index 97d3fe0..751cd07 100644 --- a/python3.9.spec +++ b/python3.9.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 3%{?dist} License: Python @@ -403,6 +403,13 @@ Patch407: 00407-gh-99086-fix-implicit-int-compiler-warning-in-configure-check-fo # even when cross-compiling. Patch452: 00452-properly-apply-exported-cflags-for-dtrace-systemtap-builds.patch +# 00471 # fc5f344f7e15c13dbf41824a1b7a82d92205f79d +# CVE-2025-12084 +# +# * gh-142145: Remove quadratic behavior in node ID cache clearing (GH-142146) +# * gh-142754: Ensure that Element & Attr instances have the ownerDocument attribute (GH-142794) +Patch471: 00471-cve-2025-12084.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1892,6 +1899,9 @@ CheckPython optimized # ====================================================== %changelog +* Wed Jan 14 2026 Lumír Balhar - 3.9.25-3 +- Security fix for CVE-2025-12084 + * Mon Nov 10 2025 Tomas Orsava - 3.9.25-2 - Move _sysconfigdata_d_linux*.py to the debug subpackage