From: François Degros Date: Tue, 29 Jul 2025 05:18:28 +0000 (+1000) Subject: Use closefrom() or close_range() when possible X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=64bcf69ef8c266fa78c26c09fa88e7356ee20098;p=thirdparty%2Flibarchive.git Use closefrom() or close_range() when possible To avoid leaking file descriptors into subprocesses. Fixes: https://github.com/libarchive/libarchive/issues/2520 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 83a02857e..a28c99919 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 692d4516a..6ef8bb2f1 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 cacc97ee6..9b1408949 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 4754744d8..7aa08b54b 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..a90ef4014 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,6 +76,11 @@ __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 (HAVE_FORK || HAVE_VFORK) && (HAVE_CLOSEFROM || HAVE_CLOSE_RANGE) +#undef HAVE_POSIX_SPAWNP +#endif + #if HAVE_POSIX_SPAWNP posix_spawn_file_actions_t actions; int r; @@ -162,6 +167,13 @@ __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); +#endif + execvp(cmdline->path, cmdline->argv); _exit(254); }