diff --git a/backport-CVE-2025-59042.patch b/backport-CVE-2025-59042.patch new file mode 100644 index 0000000000000000000000000000000000000000..01fbc1a1f888c6e57fc2f9ee62923f3dce3a25f9 --- /dev/null +++ b/backport-CVE-2025-59042.patch @@ -0,0 +1,604 @@ +From f5adf291c8b832d5aff7632844f7e3ddf7ad4923 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Br=C3=A9nainn=20Woodsend?= +Date: Thu, 28 Jul 2022 22:10:42 +0100 +Subject: [PATCH] Remove the --key/cipher bytecode encryption. + +Bytecode encryption, given that the decryption key has to be stored somewhere in +the built application for the application to be able to function, was only ever +a mild deterrent against prying eyes. It could be cracked by anyone willing to +dig around PyInstaller's source code for the exact layout of the executable +archive and a quick hexdump to get the key once you know where to look. + +These days however, PyInstaller reverse engineering tools like PyExtractor have +this all built in. For example, in the steps below, our would be prying user +doesn't even need to know that the application they are trying to break open is +encrypted, let alone have to do anything clever to decrypt it. + + git clone https://github.com/Rdimo/PyExtractor.git + cd PyExtractor + pip install -r requirements.txt + python main.py some/pyinstaller/application + +So since the knowledge barrier to reverse engineer an encrypted build is now +identical to that of a regular one, and because users are being misled into +thinking that an encrypted PyInstaller build is a safe place to put things like +API keys, and since adding further code obfuscation will eventually lead to the +same outcome, remove the encryption feature entirely. + +Users looking for a replacement should look for code obfuscation methods that +don't require lossless de-obfuscation at runtime in order for the code to be +runable. This means PyArmour or any DIY bytecode encryption scheme should be +avoided for the same reasons that this feature is being dropped. Instead, you +can use pyminifier's obfuscation feature which mangles variable names or if (and +only if) you understand the perils of Linux ABI compatibility, are aware of the +macOS deployment target and understand that PyInstaller can't detect imports +made by C extensions (i.e. you will need to use +--hidden-import/--collect-submodules a lot) then you may consider running Cython +on the more confidential Python files in your project. + +Origin: https://github.com/pyinstaller/pyinstaller/commit/f5adf291c8b832d5aff7632844f7e3ddf7ad4923 +--- + PyInstaller/archive/pyz_crypto.py | 36 ++------------------- + PyInstaller/archive/writers.py | 12 ++----- + PyInstaller/building/api.py | 18 ++++------- + PyInstaller/building/build_main.py | 20 +++--------- + PyInstaller/building/makespec.py | 32 +++--------------- + PyInstaller/building/templates.py | 16 ++------- + PyInstaller/exceptions.py | 6 ++++ + PyInstaller/loader/pyimod01_archive.py | 45 -------------------------- + doc/spec-files.rst | 7 ++-- + news/6999.breaking.rst | 1 + + setup.cfg | 2 -- + tests/functional/test_basic.py | 32 ------------------ + tests/requirements-tools.txt | 3 -- + 13 files changed, 32 insertions(+), 198 deletions(-) + create mode 100644 news/6999.breaking.rst + +diff --git a/PyInstaller/archive/pyz_crypto.py b/PyInstaller/archive/pyz_crypto.py +index 530469a..a16905f 100755 +--- a/PyInstaller/archive/pyz_crypto.py ++++ b/PyInstaller/archive/pyz_crypto.py +@@ -9,40 +9,8 @@ + # SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception) + #----------------------------------------------------------------------------- + +-import os +- +-from PyInstaller import log as logging +- +-BLOCK_SIZE = 16 +-logger = logging.getLogger(__name__) +- + + class PyiBlockCipher: +- """ +- This class is used only to encrypt Python modules. +- """ + def __init__(self, key=None): +- logger.log( +- logging.DEPRECATION, +- "Bytecode encryption will be removed in PyInstaller v6. Please remove cipher and block_cipher parameters " +- "from your spec file to avoid breakages on upgrade. For the rationale/alternatives see " +- "https://github.com/pyinstaller/pyinstaller/pull/6999" +- ) +- assert type(key) is str +- if len(key) > BLOCK_SIZE: +- self.key = key[0:BLOCK_SIZE] +- else: +- self.key = key.zfill(BLOCK_SIZE) +- assert len(self.key) == BLOCK_SIZE +- +- import tinyaes +- self._aesmod = tinyaes +- +- def encrypt(self, data): +- iv = os.urandom(BLOCK_SIZE) +- return iv + self.__create_cipher(iv).CTR_xcrypt_buffer(data) +- +- def __create_cipher(self, iv): +- # The 'AES' class is stateful, and this factory method is used to re-initialize the block cipher class with +- # each call to xcrypt(). +- return self._aesmod.AES(self.key.encode(), iv) ++ from PyInstaller.exceptions import RemovedCipherFeatureError ++ raise RemovedCipherFeatureError("Please remove cipher and block_cipher parameters from your spec file.") +diff --git a/PyInstaller/archive/writers.py b/PyInstaller/archive/writers.py +index 642ee07..f01f810 100755 +--- a/PyInstaller/archive/writers.py ++++ b/PyInstaller/archive/writers.py +@@ -33,7 +33,7 @@ class ZlibArchiveWriter: + _HEADER_LENGTH = 12 + 5 + _COMPRESSION_LEVEL = 6 # zlib compression level + +- def __init__(self, filename, entries, code_dict=None, cipher=None): ++ def __init__(self, filename, entries, code_dict=None): + """ + filename + Target filename of the archive. +@@ -44,8 +44,6 @@ def __init__(self, filename, entries, code_dict=None, cipher=None): + `DATA`). + code_dict + Optional code dictionary containing code objects for analyzed/collected python modules. +- cipher +- Optional `Cipher` object for bytecode encryption. + """ + code_dict = code_dict or {} + +@@ -56,7 +54,7 @@ def __init__(self, filename, entries, code_dict=None, cipher=None): + # Write entries' data and collect TOC entries + toc = [] + for entry in entries: +- toc_entry = self._write_entry(fp, entry, code_dict, cipher) ++ toc_entry = self._write_entry(fp, entry, code_dict) + toc.append(toc_entry) + + # Write TOC +@@ -68,17 +66,15 @@ def __init__(self, filename, entries, code_dict=None, cipher=None): + # - PYZ magic pattern (4 bytes) + # - python bytecode magic pattern (4 bytes) + # - TOC offset (32-bit int, 4 bytes) +- # - encryption flag (1 byte) + # - 4 unused bytes + fp.seek(0, os.SEEK_SET) + + fp.write(self._PYZ_MAGIC_PATTERN) + fp.write(BYTECODE_MAGIC) + fp.write(struct.pack('!i', toc_offset)) +- fp.write(struct.pack('!B', cipher is not None)) + + @classmethod +- def _write_entry(cls, fp, entry, code_dict, cipher): ++ def _write_entry(cls, fp, entry, code_dict): + name, src_path, typecode = entry + + if typecode == 'PYMODULE': +@@ -102,8 +98,6 @@ def _write_entry(cls, fp, entry, code_dict, cipher): + + # First compress, then encrypt. + obj = zlib.compress(data, cls._COMPRESSION_LEVEL) +- if cipher: +- obj = cipher.encrypt(obj) + + # Create TOC entry + toc_entry = (name, (typecode, fp.tell(), len(obj))) +diff --git a/PyInstaller/building/api.py b/PyInstaller/building/api.py +index 1e1995b..2e205a7 100755 +--- a/PyInstaller/building/api.py ++++ b/PyInstaller/building/api.py +@@ -61,16 +61,18 @@ def __init__(self, *tocs, **kwargs): + + name + A filename for the .pyz. Normally not needed, as the generated name will do fine. +- cipher +- The block cipher that will be used to encrypt Python bytecode. + """ ++ if kwargs.get("cipher"): ++ from PyInstaller.exceptions import RemovedCipherFeatureError ++ raise RemovedCipherFeatureError( ++ "Please remove the 'cipher' arguments to PYZ() and Analysis() in your spec file." ++ ) + + from PyInstaller.config import CONF + + super().__init__() + + name = kwargs.get('name', None) +- cipher = kwargs.get('cipher', None) + + self.name = name + if name is None: +@@ -79,14 +81,6 @@ def __init__(self, *tocs, **kwargs): + # PyInstaller bootstrapping modules. + bootstrap_dependencies = get_bootstrap_modules() + +- # Bundle the crypto key. +- self.cipher = cipher +- if cipher: +- key_file = ('pyimod00_crypto_key', os.path.join(CONF['workpath'], 'pyimod00_crypto_key.py'), 'PYMODULE') +- # Insert the key as the first module in the list. The key module contains just variables and does not depend +- # on other modules. +- bootstrap_dependencies.insert(0, key_file) +- + # Compile the python modules that are part of bootstrap dependencies, so that they can be collected into the + # CArchive and imported by the bootstrap script. + self.dependencies = [] +@@ -156,7 +150,7 @@ def assemble(self): + self.code_dict = {name: strip_paths_in_code(code) for name, code in self.code_dict.items()} + + # Create the archive +- ZlibArchiveWriter(self.name, archive_toc, code_dict=self.code_dict, cipher=self.cipher) ++ ZlibArchiveWriter(self.name, archive_toc, code_dict=self.code_dict) + logger.info("Building PYZ (ZlibArchive) %s completed successfully.", self.name) + + +diff --git a/PyInstaller/building/build_main.py b/PyInstaller/building/build_main.py +index 8e4e247..ba5ecfc 100755 +--- a/PyInstaller/building/build_main.py ++++ b/PyInstaller/building/build_main.py +@@ -24,7 +24,6 @@ + + from PyInstaller import DEFAULT_DISTPATH, DEFAULT_WORKPATH, HOMEPATH, compat + from PyInstaller import log as logging +-from PyInstaller.archive import pyz_crypto + from PyInstaller.building.api import COLLECT, EXE, MERGE, PYZ + from PyInstaller.building.datastruct import TOC, Target, Tree, _check_guts_eq, normalize_toc, normalize_pyz_toc + from PyInstaller.building.osx import BUNDLE +@@ -307,8 +306,6 @@ def __init__( + ignored (as though they were not found). + runtime_hooks + An optional list of scripts to use as users' runtime hooks. Specified as file names. +- cipher +- Add optional instance of the pyz_crypto.PyiBlockCipher class (with a provided key). + win_no_prefer_redirects + If True, prefer not to follow version redirects when searching for Windows SxS Assemblies. + win_private_assemblies +@@ -319,6 +316,11 @@ def __init__( + An optional dict of package/module names and collection mode strings. Valid collection mode strings: + 'pyz' (default), 'pyc', 'py', 'pyz+py' (or 'py+pyz') + """ ++ if cipher is not None: ++ from PyInstaller.exceptions import RemovedCipherFeatureError ++ raise RemovedCipherFeatureError( ++ "Please remove the 'cipher' arguments to PYZ() and Analysis() in your spec file." ++ ) + super().__init__() + from PyInstaller.config import CONF + +@@ -379,15 +381,6 @@ def __init__( + # Custom runtime hook files that should be included and started before any existing PyInstaller runtime hooks. + self.custom_runtime_hooks = runtime_hooks or [] + +- if cipher: +- logger.info('Will encrypt Python bytecode with provided cipher key') +- # Create a Python module which contains the decryption key which will be used at runtime by +- # pyi_crypto.PyiBlockCipher. +- pyi_crypto_key_path = os.path.join(CONF['workpath'], 'pyimod00_crypto_key.py') +- with open(pyi_crypto_key_path, 'w', encoding='utf-8') as f: +- f.write('# -*- coding: utf-8 -*-\nkey = %r\n' % cipher.key) +- self.hiddenimports.append('tinyaes') +- + self._input_binaries = [] + self._input_datas = [] + +@@ -444,8 +437,6 @@ def __init__( + ('_input_binaries', _check_guts_toc), + ('_input_datas', _check_guts_toc), + +- # 'cipher': no need to check as it is implied by an additional hidden import +- + # calculated/analysed values + ('_python_version', _check_guts_eq), + ('scripts', _check_guts_toc_mtime), +@@ -931,7 +922,6 @@ def build(spec, distpath, workpath, clean_build): + 'Splash': Splash, + # Python modules available for .spec. + 'os': os, +- 'pyi_crypto': pyz_crypto, + } + + # Execute the specfile. Read it as a binary file... +diff --git a/PyInstaller/building/makespec.py b/PyInstaller/building/makespec.py +index b71f0d3..b02877b 100755 +--- a/PyInstaller/building/makespec.py ++++ b/PyInstaller/building/makespec.py +@@ -14,13 +14,10 @@ + + import argparse + import os +-import sys + + from PyInstaller import DEFAULT_SPECPATH, HOMEPATH + from PyInstaller import log as logging +-from PyInstaller.building.templates import ( +- bundleexetmplt, bundletmplt, cipher_absent_template, cipher_init_template, onedirtmplt, onefiletmplt, splashtmpl +-) ++from PyInstaller.building.templates import bundleexetmplt, bundletmplt, onedirtmplt, onefiletmplt, splashtmpl + from PyInstaller.compat import expand_path, is_darwin, is_win + + logger = logging.getLogger(__name__) +@@ -91,13 +88,9 @@ def make_variable_path(filename, conversions=path_conversions): + return None, filename + + +-def deprecated_key_option(x): +- logger.log( +- logging.DEPRECATION, +- "Bytecode encryption will be removed in PyInstaller v6. Please remove your --key=xxx argument to avoid " +- "breakages on upgrade. For the rationale/alternatives see https://github.com/pyinstaller/pyinstaller/pull/6999" +- ) +- return x ++def removed_key_option(x): ++ from PyInstaller.exceptions import RemovedCipherFeatureError ++ raise RemovedCipherFeatureError("Please remove your --key=xxx argument.") + + + # An object used in place of a "path string", which knows how to repr() itself using variable names instead of +@@ -356,7 +349,7 @@ def __add_options(parser): + '--key', + dest='key', + help=argparse.SUPPRESS, +- type=deprecated_key_option, ++ type=removed_key_option, + ) + g.add_argument( + '--splash', +@@ -732,20 +725,6 @@ def main( + # With absolute paths replace prefix with variable HOMEPATH. + scripts = list(map(Path, scripts)) + +- if key: +- # Try to import tinyaes as we need it for bytecode obfuscation. +- try: +- import tinyaes # noqa: F401 (test import) +- except ImportError: +- logger.error( +- 'We need tinyaes to use byte-code obfuscation but we could not find it. You can install it ' +- 'with pip by running:\n pip install tinyaes' +- ) +- sys.exit(1) +- cipher_init = cipher_init_template % {'key': key} +- else: +- cipher_init = cipher_absent_template +- + # Translate the default of ``debug=None`` to an empty list. + if debug is None: + debug = [] +@@ -788,7 +767,6 @@ def main( + 'upx_exclude': upx_exclude, + 'runtime_tmpdir': runtime_tmpdir, + 'exe_options': exe_options, +- 'cipher_init': cipher_init, + # Directory with additional custom import hooks. + 'hookspath': hookspath, + # List with custom runtime hook files. +diff --git a/PyInstaller/building/templates.py b/PyInstaller/building/templates.py +index ceb90f3..d8cbabf 100755 +--- a/PyInstaller/building/templates.py ++++ b/PyInstaller/building/templates.py +@@ -14,7 +14,6 @@ + + onefiletmplt = """# -*- mode: python ; coding: utf-8 -*- + %(preamble)s +-%(cipher_init)s + + a = Analysis( + %(scripts)s, +@@ -28,10 +27,9 @@ + excludes=%(excludes)s, + win_no_prefer_redirects=%(win_no_prefer_redirects)s, + win_private_assemblies=%(win_private_assemblies)s, +- cipher=block_cipher, + noarchive=%(noarchive)s, + ) +-pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) ++pyz = PYZ(a.pure, a.zipped_data) + %(splash_init)s + exe = EXE( + pyz, +@@ -58,7 +56,6 @@ + + onedirtmplt = """# -*- mode: python ; coding: utf-8 -*- + %(preamble)s +-%(cipher_init)s + + a = Analysis( + %(scripts)s, +@@ -72,10 +69,9 @@ + excludes=%(excludes)s, + win_no_prefer_redirects=%(win_no_prefer_redirects)s, + win_private_assemblies=%(win_private_assemblies)s, +- cipher=block_cipher, + noarchive=%(noarchive)s, + ) +-pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) ++pyz = PYZ(a.pure, a.zipped_data) + %(splash_init)s + exe = EXE( + pyz, +@@ -106,14 +102,6 @@ + ) + """ + +-cipher_absent_template = """ +-block_cipher = None +-""" +- +-cipher_init_template = """ +-block_cipher = pyi_crypto.PyiBlockCipher(key=%(key)r) +-""" +- + bundleexetmplt = """app = BUNDLE( + exe, + name='%(name)s.app', +diff --git a/PyInstaller/exceptions.py b/PyInstaller/exceptions.py +index f3d4387..ff773b2 100755 +--- a/PyInstaller/exceptions.py ++++ b/PyInstaller/exceptions.py +@@ -28,3 +28,9 @@ def __str__(self): + "exists and whether the hook is compatible with your version of {1}: You might want to read more about " + "hooks in the manual and provide a pull-request to improve PyInstaller.".format(self.args[0], self.args[1]) + ) ++ ++ ++class RemovedCipherFeatureError(SystemExit): ++ def __str__(self): ++ return f"Bytecode encryption was removed in PyInstaller v6.0. {self.args[0]}" \ ++ " For the rationale and alternatives see https://github.com/pyinstaller/pyinstaller/pull/6999" +diff --git a/PyInstaller/loader/pyimod01_archive.py b/PyInstaller/loader/pyimod01_archive.py +index f3ceea3..097b517 100755 +--- a/PyInstaller/loader/pyimod01_archive.py ++++ b/PyInstaller/loader/pyimod01_archive.py +@@ -14,7 +14,6 @@ + # List of built-in modules: sys.builtin_module_names + # List of modules collected into base_library.zip: PyInstaller.compat.PY3_BASE_MODULES + +-import sys + import os + import struct + import marshal +@@ -40,39 +39,6 @@ class ArchiveReadError(RuntimeError): + pass + + +-class Cipher: +- """ +- This class is used only to decrypt Python modules. +- """ +- def __init__(self): +- # At build-time the key is given to us from inside the spec file. At bootstrap-time, we must look for it +- # ourselves, by trying to import the generated 'pyi_crypto_key' module. +- import pyimod00_crypto_key +- key = pyimod00_crypto_key.key +- +- assert type(key) is str +- if len(key) > CRYPT_BLOCK_SIZE: +- self.key = key[0:CRYPT_BLOCK_SIZE] +- else: +- self.key = key.zfill(CRYPT_BLOCK_SIZE) +- assert len(self.key) == CRYPT_BLOCK_SIZE +- +- import tinyaes +- self._aesmod = tinyaes +- # Issue #1663: Remove the AES module from sys.modules list. Otherwise it interferes with using 'tinyaes' module +- # in users' code. +- del sys.modules['tinyaes'] +- +- def __create_cipher(self, iv): +- # The 'AES' class is stateful, and this factory method is used to re-initialize the block cipher class with +- # each call to xcrypt(). +- return self._aesmod.AES(self.key.encode(), iv) +- +- def decrypt(self, data): +- cipher = self.__create_cipher(data[:CRYPT_BLOCK_SIZE]) +- return cipher.CTR_xcrypt_buffer(data[CRYPT_BLOCK_SIZE:]) +- +- + class ZlibArchiveReader: + """ + Reader for PyInstaller's PYZ (ZlibArchive) archive. The archive is used to store collected byte-compiled Python +@@ -86,15 +52,6 @@ def __init__(self, filename, start_offset=None, check_pymagic=False): + + self.toc = {} + +- self.cipher = None +- +- # Try to create Cipher() instance; if encryption is not enabled, pyimod00_crypto_key is not available, and +- # instantiation fails with ImportError. +- try: +- self.cipher = Cipher() +- except ImportError: +- pass +- + # If no offset is given, try inferring it from filename + if start_offset is None: + self._filename, self._start_offset = self._parse_offset_from_filename(filename) +@@ -192,8 +149,6 @@ def extract(self, name, raw=False): + ) + + try: +- if self.cipher: +- obj = self.cipher.decrypt(obj) + obj = zlib.decompress(obj) + if typecode in (PYZ_ITEM_MODULE, PYZ_ITEM_PKG, PYZ_ITEM_NSPKG) and not raw: + obj = marshal.loads(obj) +diff --git a/doc/spec-files.rst b/doc/spec-files.rst +index 21640cd..863ab9f 100755 +--- a/doc/spec-files.rst ++++ b/doc/spec-files.rst +@@ -73,7 +73,6 @@ the ``pyinstaller`` command executes the spec file as code. + Your bundled application is created by the execution of the spec file. + The following is a shortened example of a spec file for a minimal, one-folder app:: + +- block_cipher = None + a = Analysis(['minimal.py'], + pathex=['/Developer/PItests/minimal'], + binaries=None, +@@ -81,10 +80,8 @@ The following is a shortened example of a spec file for a minimal, one-folder ap + hiddenimports=[], + hookspath=None, + runtime_hooks=None, +- excludes=None, +- cipher=block_cipher) +- pyz = PYZ(a.pure, a.zipped_data, +- cipher=block_cipher) ++ excludes=None) ++ pyz = PYZ(a.pure, a.zipped_data) + exe = EXE(pyz,... ) + coll = COLLECT(...) + +diff --git a/news/6999.breaking.rst b/news/6999.breaking.rst +new file mode 100644 +index 0000000..53a525d +--- /dev/null ++++ b/news/6999.breaking.rst +@@ -0,0 +1 @@ ++Remove bytecode encryption (``--key`` and ``cipher`` options). +diff --git a/setup.cfg b/setup.cfg +index 756ae34..fb035a8 100755 +--- a/setup.cfg ++++ b/setup.cfg +@@ -79,8 +79,6 @@ hook_testing = + pytest >= 2.7.3 + execnet >= 1.5.0 + psutil +-encryption = +- tinyaes>=1.0.0 + + [options.entry_points] + console_scripts = +diff --git a/tests/functional/test_basic.py b/tests/functional/test_basic.py +index 4fa52fc..29ef348 100755 +--- a/tests/functional/test_basic.py ++++ b/tests/functional/test_basic.py +@@ -157,38 +157,6 @@ def test_email(pyi_builder): + ) + + +-@importorskip('tinyaes') +-def test_feature_crypto(pyi_builder): +- pyi_builder.test_source( +- """ +- from pyimod00_crypto_key import key +- from pyimod01_archive import CRYPT_BLOCK_SIZE +- +- # Test against issue #1663: importing a package in the bootstrap +- # phase should not interfere with subsequent imports. +- import tinyaes +- +- assert type(key) is str +- # The test runner uses 'test_key' as key. +- assert key == 'test_key'.zfill(CRYPT_BLOCK_SIZE) +- """, +- pyi_args=['--key=test_key'] +- ) +- +- +-def test_feature_nocrypto(pyi_builder): +- pyi_builder.test_source( +- """ +- try: +- import pyimod00_crypto_key +- +- raise AssertionError('The pyimod00_crypto_key module must NOT be there if crypto is disabled.') +- except ImportError: +- pass +- """ +- ) +- +- + def test_filename(pyi_builder): + pyi_builder.test_script('pyi_filename.py') + +diff --git a/tests/requirements-tools.txt b/tests/requirements-tools.txt +index 1c6228e..3df126f 100755 +--- a/tests/requirements-tools.txt ++++ b/tests/requirements-tools.txt +@@ -37,6 +37,3 @@ ruff + pywin32; sys_platform == 'win32' + + lxml; python_version < '3.11' +- +-# crypto support (`--key` option) +-tinyaes ~= 1.0; python_version < '3.11' +-- +2.51.0 + diff --git a/python-pyinstaller.spec b/python-pyinstaller.spec index 42fcca1a84d1842098de35a5b7558c96b4e05a53..d5447f644086c0f0172c4bc3025853385ead5c8c 100644 --- a/python-pyinstaller.spec +++ b/python-pyinstaller.spec @@ -1,7 +1,7 @@ %global _empty_manifest_terminate_build 0 Name: python-pyinstaller Version: 5.13.0 -Release: 2 +Release: 3 Summary: PyInstaller bundles a Python application and all its dependencies into a single package. License: GPL-2.0-only URL: http://www.pyinstaller.org @@ -10,6 +10,8 @@ Source0: https://files.pythonhosted.org/packages/51/37/2e0195ef4e4dec35e3 Patch3000: backport-CVE-2023-49797-pre.patch # https://github.com/pyinstaller/pyinstaller/commit/5a53dc58295b26eb8af1f146df990a657bc916d1 Patch3001: backport-CVE-2023-49797.patch +# https://github.com/pyinstaller/pyinstaller/commit/f5adf291c8b832d5aff7632844f7e3ddf7ad4923 +Patch3002: backport-CVE-2025-59042.patch BuildRequires: python3-devel python3-setuptools zlib-devel BuildRequires: python3-wheel @@ -78,6 +80,9 @@ mv %{buildroot}/doclist.lst . %{_pkgdocdir} %changelog +* Fri Sep 19 2025 yaoxin <1024769339@qq.com> - 5.13.0-3 +- Fix CVE-2025-59042 + * Tue Jun 18 2024 yaoxin - 5.13.0-2 - Fix CVE-2023-49797