]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Merge pull request #2707 from fdegros/close_range_support
authorTim Kientzle <kientzle@acm.org>
Wed, 20 Aug 2025 18:18:45 +0000 (11:18 -0700)
committerMartin Matuska <martin@matuska.de>
Tue, 23 Sep 2025 20:58:40 +0000 (22:58 +0200)
Avoid leaking file descriptors into subprocesses

(cherry picked from commit ab4d21e4cb1124d71232f81b33b2738d93c97b5a)

CMakeLists.txt
build/cmake/config.h.in
configure.ac
contrib/android/config/android.h
contrib/android/config/linux_host.h
contrib/android/config/windows_host.h
libarchive/filter_fork_posix.c

index 93c5031fe4100f027458f1c4987b7145b16fab0d..f44adc77725a30a26aaf367a8f88489bfe3be750 100644 (file)
@@ -1479,6 +1479,8 @@ CHECK_FUNCTION_EXISTS_GLIBC(arc4random_buf HAVE_ARC4RANDOM_BUF)
 CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
 CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
 CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
+CHECK_FUNCTION_EXISTS_GLIBC(closefrom HAVE_CLOSEFROM)
+CHECK_FUNCTION_EXISTS_GLIBC(close_range HAVE_CLOSE_RANGE)
 CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
 CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
 CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
index bea6cc7c02d0a06f59806d770355110f4dd72389..06f66b4378c17b3fdb3eb4a9ca972ee74970d1c8 100644 (file)
@@ -405,6 +405,12 @@ typedef uint64_t uintmax_t;
 /* Define to 1 if you have the `chroot' function. */
 #cmakedefine HAVE_CHROOT 1
 
+/* Define to 1 if you have the `closefrom' function. */
+#cmakedefine HAVE_CLOSEFROM 1
+
+/* Define to 1 if you have the `close_range' function. */
+#cmakedefine HAVE_CLOSE_RANGE 1
+
 /* Define to 1 if you have the <copyfile.h> header file. */
 #cmakedefine HAVE_COPYFILE_H 1
 
index c70573f293bd058e90eeba3cabac320f9a62ca7b..aae0f381e31238bf79e1708ad006179fff9e725e 100644 (file)
@@ -821,7 +821,8 @@ AC_FUNC_VPRINTF
 # To avoid necessity for including windows.h or special forward declaration
 # workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
 AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
-AC_CHECK_FUNCS([arc4random_buf chflags chown chroot ctime_r])
+AC_CHECK_FUNCS([arc4random_buf chflags chown chroot])
+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])
index 00fa4e9fdcfa5cb97d7b4164fdfc67f740761e27..0a273be235b7444d6469ea389a7f2f82ef43316a 100644 (file)
@@ -40,6 +40,8 @@
 
 #define HAVE_CHOWN 1
 #define HAVE_CHROOT 1
+#define HAVE_CLOSEFROM 1
+#define HAVE_CLOSE_RANGE 1
 #define HAVE_CTIME_R 1
 #define HAVE_CTYPE_H 1
 #define HAVE_DECL_EXTATTR_NAMESPACE_USER 0
index f0f7ab39ca178df789ffbbe54a00f08d6404fb18..cc96e5efe3dab2ce46042d7cf322668cbbe30128 100644 (file)
@@ -28,6 +28,8 @@
 
 #define HAVE_CHOWN 1
 #define HAVE_CHROOT 1
+#define HAVE_CLOSEFROM 1
+#define HAVE_CLOSE_RANGE 1
 #define HAVE_CTIME_R 1
 #define HAVE_CTYPE_H 1
 #define HAVE_DECL_EXTATTR_NAMESPACE_USER 0
 #define HAVE_WMEMCMP 1
 #define HAVE_WMEMCPY 1
 #define HAVE_ZLIB_H 1
-#define ICONV_CONST 
+#define ICONV_CONST
 #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
 #define SIZEOF_WCHAR_T 4
 #define STDC_HEADERS 1
index 98c005c5149ca4835df148463e19f1d34a068370..2e24be1d3d75843e16e59494125edcf4b0b1e9c2 100644 (file)
 /* Define to 1 if you have the `chroot' function. */
 /* #undef HAVE_CHROOT */
 
+/* Define to 1 if you have the `closefrom' function. */
+/* #undef HAVE_CLOSEFROM */
+
+/* Define to 1 if you have the `close_range' function. */
+/* #undef HAVE_CLOSE_RANGE */
+
 /* Define to 1 if you have the <copyfile.h> header file. */
 /* #undef HAVE_COPYFILE_H */
 
index c895c08e59b3366f6f4e36b7e66bc7a27f51f23f..7c48519336ff1bd525a6b93a9b3d660424de2d20 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2007 Joerg Sonnenberger
- * Copyright (c) 2012 Michihiro NAKAJIMA 
+ * Copyright (c) 2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,7 +76,15 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
 {
        pid_t child = -1;
        int stdin_pipe[2], stdout_pipe[2], tmp;
+
+#if !defined(POSIX_SPAWN_CLOEXEC_DEFAULT) && \
+    (HAVE_FORK || HAVE_VFORK) && \
+    (HAVE_CLOSEFROM || HAVE_CLOSE_RANGE || defined(_SC_OPEN_MAX))
+#undef HAVE_POSIX_SPAWNP
+#endif
+
 #if HAVE_POSIX_SPAWNP
+       posix_spawnattr_t attr;
        posix_spawn_file_actions_t actions;
        int r;
 #endif
@@ -107,11 +115,21 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
 
 #if HAVE_POSIX_SPAWNP
 
-       r = posix_spawn_file_actions_init(&actions);
+       r = posix_spawnattr_init(&attr);
        if (r != 0) {
                errno = r;
                goto stdout_opened;
        }
+       r = posix_spawn_file_actions_init(&actions);
+       if (r != 0) {
+               errno = r;
+               goto attr_inited;
+       }
+#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
+       r = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT);
+       if (r != 0)
+               goto actions_inited;
+#endif
        r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[1]);
        if (r != 0)
                goto actions_inited;
@@ -136,11 +154,12 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
                if (r != 0)
                        goto actions_inited;
        }
-       r = posix_spawnp(&child, cmdline->path, &actions, NULL,
+       r = posix_spawnp(&child, cmdline->path, &actions, &attr,
                cmdline->argv, NULL);
        if (r != 0)
                goto actions_inited;
        posix_spawn_file_actions_destroy(&actions);
+       posix_spawnattr_destroy(&attr);
 
 #else /* HAVE_POSIX_SPAWNP */
 
@@ -162,6 +181,16 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
                        _exit(254);
                if (stdout_pipe[1] != 1 /* stdout */)
                        close(stdout_pipe[1]);
+
+#if HAVE_CLOSEFROM
+               closefrom(3);
+#elif HAVE_CLOSE_RANGE
+               close_range(3, ~0U, 0);
+#elif defined(_SC_OPEN_MAX)
+               for (int i = sysconf(_SC_OPEN_MAX); i > 3;)
+                       close(--i);
+#endif
+
                execvp(cmdline->path, cmdline->argv);
                _exit(254);
        }
@@ -183,6 +212,8 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
 actions_inited:
        errno = r;
        posix_spawn_file_actions_destroy(&actions);
+attr_inited:
+       posix_spawnattr_destroy(&attr);
 #endif
 stdout_opened:
        close(stdout_pipe[0]);