Compare commits
10 Commits
90850f451b
...
3aa6b701da
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3aa6b701da | ||
|
|
e3d95da23c | ||
|
|
4e09a19f98 | ||
|
|
63111c078e | ||
|
|
2d38d00a01 | ||
|
|
a13872c06f | ||
|
|
8299ef4bc3 | ||
|
|
092d8765e4 | ||
|
|
e801a95031 | ||
|
|
5cc75f2cc7 |
@ -1,81 +0,0 @@
|
||||
From 22ad4f7200a56da969e9296d8fecf2f0b8368afc Mon Sep 17 00:00:00 2001
|
||||
From: Dan Yeaw <dyeaw@ford.com>
|
||||
Date: Mon, 23 Dec 2019 15:31:04 -0500
|
||||
Subject: [PATCH] Bootloader: Fix GCC warnings for strncpy and strncat.
|
||||
|
||||
Fixes Issue #4196. GCC 8.1 and later added checks to prevent using
|
||||
strncpy and strncat with the bounds depending on the length of the
|
||||
source str. In order to fix this, a few approaches were made:
|
||||
1. Where guards already existed to ensure that added paths weren't
|
||||
larger than the PATH_MAX, changed to strcpy / strcat which don't take a
|
||||
length parameter.
|
||||
2. Where path length checks didn't exist, set the bounds of the strncpy
|
||||
and strncat to PATH_MAX.
|
||||
|
||||
Signed-off-by: Dan Yeaw <dyeaw@ford.com>
|
||||
---
|
||||
bootloader/src/pyi_path.c | 7 ++++---
|
||||
bootloader/src/pyi_pythonlib.c | 12 ++++++------
|
||||
2 files changed, 10 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/bootloader/src/pyi_path.c b/bootloader/src/pyi_path.c
|
||||
index a449f79..d36e3d2 100644
|
||||
--- a/bootloader/src/pyi_path.c
|
||||
+++ b/bootloader/src/pyi_path.c
|
||||
@@ -56,7 +56,7 @@ pyi_path_dirname(char *result, const char *path)
|
||||
char *match = NULL;
|
||||
|
||||
/* Copy path to result and then just write '\0' to the place with path separator. */
|
||||
- strncpy(result, path, strlen(path) + 1);
|
||||
+ strncpy(result, path, PATH_MAX);
|
||||
/* Remove separator from the end. */
|
||||
len = strlen(result);
|
||||
|
||||
@@ -143,7 +143,7 @@ pyi_path_join(char *result, const char *path1, const char *path2)
|
||||
memset(result, 0, PATH_MAX);
|
||||
}
|
||||
/* Copy path1 to result without null terminator */
|
||||
- strncpy(result, path1, strlen(path1));
|
||||
+ strcpy(result, path1);
|
||||
/* Append trailing slash if missing. */
|
||||
len = strlen(result);
|
||||
|
||||
@@ -156,7 +156,8 @@ pyi_path_join(char *result, const char *path1, const char *path2)
|
||||
|
||||
if (path2[len - 1] == PYI_SEP) {
|
||||
/* Append path2 without slash. */
|
||||
- strncat(result, path2, len - 2);
|
||||
+ strcat(result, path2);
|
||||
+ result[strlen(result) - 1] = PYI_NULLCHAR;
|
||||
}
|
||||
else {
|
||||
/* path2 does not end with slash. */
|
||||
diff --git a/bootloader/src/pyi_pythonlib.c b/bootloader/src/pyi_pythonlib.c
|
||||
index ee4b3b2..d90c239 100644
|
||||
--- a/bootloader/src/pyi_pythonlib.c
|
||||
+++ b/bootloader/src/pyi_pythonlib.c
|
||||
@@ -480,15 +480,15 @@ pyi_pylib_start_python(ARCHIVE_STATUS *status)
|
||||
/* Set sys.path */
|
||||
if (is_py2) {
|
||||
/* sys.path = [mainpath] */
|
||||
- strncpy(pypath, status->mainpath, strlen(status->mainpath));
|
||||
+ strncpy(pypath, status->mainpath, PATH_MAX);
|
||||
}
|
||||
else {
|
||||
/* sys.path = [base_library, mainpath] */
|
||||
- strncpy(pypath, status->mainpath, strlen(status->mainpath));
|
||||
- strncat(pypath, PYI_SEPSTR, strlen(PYI_SEPSTR));
|
||||
- strncat(pypath, "base_library.zip", strlen("base_library.zip"));
|
||||
- strncat(pypath, PYI_PATHSEPSTR, strlen(PYI_PATHSEPSTR));
|
||||
- strncat(pypath, status->mainpath, strlen(status->mainpath));
|
||||
+ strncpy(pypath, status->mainpath, PATH_MAX);
|
||||
+ strncat(pypath, PYI_SEPSTR, PATH_MAX);
|
||||
+ strncat(pypath, "base_library.zip", PATH_MAX);
|
||||
+ strncat(pypath, PYI_PATHSEPSTR, PATH_MAX);
|
||||
+ strncat(pypath, status->mainpath, PATH_MAX);
|
||||
};
|
||||
|
||||
/*
|
||||
--
|
||||
2.23.0
|
||||
|
||||
Binary file not shown.
@ -1,63 +0,0 @@
|
||||
From a95fbb0f497680cce0a097aa3a143e84943b903f Mon Sep 17 00:00:00 2001
|
||||
From: Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
Date: Sun, 3 May 2020 15:26:43 +0200
|
||||
Subject: [PATCH] Bootloader: Reimplement pyi_search_path using strtok().
|
||||
|
||||
This avoids some places where we need to cope with strncpy(= and related. Also
|
||||
the implementation becomes much simpler.
|
||||
---
|
||||
bootloader/src/pyi_path.c | 34 +++++++---------------------------
|
||||
1 file changed, 7 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/bootloader/src/pyi_path.c b/bootloader/src/pyi_path.c
|
||||
index 8736de8cc5..fb417e9269 100644
|
||||
--- a/bootloader/src/pyi_path.c
|
||||
+++ b/bootloader/src/pyi_path.c
|
||||
@@ -205,40 +205,20 @@ pyi_path_exists(char * path)
|
||||
int
|
||||
pyi_search_path(char * result, const char * appname)
|
||||
{
|
||||
- char * path = pyi_getenv("PATH");
|
||||
- char dirname[PATH_MAX + 1];
|
||||
- char filename[PATH_MAX + 1];
|
||||
+ char *path = pyi_getenv("PATH"); // returns a copy
|
||||
+ char *dirname;
|
||||
|
||||
if (NULL == path) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
- while (1) {
|
||||
- char *delim = strchr(path, PYI_PATHSEP);
|
||||
-
|
||||
- if (delim) {
|
||||
- size_t len = delim - path;
|
||||
-
|
||||
- if (len > PATH_MAX) {
|
||||
- len = PATH_MAX;
|
||||
- }
|
||||
- strncpy(dirname, path, len);
|
||||
- *(dirname + len) = '\0';
|
||||
- }
|
||||
- else { /* last $PATH element */
|
||||
- strncpy(dirname, path, PATH_MAX);
|
||||
- }
|
||||
- pyi_path_join(filename, dirname, appname);
|
||||
-
|
||||
- if (pyi_path_exists(filename)) {
|
||||
- strncpy(result, filename, PATH_MAX);
|
||||
+ dirname = strtok(path, PYI_PATHSEPSTR);
|
||||
+ while (dirname != NULL) {
|
||||
+ pyi_path_join(result, dirname, appname);
|
||||
+ if (pyi_path_exists(result)) {
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
- if (!delim) {
|
||||
- break;
|
||||
- }
|
||||
- path = delim + 1;
|
||||
+ dirname = strtok(NULL, PYI_PATHSEPSTR);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -1,208 +0,0 @@
|
||||
From b4c0d01e751975090fa7346a2a71dd778c3b412c Mon Sep 17 00:00:00 2001
|
||||
From: Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
Date: Sun, 3 May 2020 15:43:52 +0200
|
||||
Subject: [PATCH] Bootloader: Use snprintf() to simplify some string length
|
||||
checks.
|
||||
|
||||
Instead of copying strings and checking whether the string si terminated with
|
||||
a Null bytes, use snprintf, which tells how much space the new string would
|
||||
have taken and compare this to the available space.
|
||||
|
||||
Since snprintf() add some overhead, This code might be a bit less efficient.
|
||||
But this sie the bootloader, and most of the functions are called once only.
|
||||
---
|
||||
bootloader/src/pyi_archive.c | 21 ++++++++-------------
|
||||
bootloader/src/pyi_launch.c | 27 +++++++++------------------
|
||||
bootloader/src/pyi_main.c | 4 ++--
|
||||
bootloader/src/pyi_path.c | 3 +--
|
||||
bootloader/src/pyi_pythonlib.c | 14 +++++++++-----
|
||||
bootloader/src/pyi_utils.c | 7 ++-----
|
||||
6 files changed, 31 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/bootloader/src/pyi_archive.c b/bootloader/src/pyi_archive.c
|
||||
index ed886e09fb..32b129fb98 100644
|
||||
--- a/bootloader/src/pyi_archive.c
|
||||
+++ b/bootloader/src/pyi_archive.c
|
||||
@@ -455,28 +455,23 @@ int
|
||||
pyi_arch_set_paths(ARCHIVE_STATUS *status, char const * archivePath,
|
||||
char const * archiveName)
|
||||
{
|
||||
- size_t pathlen, namelen;
|
||||
-
|
||||
- pathlen = strnlen(archivePath, PATH_MAX);
|
||||
- namelen = strnlen(archiveName, PATH_MAX);
|
||||
-
|
||||
- if (pathlen+namelen+1 > PATH_MAX) {
|
||||
- return -1;
|
||||
+ /* Set homepath to where the archive is */
|
||||
+ if (snprintf(status->homepath, PATH_MAX, "%s", archivePath) >= PATH_MAX) {
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
/* Get the archive Path */
|
||||
- strcpy(status->archivename, archivePath);
|
||||
- strcat(status->archivename, archiveName);
|
||||
-
|
||||
- /* Set homepath to where the archive is */
|
||||
- strcpy(status->homepath, archivePath);
|
||||
+ if (snprintf(status->archivename, PATH_MAX,
|
||||
+ "%s%s", archivePath, archiveName) >= PATH_MAX) {
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Initial value of mainpath is homepath. It might be overriden
|
||||
* by temppath if it is available.
|
||||
*/
|
||||
status->has_temp_directory = false;
|
||||
- strcpy(status->mainpath, status->homepath);
|
||||
+ strcpy(status->mainpath, status->homepath); // homepath fits into PATH_MAX
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/bootloader/src/pyi_launch.c b/bootloader/src/pyi_launch.c
|
||||
index 3517be6353..432a43416f 100644
|
||||
--- a/bootloader/src/pyi_launch.c
|
||||
+++ b/bootloader/src/pyi_launch.c
|
||||
@@ -79,15 +79,13 @@ checkFile(char *buf, const char *fmt, ...)
|
||||
static int
|
||||
splitName(char *path, char *filename, const char *item)
|
||||
{
|
||||
- char name[PATH_MAX + 1];
|
||||
+ char name[PATH_MAX];
|
||||
|
||||
VS("LOADER: Splitting item into path and filename\n");
|
||||
- strncpy(name, item, PATH_MAX + 1);
|
||||
-
|
||||
- if (name[PATH_MAX] != '\0') {
|
||||
+ if (snprintf(name, PATH_MAX, "%s", item) >= PATH_MAX) {
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
+ // `name` fits into PATH_MAX, so will all substrings
|
||||
strcpy(path, strtok(name, ":"));
|
||||
strcpy(filename, strtok(NULL, ":"));
|
||||
|
||||
@@ -148,13 +146,11 @@ _get_archive(ARCHIVE_STATUS *archive_pool[], const char *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- strncpy(archive->archivename, path, PATH_MAX);
|
||||
- strncpy(archive->homepath, archive_pool[SELF]->homepath, PATH_MAX);
|
||||
- strncpy(archive->temppath, archive_pool[SELF]->temppath, PATH_MAX);
|
||||
-
|
||||
- if (archive->archivename[PATH_MAX-1] != '\0'
|
||||
- || archive->homepath[PATH_MAX-1] != '\0'
|
||||
- || archive->temppath[PATH_MAX-1] != '\0') {
|
||||
+ if ((snprintf(archive->archivename, PATH_MAX, "%s", path) >= PATH_MAX) ||
|
||||
+ (snprintf(archive->homepath, PATH_MAX, "%s",
|
||||
+ archive_pool[SELF]->homepath) >= PATH_MAX) ||
|
||||
+ (snprintf(archive->temppath, PATH_MAX, "%s",
|
||||
+ archive_pool[SELF]->temppath) >= PATH_MAX)) {
|
||||
FATALERROR("Archive path exceeds PATH_MAX\n");
|
||||
free(archive);
|
||||
return NULL;
|
||||
@@ -369,7 +365,6 @@ pyi_launch_run_scripts(ARCHIVE_STATUS *status)
|
||||
{
|
||||
unsigned char *data;
|
||||
char buf[PATH_MAX];
|
||||
- size_t namelen;
|
||||
TOC * ptoc = status->tocbuff;
|
||||
PyObject *__main__;
|
||||
PyObject *__file__;
|
||||
@@ -400,14 +395,10 @@ pyi_launch_run_scripts(ARCHIVE_STATUS *status)
|
||||
data = pyi_arch_extract(status, ptoc);
|
||||
/* Set the __file__ attribute within the __main__ module,
|
||||
* for full compatibility with normal execution. */
|
||||
- namelen = strnlen(ptoc->name, PATH_MAX);
|
||||
- if (namelen >= PATH_MAX-strlen(".py")-1) {
|
||||
+ if (snprintf(buf, PATH_MAX, "%s.py", ptoc->name) >= PATH_MAX) {
|
||||
FATALERROR("Name exceeds PATH_MAX\n");
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
- strcpy(buf, ptoc->name);
|
||||
- strcat(buf, ".py");
|
||||
VS("LOADER: Running %s\n", buf);
|
||||
|
||||
if (is_py2) {
|
||||
diff --git a/bootloader/src/pyi_main.c b/bootloader/src/pyi_main.c
|
||||
index 02b1bec5dc..472cd1ae9a 100644
|
||||
--- a/bootloader/src/pyi_main.c
|
||||
+++ b/bootloader/src/pyi_main.c
|
||||
@@ -126,8 +126,8 @@ pyi_main(int argc, char * argv[])
|
||||
* we pass it through status variable
|
||||
*/
|
||||
if (strcmp(homepath, extractionpath) != 0) {
|
||||
- strncpy(archive_status->temppath, extractionpath, PATH_MAX);
|
||||
- if (archive_status->temppath[PATH_MAX-1] != '\0') {
|
||||
+ if (snprintf(archive_status->temppath, PATH_MAX,
|
||||
+ "%s", extractionpath) >= PATH_MAX) {
|
||||
VS("LOADER: temppath exceeds PATH_MAX\n");
|
||||
return -1;
|
||||
}
|
||||
diff --git a/bootloader/src/pyi_path.c b/bootloader/src/pyi_path.c
|
||||
index fb417e9269..6ed252ffab 100644
|
||||
--- a/bootloader/src/pyi_path.c
|
||||
+++ b/bootloader/src/pyi_path.c
|
||||
@@ -286,8 +286,7 @@ pyi_path_executable(char *execfile, const char *appname)
|
||||
if (-1 == result) {
|
||||
/* Searching $PATH failed, user is crazy. */
|
||||
VS("LOADER: Searching $PATH failed for %s", appname);
|
||||
- strncpy(buffer, appname, PATH_MAX);
|
||||
- if (buffer[PATH_MAX-1] != '\0') {
|
||||
+ if (snprintf(buffer, PATH_MAX, "%s", "appname") >= PATH_MAX) {
|
||||
VS("LOADER: Appname too large %s\n", appname);
|
||||
return -1;
|
||||
}
|
||||
diff --git a/bootloader/src/pyi_pythonlib.c b/bootloader/src/pyi_pythonlib.c
|
||||
index caffcd6daa..8144885b17 100644
|
||||
--- a/bootloader/src/pyi_pythonlib.c
|
||||
+++ b/bootloader/src/pyi_pythonlib.c
|
||||
@@ -414,18 +414,16 @@ pyi_pylib_start_python(ARCHIVE_STATUS *status)
|
||||
};
|
||||
|
||||
/* Set sys.path */
|
||||
- if (is_py2) {
|
||||
- /* sys.path = [mainpath] */
|
||||
- strncpy(pypath, status->mainpath, PATH_MAX);
|
||||
- }
|
||||
- else {
|
||||
- /* sys.path = [base_library, mainpath] */
|
||||
+ /* sys.path = [base_library, mainpath] */
|
||||
- strncpy(pypath, status->mainpath, PATH_MAX);
|
||||
- strncat(pypath, PYI_SEPSTR, PATH_MAX);
|
||||
- strncat(pypath, "base_library.zip", PATH_MAX);
|
||||
- strncat(pypath, PYI_PATHSEPSTR, PATH_MAX);
|
||||
- strncat(pypath, status->mainpath, PATH_MAX);
|
||||
- };
|
||||
+ if (snprintf(pypath, sizeof pypath, "%s%cbase_library.zip%c%s",
|
||||
+ status->mainpath, PYI_SEP, PYI_PATHSEP, status->mainpath)
|
||||
+ >= sizeof pypath) {
|
||||
+ // This should never happen, since mainpath is < PATH_MAX and pypath is
|
||||
+ // huge enough
|
||||
+ FATALERROR("sys.path (based on %s) exceeds buffer[%d] space\n",
|
||||
+ status->mainpath, sizeof pypath);
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* On Python 3, we must set sys.path to have base_library.zip before
|
||||
diff --git a/bootloader/src/pyi_utils.c b/bootloader/src/pyi_utils.c
|
||||
index e18d611f26..0c89975908 100644
|
||||
--- a/bootloader/src/pyi_utils.c
|
||||
+++ b/bootloader/src/pyi_utils.c
|
||||
@@ -557,11 +557,8 @@ pyi_open_target(const char *path, const char* name_)
|
||||
char *dir;
|
||||
size_t len;
|
||||
|
||||
- strncpy(fnm, path, PATH_MAX);
|
||||
- strncpy(name, name_, PATH_MAX);
|
||||
-
|
||||
- /* Check if the path names could be copied */
|
||||
- if (fnm[PATH_MAX-1] != '\0' || name[PATH_MAX-1] != '\0') {
|
||||
+ if (snprintf(fnm, PATH_MAX, "%s", path) >= PATH_MAX ||
|
||||
+ snprintf(name, PATH_MAX, "%s", name_) >= PATH_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
95
backport-CVE-2023-49797-pre.patch
Normal file
95
backport-CVE-2023-49797-pre.patch
Normal file
@ -0,0 +1,95 @@
|
||||
From 709262381451878dadb9e9d26190167a2ab5e67c Mon Sep 17 00:00:00 2001
|
||||
From: Rok Mandeljc <rok.mandeljc@gmail.com>
|
||||
Date: Thu, 3 Aug 2023 13:49:03 +0200
|
||||
Subject: [PATCH] rthooks: win32com: fully isolate the genpy cache
|
||||
|
||||
Instead of extending the `win32.com.gen_py` sub-module search paths
|
||||
(the `__path__` attribute) with the new location of the isolated
|
||||
cache, override it completely. This prevents the global cache from
|
||||
being accessed, which might result in errors when the global cache
|
||||
contains some, but not all, required modules.
|
||||
---
|
||||
.../hooks/rthooks/pyi_rth_win32comgenpy.py | 44 +++++++------------
|
||||
news/6257.bugfix.rst | 3 ++
|
||||
2 files changed, 18 insertions(+), 29 deletions(-)
|
||||
create mode 100644 news/6257.bugfix.rst
|
||||
|
||||
diff --git a/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py b/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py
|
||||
index 3671c3ab2e..aed2515b08 100644
|
||||
--- a/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py
|
||||
+++ b/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py
|
||||
@@ -9,12 +9,12 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
-# The win32.client.gencache code must be allowed to create the cache in %temp% (user's temp). It is necessary to get the
|
||||
-# gencache code to use a suitable directory other than the default in lib\site-packages\win32com\client\gen_py.
|
||||
-# PyInstaller does not provide this directory structure and the frozen executable could be placed in a non-writable
|
||||
-# directory like 'C:\Program Files. That's the reason for %temp% directory.
|
||||
-#
|
||||
-# http://www.py2exe.org/index.cgi/UsingEnsureDispatch
|
||||
+# Put the cache generated by `win32com.client.gencache` into isolated temporary directory. Historically, this was
|
||||
+# required due to earlier versions of `pywin32` using the `site-packages\win32com\client\gen_py` directory for
|
||||
+# the cache by default. Nowadays, the default location for the cache seems to be in the configured temporary directory
|
||||
+# (pointed to by TEMP or TMP, for example %LOCALAPPDATA%\Temp), so strictly speaking, the relocation is not necessary
|
||||
+# anymore. But for the time being, we are keeping it around to isolate the frozen application from the rest of the
|
||||
+# system.
|
||||
|
||||
|
||||
def _pyi_rthook():
|
||||
@@ -23,36 +23,22 @@ def _pyi_rthook():
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
- # Put gen_py cache in temp directory.
|
||||
+ import win32com
|
||||
+
|
||||
+ # Create temporary directory. The actual cache directory needs to be named `gen_py`, so create a sub-directory.
|
||||
supportdir = tempfile.mkdtemp()
|
||||
- # gen_py has to be put into directory 'gen_py'.
|
||||
+
|
||||
genpydir = os.path.join(supportdir, 'gen_py')
|
||||
+ os.makedirs(genpydir, exist_ok=True)
|
||||
|
||||
- # Create 'gen_py' directory. This directory does not need to contain '__init__.py' file.
|
||||
- try:
|
||||
- # win32com gencache cannot be put directly to 'supportdir' with any random name. It has to be put in a directory
|
||||
- # called 'gen_py'. This is the reason why to create this directory in supportdir'.
|
||||
- os.makedirs(genpydir)
|
||||
- # Remove temp directory at application exit and ignore any errors.
|
||||
- atexit.register(shutil.rmtree, supportdir, ignore_errors=True)
|
||||
- except OSError:
|
||||
- pass
|
||||
+ # Remove the teporary directory at application exit, ignoring errors.
|
||||
+ atexit.register(shutil.rmtree, supportdir, ignore_errors=True)
|
||||
|
||||
# Override the default path to gen_py cache.
|
||||
- import win32com # noqa: E402
|
||||
-
|
||||
win32com.__gen_path__ = genpydir
|
||||
|
||||
- # The attribute __loader__ makes module 'pkg_resources' working but On Windows it breaks pywin32 (win32com) and test
|
||||
- # 'basic/test_pyttsx' will fail. Just removing that attribute for win32com fixes that and gencache is created
|
||||
- # properly.
|
||||
- if hasattr(win32com, '__loader__'):
|
||||
- del win32com.__loader__
|
||||
-
|
||||
- # Ensure genpydir is in 'gen_py' module paths.
|
||||
- import win32com.gen_py # noqa: E402
|
||||
-
|
||||
- win32com.gen_py.__path__.insert(0, genpydir)
|
||||
+ # Override the sub-module paths for win32com.gen_py run-time sub-package.
|
||||
+ win32com.gen_py.__path__ = [genpydir]
|
||||
|
||||
|
||||
_pyi_rthook()
|
||||
diff --git a/news/6257.bugfix.rst b/news/6257.bugfix.rst
|
||||
new file mode 100644
|
||||
index 0000000000..3cb746a332
|
||||
--- /dev/null
|
||||
+++ b/news/6257.bugfix.rst
|
||||
@@ -0,0 +1,3 @@
|
||||
+(Windows) Fix ``win32com`` run-time hook to fully isolate the ``gen_py``
|
||||
+cache. This prevents the access to global cache, which results in errors
|
||||
+when the global cache contains some, but not all, required modules.
|
||||
\ No newline at end of file
|
||||
513
backport-CVE-2023-49797.patch
Normal file
513
backport-CVE-2023-49797.patch
Normal file
@ -0,0 +1,513 @@
|
||||
From 5a53dc58295b26eb8af1f146df990a657bc916d1 Mon Sep 17 00:00:00 2001
|
||||
From: Rok Mandeljc <rok.mandeljc@gmail.com>
|
||||
Date: Sat, 5 Aug 2023 12:50:28 +0200
|
||||
Subject: [PATCH] rthooks: secure temp directories used by matplotlib and
|
||||
win32com rthooks
|
||||
|
||||
The run-time hooks that relocate the package's configuration/cache
|
||||
directory into isolated temporary directory create this directory using
|
||||
the `tempfile.mkdtemp` function. According to its documentation, the
|
||||
function creates the temporary directory "in the most secure manner
|
||||
possible", and the created directory should be "readable, writable, and
|
||||
searchable only by the creating user ID".
|
||||
|
||||
However, this does not apply to Windows, where the 0o700 POSIX
|
||||
permissions mask passed to the underyling `os.mkdir` call has no effect.
|
||||
Consequently, the access to the created temporary directory is in fact
|
||||
gated only by the access to the parent directory. So as long as `TEMP`
|
||||
and `TMP` point to `%LOCALAPPDATA%\Temp`, the created temporary
|
||||
directories are typically inaccessible to other users, who do not have
|
||||
access to the user's home directory. On the other hand, if the temporary
|
||||
directory base is relocated to a system-wide location (e.g., `c:\temp`),
|
||||
the temporary directories created by the run-time hooks might become
|
||||
accessible to other users as well. A malicious user with local access
|
||||
might thus modify the contents of the temporary directory, interfering
|
||||
with the application. If the application is running in privileged mode
|
||||
and developer mode is enabled on the system, they might also attempt
|
||||
a symlink attack due to lack of hardened mode for `shutil.rmtree`
|
||||
(used for clean up) on Windows.
|
||||
|
||||
Therefore, we replace the use of `tempfile.mkdtemp` with custom function
|
||||
that uses original `mkdtemp` on POSIX and provides a Windows-specific
|
||||
implementation that secures the access to created directory via security
|
||||
descriptor passed to the `CreateDirectoryW` call. This is a
|
||||
`ctypes`-based port of the code that we already have in bootloader for
|
||||
mitigating the same issue with temporary directory in onefile builds.
|
||||
|
||||
In order to share the implementation among the two run-time hooks that
|
||||
require it, the code is provided by a new `_pyi_rth_utils` PyInstaller
|
||||
"fake" package, which is bundled with the frozen application on demand
|
||||
(i.e., if it is referenced in any of collected run-time hooks).
|
||||
|
||||
Origin:
|
||||
https://github.com/pyinstaller/pyinstaller/commit/5a53dc58295b26eb8af1f146df990a657bc916d1
|
||||
---
|
||||
MANIFEST.in | 2 +-
|
||||
.../fake-modules/_pyi_rth_utils/__init__.py | 56 ++++
|
||||
.../fake-modules/_pyi_rth_utils/_win32.py | 262 ++++++++++++++++++
|
||||
.../hook-_pyi_rth_utils.py | 25 ++
|
||||
.../hooks/rthooks/pyi_rth_mplconfig.py | 8 +-
|
||||
.../hooks/rthooks/pyi_rth_win32comgenpy.py | 8 +-
|
||||
news/7827.bugfix.rst | 5 +
|
||||
setup.cfg | 1 +
|
||||
setup.py | 1 +
|
||||
9 files changed, 361 insertions(+), 7 deletions(-)
|
||||
create mode 100644 PyInstaller/fake-modules/_pyi_rth_utils/__init__.py
|
||||
create mode 100644 PyInstaller/fake-modules/_pyi_rth_utils/_win32.py
|
||||
create mode 100644 PyInstaller/hooks/pre_find_module_path/hook-_pyi_rth_utils.py
|
||||
create mode 100644 news/7827.bugfix.rst
|
||||
|
||||
diff --git a/MANIFEST.in b/MANIFEST.in
|
||||
index a77f401..2c702a1 100755
|
||||
--- a/MANIFEST.in
|
||||
+++ b/MANIFEST.in
|
||||
@@ -12,6 +12,6 @@ recursive-include PyInstaller/bootloader/Windows-64bit-intel *
|
||||
recursive-include PyInstaller/bootloader/Darwin-64bit *
|
||||
include pyproject.toml
|
||||
# These files need to be explicitly included
|
||||
-include PyInstaller/fake-modules/*.py
|
||||
+recursive-include PyInstaller/fake-modules *.py
|
||||
include PyInstaller/hooks/rthooks.dat
|
||||
include PyInstaller/lib/README.rst
|
||||
diff --git a/PyInstaller/fake-modules/_pyi_rth_utils/__init__.py b/PyInstaller/fake-modules/_pyi_rth_utils/__init__.py
|
||||
new file mode 100644
|
||||
index 0000000..2d3af0e
|
||||
--- /dev/null
|
||||
+++ b/PyInstaller/fake-modules/_pyi_rth_utils/__init__.py
|
||||
@@ -0,0 +1,56 @@
|
||||
+# -----------------------------------------------------------------------------
|
||||
+# Copyright (c) 2023, PyInstaller Development Team.
|
||||
+#
|
||||
+# Distributed under the terms of the GNU General Public License (version 2
|
||||
+# or later) with exception for distributing the bootloader.
|
||||
+#
|
||||
+# The full license is in the file COPYING.txt, distributed with this software.
|
||||
+#
|
||||
+# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
|
||||
+# -----------------------------------------------------------------------------
|
||||
+
|
||||
+import os
|
||||
+import sys
|
||||
+import errno
|
||||
+import tempfile
|
||||
+
|
||||
+# Helper for creating temporary directories with access restricted to the user running the process.
|
||||
+# On POSIX systems, this is already achieved by `tempfile.mkdtemp`, which uses 0o700 permissions mask.
|
||||
+# On Windows, however, the POSIX permissions semantics have no effect, and we need to provide our own implementation
|
||||
+# that restricts the access by passing appropriate security attributes to the `CreateDirectory` function.
|
||||
+
|
||||
+if os.name == 'nt':
|
||||
+ from . import _win32
|
||||
+
|
||||
+ def secure_mkdtemp(suffix=None, prefix=None, dir=None):
|
||||
+ """
|
||||
+ Windows-specific replacement for `tempfile.mkdtemp` that restricts access to the user running the process.
|
||||
+ Based on `mkdtemp` implementation from python 3.11 stdlib.
|
||||
+ """
|
||||
+
|
||||
+ prefix, suffix, dir, output_type = tempfile._sanitize_params(prefix, suffix, dir)
|
||||
+
|
||||
+ names = tempfile._get_candidate_names()
|
||||
+ if output_type is bytes:
|
||||
+ names = map(os.fsencode, names)
|
||||
+
|
||||
+ for seq in range(tempfile.TMP_MAX):
|
||||
+ name = next(names)
|
||||
+ file = os.path.join(dir, prefix + name + suffix)
|
||||
+ sys.audit("tempfile.mkdtemp", file)
|
||||
+ try:
|
||||
+ _win32.secure_mkdir(file)
|
||||
+ except FileExistsError:
|
||||
+ continue # try again
|
||||
+ except PermissionError:
|
||||
+ # This exception is thrown when a directory with the chosen name already exists on windows.
|
||||
+ if (os.name == 'nt' and os.path.isdir(dir) and os.access(dir, os.W_OK)):
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
+ return file
|
||||
+
|
||||
+ raise FileExistsError(errno.EEXIST, "No usable temporary directory name found")
|
||||
+
|
||||
+else:
|
||||
+ secure_mkdtemp = tempfile.mkdtemp
|
||||
diff --git a/PyInstaller/fake-modules/_pyi_rth_utils/_win32.py b/PyInstaller/fake-modules/_pyi_rth_utils/_win32.py
|
||||
new file mode 100644
|
||||
index 0000000..41237fb
|
||||
--- /dev/null
|
||||
+++ b/PyInstaller/fake-modules/_pyi_rth_utils/_win32.py
|
||||
@@ -0,0 +1,262 @@
|
||||
+# -----------------------------------------------------------------------------
|
||||
+# Copyright (c) 2023, PyInstaller Development Team.
|
||||
+#
|
||||
+# Distributed under the terms of the GNU General Public License (version 2
|
||||
+# or later) with exception for distributing the bootloader.
|
||||
+#
|
||||
+# The full license is in the file COPYING.txt, distributed with this software.
|
||||
+#
|
||||
+# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
|
||||
+# -----------------------------------------------------------------------------
|
||||
+
|
||||
+import ctypes
|
||||
+import ctypes.wintypes
|
||||
+
|
||||
+# Constants from win32 headers
|
||||
+TOKEN_QUERY = 0x0008
|
||||
+
|
||||
+TokenUser = 1 # from TOKEN_INFORMATION_CLASS enum
|
||||
+
|
||||
+ERROR_INSUFFICIENT_BUFFER = 122
|
||||
+
|
||||
+INVALID_HANDLE = -1
|
||||
+
|
||||
+FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100
|
||||
+FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
|
||||
+
|
||||
+SDDL_REVISION1 = 1
|
||||
+
|
||||
+# Structures for ConvertSidToStringSidW
|
||||
+PSID = ctypes.wintypes.LPVOID
|
||||
+
|
||||
+
|
||||
+class SID_AND_ATTRIBUTES(ctypes.Structure):
|
||||
+ _fields_ = [
|
||||
+ ("Sid", PSID),
|
||||
+ ("Attributes", ctypes.wintypes.DWORD),
|
||||
+ ]
|
||||
+
|
||||
+
|
||||
+class TOKEN_USER(ctypes.Structure):
|
||||
+ _fields_ = [
|
||||
+ ("User", SID_AND_ATTRIBUTES),
|
||||
+ ]
|
||||
+
|
||||
+
|
||||
+PTOKEN_USER = ctypes.POINTER(TOKEN_USER)
|
||||
+
|
||||
+# SECURITY_ATTRIBUTES structure for CreateDirectoryW
|
||||
+PSECURITY_DESCRIPTOR = ctypes.wintypes.LPVOID
|
||||
+
|
||||
+
|
||||
+class SECURITY_ATTRIBUTES(ctypes.Structure):
|
||||
+ _fields_ = [
|
||||
+ ("nLength", ctypes.wintypes.DWORD),
|
||||
+ ("lpSecurityDescriptor", PSECURITY_DESCRIPTOR),
|
||||
+ ("bInheritHandle", ctypes.wintypes.BOOL),
|
||||
+ ]
|
||||
+
|
||||
+
|
||||
+# win32 API functions, bound via ctypes.
|
||||
+# NOTE: we do not use ctypes.windll.<dll_name> to avoid modifying its (global) function prototypes, which might affect
|
||||
+# user's code.
|
||||
+kernel32 = ctypes.WinDLL("kernel32")
|
||||
+advapi32 = ctypes.WinDLL("advapi32")
|
||||
+
|
||||
+kernel32.CloseHandle.restype = ctypes.wintypes.BOOL
|
||||
+kernel32.CloseHandle.argtypes = (ctypes.wintypes.HANDLE,)
|
||||
+
|
||||
+kernel32.LocalFree.restype = ctypes.wintypes.BOOL
|
||||
+kernel32.LocalFree.argtypes = (ctypes.wintypes.HLOCAL,)
|
||||
+
|
||||
+kernel32.GetCurrentProcess.restype = ctypes.wintypes.HANDLE
|
||||
+
|
||||
+kernel32.OpenProcessToken.restype = ctypes.wintypes.BOOL
|
||||
+kernel32.OpenProcessToken.argtypes = (
|
||||
+ ctypes.wintypes.HANDLE,
|
||||
+ ctypes.wintypes.DWORD,
|
||||
+ ctypes.wintypes.PHANDLE,
|
||||
+)
|
||||
+
|
||||
+advapi32.ConvertSidToStringSidW.restype = ctypes.wintypes.BOOL
|
||||
+advapi32.ConvertSidToStringSidW.argtypes = (
|
||||
+ PSID,
|
||||
+ ctypes.POINTER(ctypes.wintypes.LPWSTR),
|
||||
+)
|
||||
+
|
||||
+advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW.restype = ctypes.wintypes.BOOL
|
||||
+advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW.argtypes = (
|
||||
+ ctypes.wintypes.LPCWSTR,
|
||||
+ ctypes.wintypes.DWORD,
|
||||
+ ctypes.POINTER(PSECURITY_DESCRIPTOR),
|
||||
+ ctypes.wintypes.PULONG,
|
||||
+)
|
||||
+
|
||||
+
|
||||
+def _win_error_to_message(error_code):
|
||||
+ """
|
||||
+ Convert win32 error code to message.
|
||||
+ """
|
||||
+ message_wstr = ctypes.wintypes.LPWSTR(None)
|
||||
+ ret = kernel32.FormatMessageW(
|
||||
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
+ None, # lpSource
|
||||
+ error_code, # dwMessageId
|
||||
+ 0x400, # dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
|
||||
+ ctypes.byref(message_wstr), # pointer to LPWSTR due to FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
+ 64, # due to FORMAT_MESSAGE_ALLOCATE_BUFFER, this is minimum number of characters to allocate
|
||||
+ )
|
||||
+ if ret == 0:
|
||||
+ return None
|
||||
+
|
||||
+ message = message_wstr.value
|
||||
+ kernel32.LocalFree(message_wstr)
|
||||
+
|
||||
+ # Strip trailing CR/LF.
|
||||
+ if message:
|
||||
+ message = message.strip()
|
||||
+ return message
|
||||
+
|
||||
+
|
||||
+def _get_user_sid():
|
||||
+ """
|
||||
+ Obtain the SID for the current user.
|
||||
+ """
|
||||
+ process_token = ctypes.wintypes.HANDLE(INVALID_HANDLE)
|
||||
+
|
||||
+ try:
|
||||
+ # Get access token for the current process
|
||||
+ ret = kernel32.OpenProcessToken(
|
||||
+ kernel32.GetCurrentProcess(),
|
||||
+ TOKEN_QUERY,
|
||||
+ ctypes.pointer(process_token),
|
||||
+ )
|
||||
+ if ret == 0:
|
||||
+ error_code = kernel32.GetLastError()
|
||||
+ raise RuntimeError(f"Failed to open process token! Error code: 0x{error_code:X}")
|
||||
+
|
||||
+ # Query buffer size for user info structure
|
||||
+ user_info_size = ctypes.wintypes.DWORD(0)
|
||||
+
|
||||
+ ret = advapi32.GetTokenInformation(
|
||||
+ process_token,
|
||||
+ TokenUser,
|
||||
+ None,
|
||||
+ 0,
|
||||
+ ctypes.byref(user_info_size),
|
||||
+ )
|
||||
+
|
||||
+ # We expect this call to fail with ERROR_INSUFFICIENT_BUFFER
|
||||
+ if ret == 0:
|
||||
+ error_code = kernel32.GetLastError()
|
||||
+ if error_code != ERROR_INSUFFICIENT_BUFFER:
|
||||
+ raise RuntimeError(f"Failed to query token information buffer size! Error code: 0x{error_code:X}")
|
||||
+ else:
|
||||
+ raise RuntimeError("Unexpected return value from GetTokenInformation!")
|
||||
+
|
||||
+ # Allocate buffer
|
||||
+ user_info = ctypes.create_string_buffer(user_info_size.value)
|
||||
+ ret = advapi32.GetTokenInformation(
|
||||
+ process_token,
|
||||
+ TokenUser,
|
||||
+ user_info,
|
||||
+ user_info_size,
|
||||
+ ctypes.byref(user_info_size),
|
||||
+ )
|
||||
+ if ret == 0:
|
||||
+ error_code = kernel32.GetLastError()
|
||||
+ raise RuntimeError(f"Failed to query token information! Error code: 0x{error_code:X}")
|
||||
+
|
||||
+ # Convert SID to string
|
||||
+ # Technically, we need to pass user_info->User.Sid, but as they are at the beginning of the
|
||||
+ # buffer, just pass the buffer instead...
|
||||
+ sid_wstr = ctypes.wintypes.LPWSTR(None)
|
||||
+ ret = advapi32.ConvertSidToStringSidW(
|
||||
+ ctypes.cast(user_info, PTOKEN_USER).contents.User.Sid,
|
||||
+ ctypes.pointer(sid_wstr),
|
||||
+ )
|
||||
+ if ret == 0:
|
||||
+ error_code = kernel32.GetLastError()
|
||||
+ raise RuntimeError(f"Failed to convert SID to string! Error code: 0x{error_code:X}")
|
||||
+ sid = sid_wstr.value
|
||||
+ kernel32.LocalFree(sid_wstr)
|
||||
+ except Exception:
|
||||
+ sid = None
|
||||
+ finally:
|
||||
+ # Close the process token
|
||||
+ if process_token.value != INVALID_HANDLE:
|
||||
+ kernel32.CloseHandle(process_token)
|
||||
+
|
||||
+ return sid
|
||||
+
|
||||
+
|
||||
+# Get and cache current user's SID
|
||||
+_user_sid = _get_user_sid()
|
||||
+
|
||||
+
|
||||
+def secure_mkdir(dir_name):
|
||||
+ """
|
||||
+ Replacement for mkdir that limits the access to created directory to current user.
|
||||
+ """
|
||||
+
|
||||
+ # Create security descriptor
|
||||
+ # Prefer actual user SID over SID S-1-3-4 (current owner), because at the time of writing, Wine does not properly
|
||||
+ # support the latter.
|
||||
+ sid = _user_sid or "S-1-3-4"
|
||||
+
|
||||
+ # DACL descriptor (D):
|
||||
+ # ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)
|
||||
+ # - ace_type = SDDL_ACCESS_ALLOWED (A)
|
||||
+ # - rights = SDDL_FILE_ALL (FA)
|
||||
+ # - account_sid = current user (queried SID)
|
||||
+ security_desc_str = f"D:(A;;FA;;;{sid})"
|
||||
+ security_desc = ctypes.wintypes.LPVOID(None)
|
||||
+
|
||||
+ ret = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||
+ security_desc_str,
|
||||
+ SDDL_REVISION1,
|
||||
+ ctypes.byref(security_desc),
|
||||
+ None,
|
||||
+ )
|
||||
+ if ret == 0:
|
||||
+ error_code = kernel32.GetLastError()
|
||||
+ raise RuntimeError(
|
||||
+ f"Failed to create security descriptor! Error code: 0x{error_code:X}, "
|
||||
+ f"message: {_win_error_to_message(error_code)}"
|
||||
+ )
|
||||
+
|
||||
+ security_attr = SECURITY_ATTRIBUTES()
|
||||
+ security_attr.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES)
|
||||
+ security_attr.lpSecurityDescriptor = security_desc
|
||||
+ security_attr.bInheritHandle = False
|
||||
+
|
||||
+ # Create directory
|
||||
+ ret = kernel32.CreateDirectoryW(
|
||||
+ dir_name,
|
||||
+ security_attr,
|
||||
+ )
|
||||
+ if ret == 0:
|
||||
+ # Call failed; store error code immediately, to avoid it being overwritten in cleanup below.
|
||||
+ error_code = kernel32.GetLastError()
|
||||
+
|
||||
+ # Free security descriptor
|
||||
+ kernel32.LocalFree(security_desc)
|
||||
+
|
||||
+ # Exit on succeess
|
||||
+ if ret != 0:
|
||||
+ return
|
||||
+
|
||||
+ # Construct OSError from win error code
|
||||
+ error_message = _win_error_to_message(error_code)
|
||||
+
|
||||
+ # Strip trailing dot to match error message from os.mkdir().
|
||||
+ if error_message and error_message[-1] == '.':
|
||||
+ error_message = error_message[:-1]
|
||||
+
|
||||
+ raise OSError(
|
||||
+ None, # errno
|
||||
+ error_message, # strerror
|
||||
+ dir_name, # filename
|
||||
+ error_code, # winerror
|
||||
+ None, # filename2
|
||||
+ )
|
||||
diff --git a/PyInstaller/hooks/pre_find_module_path/hook-_pyi_rth_utils.py b/PyInstaller/hooks/pre_find_module_path/hook-_pyi_rth_utils.py
|
||||
new file mode 100644
|
||||
index 0000000..d035df0
|
||||
--- /dev/null
|
||||
+++ b/PyInstaller/hooks/pre_find_module_path/hook-_pyi_rth_utils.py
|
||||
@@ -0,0 +1,25 @@
|
||||
+# -----------------------------------------------------------------------------
|
||||
+# Copyright (c) 2023, PyInstaller Development Team.
|
||||
+#
|
||||
+# Distributed under the terms of the GNU General Public License (version 2
|
||||
+# or later) with exception for distributing the bootloader.
|
||||
+#
|
||||
+# The full license is in the file COPYING.txt, distributed with this software.
|
||||
+#
|
||||
+# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
|
||||
+# -----------------------------------------------------------------------------
|
||||
+"""
|
||||
+This hook allows discovery and collection of PyInstaller's internal _pyi_rth_utils module that provides utility
|
||||
+functions for run-time hooks.
|
||||
+
|
||||
+The module is implemented in 'PyInstaller/fake-modules/_pyi_rth_utils.py'.
|
||||
+"""
|
||||
+
|
||||
+import os
|
||||
+
|
||||
+from PyInstaller import PACKAGEPATH
|
||||
+
|
||||
+
|
||||
+def pre_find_module_path(api):
|
||||
+ module_dir = os.path.join(PACKAGEPATH, 'fake-modules')
|
||||
+ api.search_dirs = [module_dir]
|
||||
diff --git a/PyInstaller/hooks/rthooks/pyi_rth_mplconfig.py b/PyInstaller/hooks/rthooks/pyi_rth_mplconfig.py
|
||||
index 018d6fe..6ea9425 100755
|
||||
--- a/PyInstaller/hooks/rthooks/pyi_rth_mplconfig.py
|
||||
+++ b/PyInstaller/hooks/rthooks/pyi_rth_mplconfig.py
|
||||
@@ -27,10 +27,12 @@ def _pyi_rthook():
|
||||
import atexit
|
||||
import os
|
||||
import shutil
|
||||
- import tempfile
|
||||
|
||||
- # Put matplot config dir to temp directory.
|
||||
- configdir = tempfile.mkdtemp()
|
||||
+ import _pyi_rth_utils # PyInstaller's run-time hook utilities module
|
||||
+
|
||||
+ # Isolate matplotlib's config dir into temporary directory.
|
||||
+ # Use our replacement for `tempfile.mkdtemp` function that properly restricts access to directory on all platforms.
|
||||
+ configdir = _pyi_rth_utils.secure_mkdtemp()
|
||||
os.environ['MPLCONFIGDIR'] = configdir
|
||||
|
||||
try:
|
||||
diff --git a/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py b/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py
|
||||
index aed2515..a9bbbd1 100755
|
||||
--- a/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py
|
||||
+++ b/PyInstaller/hooks/rthooks/pyi_rth_win32comgenpy.py
|
||||
@@ -21,13 +21,15 @@ def _pyi_rthook():
|
||||
import atexit
|
||||
import os
|
||||
import shutil
|
||||
- import tempfile
|
||||
|
||||
import win32com
|
||||
|
||||
- # Create temporary directory. The actual cache directory needs to be named `gen_py`, so create a sub-directory.
|
||||
- supportdir = tempfile.mkdtemp()
|
||||
+ import _pyi_rth_utils # PyInstaller's run-time hook utilities module
|
||||
|
||||
+ # Create temporary directory.
|
||||
+ # Use our replacement for `tempfile.mkdtemp` function that properly restricts access to directory on all platforms.
|
||||
+ supportdir = _pyi_rth_utils.secure_mkdtemp()
|
||||
+ # The actual cache directory needs to be named `gen_py`, so create a sub-directory.
|
||||
genpydir = os.path.join(supportdir, 'gen_py')
|
||||
os.makedirs(genpydir, exist_ok=True)
|
||||
|
||||
diff --git a/news/7827.bugfix.rst b/news/7827.bugfix.rst
|
||||
new file mode 100644
|
||||
index 0000000..41ea37a
|
||||
--- /dev/null
|
||||
+++ b/news/7827.bugfix.rst
|
||||
@@ -0,0 +1,5 @@
|
||||
+(Windows) Ensure that the access to temporary directories created by
|
||||
+the ``matplotlib`` and ``win32com`` run-time hooks is restricted to
|
||||
+the user running the frozen application, even if ``TMP`` / ``TEMP``
|
||||
+environment directory points to a system-wide location that can be
|
||||
+accessed to all users.
|
||||
diff --git a/setup.cfg b/setup.cfg
|
||||
index 7cd1548..756ae34 100755
|
||||
--- a/setup.cfg
|
||||
+++ b/setup.cfg
|
||||
@@ -70,6 +70,7 @@ include =
|
||||
PyInstaller =
|
||||
bootloader/*/*
|
||||
fake-modules/*.py
|
||||
+ fake-modules/_pyi_rth_utils/*.py
|
||||
hooks/rthooks.dat
|
||||
lib/README.rst
|
||||
|
||||
diff --git a/setup.py b/setup.py
|
||||
index 51d2482..ac82bb6 100755
|
||||
--- a/setup.py
|
||||
+++ b/setup.py
|
||||
@@ -114,6 +114,7 @@ def finalize_options(self):
|
||||
*(f"bootloader/images/*.{suffix}" for suffix in self.ICON_TYPES),
|
||||
# These files need to be explicitly included as well.
|
||||
"fake-modules/*.py",
|
||||
+ "fake-modules/_pyi_rth_utils/*.py",
|
||||
"hooks/rthooks.dat",
|
||||
"lib/README.rst",
|
||||
],
|
||||
--
|
||||
2.43.0
|
||||
|
||||
BIN
pyinstaller-5.13.0.tar.gz
Normal file
BIN
pyinstaller-5.13.0.tar.gz
Normal file
Binary file not shown.
@ -1,15 +1,17 @@
|
||||
%global _empty_manifest_terminate_build 0
|
||||
Name: python-pyinstaller
|
||||
Version: 3.6
|
||||
Release: 1
|
||||
Version: 5.13.0
|
||||
Release: 2
|
||||
Summary: PyInstaller bundles a Python application and all its dependencies into a single package.
|
||||
License: GPL license with a special exception which allows to use PyInstaller to build and distribute non-free programs (including commercial ones)
|
||||
License: GPL-2.0-only
|
||||
URL: http://www.pyinstaller.org
|
||||
Source0: https://files.pythonhosted.org/packages/3c/c9/c3f9bc64eb11eee6a824686deba6129884c8cbdf70e750661773b9865ee0/PyInstaller-3.6.tar.gz
|
||||
Patch6000: Fix-Gcc-warnings-for-strncpy-and-strncat.patch
|
||||
Patch6001: Reimplement-pyi-search-path-using-strtok.patch
|
||||
Patch6002: Use-snprintf-to-simplify-some-string-len.patch
|
||||
Source0: https://files.pythonhosted.org/packages/51/37/2e0195ef4e4dec35e3f116361c4c780e0c4cd2cd96079199b3218c08fabb/pyinstaller-%{version}.tar.gz
|
||||
# https://github.com/pyinstaller/pyinstaller/commit/709262381451878dadb9e9d26190167a2ab5e67c
|
||||
Patch3000: backport-CVE-2023-49797-pre.patch
|
||||
# https://github.com/pyinstaller/pyinstaller/commit/5a53dc58295b26eb8af1f146df990a657bc916d1
|
||||
Patch3001: backport-CVE-2023-49797.patch
|
||||
BuildRequires: python3-devel python3-setuptools zlib-devel
|
||||
BuildRequires: python3-wheel
|
||||
|
||||
%description
|
||||
PyInstaller bundles a Python application and all its dependencies into a single
|
||||
@ -35,7 +37,7 @@ package. The user can run the packaged app without installing a Python
|
||||
interpreter or any modules.
|
||||
|
||||
%prep
|
||||
%autosetup -n PyInstaller-%{version} -p1
|
||||
%autosetup -n pyinstaller-%{version} -p1
|
||||
|
||||
%build
|
||||
%py3_build
|
||||
@ -70,10 +72,20 @@ mv %{buildroot}/doclist.lst .
|
||||
|
||||
%files -n python3-pyinstaller -f filelist.lst
|
||||
%dir %{python3_sitelib}/*
|
||||
%exclude %{python3_sitelib}/PyInstaller/bootloader/{D*,W*,*32*,Linux-64bit}
|
||||
|
||||
%files help -f doclist.lst
|
||||
%{_pkgdocdir}
|
||||
|
||||
%changelog
|
||||
* Tue Jun 18 2024 yaoxin <yao_xin001@hoperun.com> - 5.13.0-2
|
||||
- Fix CVE-2023-49797
|
||||
|
||||
* Mon Jul 10 2023 chenzixuan<chenzixuan@kylinos.cn> - 5.13.0-1
|
||||
- Update to 5.13.0
|
||||
|
||||
* Tue May 16 2023 yaoxin <yao_xin001@hoperun.com> - 5.10.1-1
|
||||
- Update to 5.10.1
|
||||
|
||||
* Mon Jun 22 2020 Python_Bot <Python_Bot@openeuler.org>
|
||||
- Package Spec generated
|
||||
|
||||
4
python-pyinstaller.yaml
Normal file
4
python-pyinstaller.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
version_control: pypi
|
||||
src_repo: PyInstaller
|
||||
tag_prefix: "v"
|
||||
seperator: ""
|
||||
Loading…
x
Reference in New Issue
Block a user