From: Tim Kientzle Date: Wed, 20 Aug 2025 18:18:45 +0000 (-0700) Subject: Merge pull request #2707 from fdegros/close_range_support X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f162db9618ec3297444950028993dfc5ff0fe1a1;p=thirdparty%2Flibarchive.git Merge pull request #2707 from fdegros/close_range_support Avoid leaking file descriptors into subprocesses (cherry picked from commit ab4d21e4cb1124d71232f81b33b2738d93c97b5a) --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 93c5031fe..f44adc777 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index bea6cc7c0..06f66b437 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -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 header file. */ #cmakedefine HAVE_COPYFILE_H 1 diff --git a/configure.ac b/configure.ac index c70573f29..aae0f381e 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/contrib/android/config/android.h b/contrib/android/config/android.h index 00fa4e9fd..0a273be23 100644 --- a/contrib/android/config/android.h +++ b/contrib/android/config/android.h @@ -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 diff --git a/contrib/android/config/linux_host.h b/contrib/android/config/linux_host.h index f0f7ab39c..cc96e5efe 100644 --- a/contrib/android/config/linux_host.h +++ b/contrib/android/config/linux_host.h @@ -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 @@ -180,7 +182,7 @@ #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 diff --git a/contrib/android/config/windows_host.h b/contrib/android/config/windows_host.h index 98c005c51..2e24be1d3 100644 --- a/contrib/android/config/windows_host.h +++ b/contrib/android/config/windows_host.h @@ -175,6 +175,12 @@ /* 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 header file. */ /* #undef HAVE_COPYFILE_H */ diff --git a/libarchive/filter_fork_posix.c b/libarchive/filter_fork_posix.c index c895c08e5..7c4851933 100644 --- a/libarchive/filter_fork_posix.c +++ b/libarchive/filter_fork_posix.c @@ -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]);