]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Unify temporary directory handling
authorDag-Erling Smørgrav <des@des.no>
Mon, 13 Oct 2025 12:13:47 +0000 (14:13 +0200)
committerDag-Erling Smørgrav <des@des.no>
Mon, 13 Oct 2025 14:58:44 +0000 (16:58 +0200)
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).

CMakeLists.txt
configure.ac
libarchive/archive_private.h
libarchive/archive_read_disk_entry_from_file.c
libarchive/archive_util.c

index 5718117846f590a0bd8552de9d3e8894354d9648..ba2dd53629e74beda3911fe329feba5ed24d9b11 100644 (file)
@@ -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)
index 128a11318828d33e9dfdb688a7a7dafee56d6c38..2c6cc337059eb1301fec7085c668d7fb3626d676 100644 (file)
@@ -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])
index 050fc63c0b2e4df13be24e44ccd7ffcddd2b2361..3a926c6886ad3b4d776d7ffa49b4915bf78addd4 100644 (file)
@@ -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);
index 87389642db4ae3fb3eaace7fea348acdb1f6ef46..42af4034b07ea779969d24c125be41287356f7fe 100644 (file)
@@ -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,
index 7c9ba1c16042d99794463a8e17fb68c16653ad98..b0cebce195a9df940c11a3d37b7b6524fc1b7746 100644 (file)
@@ -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);