From be28dfad5bdd2df1bb2dd5fac4457963aac7289f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Feb 2024 09:35:03 +1100 Subject: [PATCH 1/3] Fix #95411: "//" temp directory prefix causing crash - Skip leading forward slashes when setting the temp directory. - Add a utility function to set the temporary directory which is used for the user preferences & environment variables. --- source/blender/blenkernel/intern/appdir.cc | 9 +---- source/blender/blenlib/BLI_tempfile.h | 8 +++++ source/blender/blenlib/intern/tempfile.c | 38 ++++++++++++++++++---- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/appdir.cc b/source/blender/blenkernel/intern/appdir.cc index e0f63b147df..120a095a1cc 100644 --- a/source/blender/blenkernel/intern/appdir.cc +++ b/source/blender/blenkernel/intern/appdir.cc @@ -1118,16 +1118,9 @@ void BKE_appdir_app_templates(ListBase *templates) */ static void where_is_temp(char *tempdir, const size_t tempdir_maxncpy, const char *userdir) { - - tempdir[0] = '\0'; - - if (userdir && userdir[0] != '\0' && BLI_is_dir(userdir)) { - BLI_strncpy(tempdir, userdir, tempdir_maxncpy); - /* Add a trailing slash if needed. */ - BLI_path_slash_ensure(tempdir, tempdir_maxncpy); + if (BLI_temp_directory_path_copy_if_valid(tempdir, tempdir_maxncpy, userdir)) { return; } - BLI_temp_directory_path_get(tempdir, tempdir_maxncpy); } diff --git a/source/blender/blenlib/BLI_tempfile.h b/source/blender/blenlib/BLI_tempfile.h index c22da8a662e..c62e8b36635 100644 --- a/source/blender/blenlib/BLI_tempfile.h +++ b/source/blender/blenlib/BLI_tempfile.h @@ -14,6 +14,14 @@ extern "C" { #endif +/** + * Sets `temp_directory` from `dirpath` when it's a valid directory. + * Simple sanitize operations are performed and a trailing slash is ensured. + */ +bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, + const size_t buffer_size, + const char *dirpath); + /* Get the path to a directory suitable for temporary files. * * The return path is guaranteed to exist and to be a directory, as well as to contain a trailing diff --git a/source/blender/blenlib/intern/tempfile.c b/source/blender/blenlib/intern/tempfile.c index 02d973a2e16..dfb68403e11 100644 --- a/source/blender/blenlib/intern/tempfile.c +++ b/source/blender/blenlib/intern/tempfile.c @@ -8,6 +8,34 @@ #include "BLI_path_util.h" #include "BLI_string.h" +bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, + const size_t buffer_size, + const char *dirpath) +{ + if (dirpath == NULL) { + return false; + } + + /* Disallow paths starting with two forward slashes. While they are valid paths, + * Blender interprets them as relative in situations relative paths aren't supported, + * see #95411. */ + while (UNLIKELY(dirpath[0] == '/' && dirpath[1] == '/')) { + dirpath++; + } + if (dirpath[0] == '\0') { + return false; + } + if (!BLI_is_dir(dirpath)) { + return false; + } + + BLI_strncpy(temp_directory, dirpath, buffer_size); + + /* Add a trailing slash if needed. */ + BLI_path_slash_ensure(temp_directory, buffer_size); + return true; +} + void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size) { temp_directory[0] = '\0'; @@ -24,9 +52,9 @@ void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size) }; for (int i = 0; i < ARRAY_SIZE(env_vars); i++) { - const char *tmp = BLI_getenv(env_vars[i]); - if (tmp && (tmp[0] != '\0') && BLI_is_dir(tmp)) { - BLI_strncpy(temp_directory, tmp, buffer_size); + if (BLI_temp_directory_path_copy_if_valid( + temp_directory, buffer_size, BLI_getenv(env_vars[i]))) + { break; } } @@ -34,10 +62,6 @@ void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size) if (temp_directory[0] == '\0') { BLI_strncpy(temp_directory, "/tmp/", buffer_size); } - else { - /* Add a trailing slash if needed. */ - BLI_path_slash_ensure(temp_directory, buffer_size); - } BLI_dir_create_recursive(temp_directory); } -- 2.30.2 From 958024b7c6b69d05f6030531c0c89c774c0f407f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Feb 2024 20:55:18 +1100 Subject: [PATCH 2/3] Check the temporary directory is writable before setting --- source/blender/blenlib/intern/tempfile.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/blenlib/intern/tempfile.c b/source/blender/blenlib/intern/tempfile.c index dfb68403e11..87ccad7b223 100644 --- a/source/blender/blenlib/intern/tempfile.c +++ b/source/blender/blenlib/intern/tempfile.c @@ -8,6 +8,12 @@ #include "BLI_path_util.h" #include "BLI_string.h" +#ifdef WIN32 +# include "BLI_winstuff.h" /* For `W_OK`. */ +#else +# include +#endif + bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, const size_t buffer_size, const char *dirpath) @@ -28,6 +34,10 @@ bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, if (!BLI_is_dir(dirpath)) { return false; } + /* Check the path is writable. */ + if (BLI_access(dirpath, W_OK) != 0) { + return false; + } BLI_strncpy(temp_directory, dirpath, buffer_size); -- 2.30.2 From d22504485867c31b1513e3ddb1f1be7c1ad675c6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Feb 2024 21:34:34 +1100 Subject: [PATCH 3/3] Revert "Check the temporary directory is writable before setting" This reverts commit 958024b7c6b69d05f6030531c0c89c774c0f407f. I'd rather handle permissions separately from relative paths. --- source/blender/blenlib/intern/tempfile.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/source/blender/blenlib/intern/tempfile.c b/source/blender/blenlib/intern/tempfile.c index 87ccad7b223..dfb68403e11 100644 --- a/source/blender/blenlib/intern/tempfile.c +++ b/source/blender/blenlib/intern/tempfile.c @@ -8,12 +8,6 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#ifdef WIN32 -# include "BLI_winstuff.h" /* For `W_OK`. */ -#else -# include -#endif - bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, const size_t buffer_size, const char *dirpath) @@ -34,10 +28,6 @@ bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, if (!BLI_is_dir(dirpath)) { return false; } - /* Check the path is writable. */ - if (BLI_access(dirpath, W_OK) != 0) { - return false; - } BLI_strncpy(temp_directory, dirpath, buffer_size); -- 2.30.2