From: Dag-Erling Smørgrav Date: Mon, 13 Oct 2025 12:13:47 +0000 (+0200) Subject: Unify temporary directory handling X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e12c955dca632df0204b9f3cfbbe265079d7c30c;p=thirdparty%2Flibarchive.git Unify temporary directory handling In archive_util.c, we have a private function named get_tempdir() which is used by __archive_mktemp() to get the temporary directory if the caller did not pass one. In archive_read_disk_entry_from_file.c, we use the same logic with a slight twist (don't trust the environment if setugid) to create a temporary file for metadata. Merge the two by renaming get_tempdir() to __archive_get_tempdir() and unstaticizing it (with a prototype in archive_private.h). --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 571811784..ba2dd5362 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1429,15 +1429,19 @@ CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE) CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS) CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES) CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT) +CHECK_FUNCTION_EXISTS_GLIBC(getegid HAVE_GETEGID) CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID) CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R) CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R) CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE) +CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID) CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R) CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R) -CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID) +CHECK_FUNCTION_EXISTS_GLIBC(getresgid HAVE_GETRESGID) +CHECK_FUNCTION_EXISTS_GLIBC(getresuid HAVE_GETRESUID) CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME) CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R) +CHECK_FUNCTION_EXISTS_GLIBC(issetugid HAVE_ISSETUGID) CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS) CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD) CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN) diff --git a/configure.ac b/configure.ac index 128a11318..2c6cc3370 100644 --- a/configure.ac +++ b/configure.ac @@ -826,8 +826,10 @@ AC_CHECK_FUNCS([closefrom close_range ctime_r]) AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fnmatch fork]) AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate]) AC_CHECK_FUNCS([futimens futimes futimesat]) -AC_CHECK_FUNCS([geteuid getline getpid getgrgid_r getgrnam_r]) -AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r]) +AC_CHECK_FUNCS([getegid geteuid getline getpid getresgid getresuid]) +AC_CHECK_FUNCS([getgrgid_r getgrnam_r getpwnam_r getpwuid_r]) +AC_CHECK_FUNCS([getvfsbyname gmtime_r]) +AC_CHECK_FUNCS([issetugid]) AC_CHECK_FUNCS([lchflags lchmod lchown link linkat localtime_r lstat lutimes]) AC_CHECK_FUNCS([mbrtowc memmove memset]) AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp]) diff --git a/libarchive/archive_private.h b/libarchive/archive_private.h index 050fc63c0..3a926c688 100644 --- a/libarchive/archive_private.h +++ b/libarchive/archive_private.h @@ -158,6 +158,7 @@ int __archive_check_magic(struct archive *, unsigned int magic, __LA_NORETURN void __archive_errx(int retvalue, const char *msg); void __archive_ensure_cloexec_flag(int fd); +int __archive_get_tempdir(struct archive_string *); int __archive_mktemp(const char *tmpdir); #if defined(_WIN32) && !defined(__CYGWIN__) int __archive_mkstemp(wchar_t *templates); diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c index 87389642d..42af4034b 100644 --- a/libarchive/archive_read_disk_entry_from_file.c +++ b/libarchive/archive_read_disk_entry_from_file.c @@ -338,7 +338,7 @@ setup_mac_metadata(struct archive_read_disk *a, int ret = ARCHIVE_OK; void *buff = NULL; int have_attrs; - const char *name, *tempdir; + const char *name; struct archive_string tempfile; (void)fd; /* UNUSED */ @@ -357,14 +357,12 @@ setup_mac_metadata(struct archive_read_disk *a, if (have_attrs == 0) return (ARCHIVE_OK); - tempdir = NULL; - if (issetugid() == 0) - tempdir = getenv("TMPDIR"); - if (tempdir == NULL) - tempdir = _PATH_TMP; archive_string_init(&tempfile); - archive_strcpy(&tempfile, tempdir); - archive_strcat(&tempfile, "/tar.md.XXXXXX"); + if (__archive_get_tempdir(&tempfile) != ARCHIVE_OK) { + ret = ARCHIVE_WARN; + goto cleanup; + } + archive_strcat(&tempfile, "tar.md.XXXXXX"); tempfd = mkstemp(tempfile.s); if (tempfd < 0) { archive_set_error(&a->archive, errno, diff --git a/libarchive/archive_util.c b/libarchive/archive_util.c index 7c9ba1c16..b0cebce19 100644 --- a/libarchive/archive_util.c +++ b/libarchive/archive_util.c @@ -416,11 +416,39 @@ __archive_mkstemp(wchar_t *template) #else static int -get_tempdir(struct archive_string *temppath) +__archive_issetugid(void) { - const char *tmp; +#ifdef HAVE_ISSETUGID + return (issetugid()); +#elif HAVE_GETRESUID + uid_t ruid, euid, suid; + gid_t rgid, egid, sgid; + if (getresuid(&ruid, &euid, &suid) != 0) + return (-1); + if (ruid != euid || ruid != suid) + return (1); + if (getresgid(&ruid, &egid, &sgid) != 0) + return (-1); + if (rgid != egid || rgid != sgid) + return (1); +#elif HAVE_GETEUID + if (geteuid() != getuid()) + return (1); +#if HAVE_GETEGID + if (getegid() != getgid()) + return (1); +#endif +#endif + return (0); +} + +int +__archive_get_tempdir(struct archive_string *temppath) +{ + const char *tmp = NULL; - tmp = getenv("TMPDIR"); + if (__archive_issetugid() == 0) + tmp = getenv("TMPDIR"); if (tmp == NULL) #ifdef _PATH_TMP tmp = _PATH_TMP; @@ -447,7 +475,7 @@ __archive_mktemp(const char *tmpdir) archive_string_init(&temp_name); if (tmpdir == NULL) { - if (get_tempdir(&temp_name) != ARCHIVE_OK) + if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK) goto exit_tmpfile; } else { archive_strcpy(&temp_name, tmpdir); @@ -509,7 +537,7 @@ __archive_mktempx(const char *tmpdir, char *template) if (template == NULL) { archive_string_init(&temp_name); if (tmpdir == NULL) { - if (get_tempdir(&temp_name) != ARCHIVE_OK) + if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK) goto exit_tmpfile; } else archive_strcpy(&temp_name, tmpdir);