From 611dda48e2c9476c5b8989b540789aeab1600de1 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 21 Jul 2022 19:49:19 -0700 Subject: [PATCH 01/13] Use bsd_closefrom.c from openssh-portable to fix #189 --- cbits/posix/bsd_closefrom.c | 153 ++++++++++++++++++++++++++++++++++++ cbits/posix/close_fds.c | 22 ++++++ cbits/posix/common.h | 3 +- cbits/posix/fork_exec.c | 8 +- cbits/posix/runProcess.c | 16 ---- process.cabal | 2 + 6 files changed, 180 insertions(+), 24 deletions(-) create mode 100644 cbits/posix/bsd_closefrom.c create mode 100644 cbits/posix/close_fds.c diff --git a/cbits/posix/bsd_closefrom.c b/cbits/posix/bsd_closefrom.c new file mode 100644 index 00000000..5a5779e7 --- /dev/null +++ b/cbits/posix/bsd_closefrom.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2004-2005 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HAVE_CLOSEFROM + +#include +#include +#include +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif +#if defined(HAVE_LIBPROC_H) +# include +#endif + +#ifndef OPEN_MAX +# define OPEN_MAX 256 +#endif + +#if 0 +__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; +#endif /* lint */ + +#ifndef HAVE_FCNTL_CLOSEM +/* + * Close all file descriptors greater than or equal to lowfd. + */ +static void +closefrom_fallback(int lowfd) +{ + long fd, maxfd; + + /* + * Fall back on sysconf() or getdtablesize(). We avoid checking + * resource limits since it is possible to open a file descriptor + * and then drop the rlimit such that it is below the open fd. + */ +#ifdef HAVE_SYSCONF + maxfd = sysconf(_SC_OPEN_MAX); +#else + maxfd = getdtablesize(); +#endif /* HAVE_SYSCONF */ + if (maxfd < 0) + maxfd = OPEN_MAX; + + for (fd = lowfd; fd < maxfd; fd++) + (void) close((int) fd); +} +#endif /* HAVE_FCNTL_CLOSEM */ + +#ifdef HAVE_FCNTL_CLOSEM +void +closefrom(int lowfd) +{ + (void) fcntl(lowfd, F_CLOSEM, 0); +} +#elif defined(HAVE_LIBPROC_H) && defined(HAVE_PROC_PIDINFO) +void +closefrom(int lowfd) +{ + int i, r, sz; + pid_t pid = getpid(); + struct proc_fdinfo *fdinfo_buf = NULL; + + sz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); + if (sz == 0) + return; /* no fds, really? */ + else if (sz == -1) + goto fallback; + if ((fdinfo_buf = malloc(sz)) == NULL) + goto fallback; + r = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fdinfo_buf, sz); + if (r < 0 || r > sz) + goto fallback; + for (i = 0; i < r / (int)PROC_PIDLISTFD_SIZE; i++) { + if (fdinfo_buf[i].proc_fd >= lowfd) + close(fdinfo_buf[i].proc_fd); + } + free(fdinfo_buf); + return; + fallback: + free(fdinfo_buf); + closefrom_fallback(lowfd); + return; +} +#elif defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) +void +closefrom(int lowfd) +{ + long fd; + char fdpath[PATH_MAX], *endp; + struct dirent *dent; + DIR *dirp; + int len; + + /* Check for a /proc/$$/fd directory. */ + len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); + if (len > 0 && (size_t)len < sizeof(fdpath) && (dirp = opendir(fdpath))) { + while ((dent = readdir(dirp)) != NULL) { + fd = strtol(dent->d_name, &endp, 10); + if (dent->d_name != endp && *endp == '\0' && + fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) + (void) close((int) fd); + } + (void) closedir(dirp); + return; + } + /* /proc/$$/fd strategy failed, fall back to brute force closure */ + closefrom_fallback(lowfd); +} +#else +void +closefrom(int lowfd) +{ + closefrom_fallback(lowfd); +} +#endif /* !HAVE_FCNTL_CLOSEM */ +#endif /* HAVE_CLOSEFROM */ diff --git a/cbits/posix/close_fds.c b/cbits/posix/close_fds.c new file mode 100644 index 00000000..e2747514 --- /dev/null +++ b/cbits/posix/close_fds.c @@ -0,0 +1,22 @@ + +#include "common.h" + +#include + +#if defined(HAVE_CLOSERANGE) +#include +#endif + + +void closefrom_excluding(int lowfd, int excludingFd) { +#if defined(HAVE_CLOSERANGE) + close_range(lowfd, excludingFd - 1); + closefrom(excludingFd + 1); +#else + for (int i = lowfd; i < excludingFd; i++) { + close(i); + } + + closefrom(excludingFd + 1); +#endif +} diff --git a/cbits/posix/common.h b/cbits/posix/common.h index d7693ad8..1ec0492d 100644 --- a/cbits/posix/common.h +++ b/cbits/posix/common.h @@ -22,7 +22,8 @@ struct std_handle { }; }; -int get_max_fd(void); +void closefrom_excluding(int from, int excluding); +void closefrom(int lowfd); // defined in find_executable.c #if !defined(HAVE_EXECVPE) diff --git a/cbits/posix/fork_exec.c b/cbits/posix/fork_exec.c index dd6e58f1..8ce6f339 100644 --- a/cbits/posix/fork_exec.c +++ b/cbits/posix/fork_exec.c @@ -222,13 +222,7 @@ do_spawn_fork (char *const args[], setup_std_handle_fork(STDERR_FILENO, stdErrHdl, forkCommunicationFds[1]); if ((flags & RUN_PROCESS_IN_CLOSE_FDS) != 0) { - int max_fd = get_max_fd(); - // XXX Not the pipe - for (int i = 3; i < max_fd; i++) { - if (i != forkCommunicationFds[1]) { - close(i); - } - } + closefrom_excluding(3, forkCommunicationFds[1]); } /* Reset the SIGINT/SIGQUIT signal handlers in the child, if requested diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index bc350d97..3b7ab8ca 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -21,22 +21,6 @@ #include #endif -int -get_max_fd() -{ - static int cache = 0; - if (cache == 0) { -#if HAVE_SYSCONF - cache = sysconf(_SC_OPEN_MAX); - if (cache == -1) { - cache = 256; - } -#else - cache = 256; -#endif - } - return cache; -} // If a process was terminated by a signal, the exit status we return // via the System.Process API is (-signum). This encoding avoids collision with diff --git a/process.cabal b/process.cabal index fe7564e1..7169e5ab 100644 --- a/process.cabal +++ b/process.cabal @@ -66,6 +66,8 @@ library else c-sources: cbits/posix/runProcess.c + cbits/posix/bsd_closefrom.c + cbits/posix/close_fds.c cbits/posix/fork_exec.c cbits/posix/posix_spawn.c cbits/posix/find_executable.c From 6f0fdb31f7e9e88f8aeddb116e4c7dd9fa93316d Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 21 Jul 2022 21:30:36 -0700 Subject: [PATCH 02/13] Don't use separate close_fds.c file --- cbits/posix/close_fds.c | 22 ---------------------- cbits/posix/runProcess.c | 17 +++++++++++++++++ process.cabal | 1 - 3 files changed, 17 insertions(+), 23 deletions(-) delete mode 100644 cbits/posix/close_fds.c diff --git a/cbits/posix/close_fds.c b/cbits/posix/close_fds.c deleted file mode 100644 index e2747514..00000000 --- a/cbits/posix/close_fds.c +++ /dev/null @@ -1,22 +0,0 @@ - -#include "common.h" - -#include - -#if defined(HAVE_CLOSERANGE) -#include -#endif - - -void closefrom_excluding(int lowfd, int excludingFd) { -#if defined(HAVE_CLOSERANGE) - close_range(lowfd, excludingFd - 1); - closefrom(excludingFd + 1); -#else - for (int i = lowfd; i < excludingFd; i++) { - close(i); - } - - closefrom(excludingFd + 1); -#endif -} diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index 3b7ab8ca..89038149 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -21,6 +21,23 @@ #include #endif +#if defined(HAVE_CLOSERANGE) +#include +#endif + +void +closefrom_excluding(int lowfd, int excludingFd) { +#if defined(HAVE_CLOSERANGE) + close_range(lowfd, excludingFd - 1); + closefrom(excludingFd + 1); +#else + for (int i = lowfd; i < excludingFd; i++) { + close(i); + } + + closefrom(excludingFd + 1); +#endif +} // If a process was terminated by a signal, the exit status we return // via the System.Process API is (-signum). This encoding avoids collision with diff --git a/process.cabal b/process.cabal index 7169e5ab..3076fe00 100644 --- a/process.cabal +++ b/process.cabal @@ -67,7 +67,6 @@ library c-sources: cbits/posix/runProcess.c cbits/posix/bsd_closefrom.c - cbits/posix/close_fds.c cbits/posix/fork_exec.c cbits/posix/posix_spawn.c cbits/posix/find_executable.c From ecc497a81ab47963b365714626e96b5329a25947 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 22 Jul 2022 08:42:13 -0700 Subject: [PATCH 03/13] Fix up configure.ac checks --- cbits/posix/runProcess.c | 4 ++-- configure.ac | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index 89038149..190f3b31 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -21,13 +21,13 @@ #include #endif -#if defined(HAVE_CLOSERANGE) +#if defined(HAVE_CLOSE_RANGE) #include #endif void closefrom_excluding(int lowfd, int excludingFd) { -#if defined(HAVE_CLOSERANGE) +#if defined(HAVE_CLOSE_RANGE) close_range(lowfd, excludingFd - 1); closefrom(excludingFd + 1); #else diff --git a/configure.ac b/configure.ac index 367f14c1..59995af7 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,17 @@ AC_CHECK_HEADERS([signal.h sys/wait.h fcntl.h]) AC_CHECK_FUNCS([setitimer sysconf]) AC_CHECK_FUNCS([execvpe]) +# check for headers and functions used by bsd_closefrom.c +AC_CHECK_HEADERS([dirent.h fcntl.h libproc.h ndir.h sys/dir.h sys/ndir.h]) +AC_CHECK_FUNCS([ + closefrom + close_range + dirfd + proc_pid + proc_pidinfo + sysconf + ]) + # posix_spawn checks AC_CHECK_HEADERS([spawn.h]) AC_CHECK_FUNCS([posix_spawnp posix_spawn_file_actions_addchdir],[],[],[ From 8a2bf908ca719979638cb2fcf162b7fcf2738438 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 22 Jul 2022 08:55:15 -0700 Subject: [PATCH 04/13] Working on macros --- cbits/posix/bsd_closefrom.h | 6 ++++++ cbits/posix/common.h | 1 - cbits/posix/runProcess.c | 5 ++++- configure.ac | 19 ++++++++++--------- 4 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 cbits/posix/bsd_closefrom.h diff --git a/cbits/posix/bsd_closefrom.h b/cbits/posix/bsd_closefrom.h new file mode 100644 index 00000000..778f1fd2 --- /dev/null +++ b/cbits/posix/bsd_closefrom.h @@ -0,0 +1,6 @@ +#ifndef BSD_CLOSEFROM_H_ +#define BSD_CLOSEFROM_H_ + +void closefrom(int lowfd); + +#endif // BSD_CLOSEFROM_H_ diff --git a/cbits/posix/common.h b/cbits/posix/common.h index 1ec0492d..c8b77e00 100644 --- a/cbits/posix/common.h +++ b/cbits/posix/common.h @@ -23,7 +23,6 @@ struct std_handle { }; void closefrom_excluding(int from, int excluding); -void closefrom(int lowfd); // defined in find_executable.c #if !defined(HAVE_EXECVPE) diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index 190f3b31..db863b18 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -9,6 +9,8 @@ #if defined(HAVE_FORK) +#include "bsd_closefrom.h" + #include #include #include @@ -21,7 +23,8 @@ #include #endif -#if defined(HAVE_CLOSE_RANGE) +#if defined(HAVE_LINUX_CLOSE_RANGE_H) +#define _GNU_SOURCE #include #endif diff --git a/configure.ac b/configure.ac index 59995af7..63f49e7d 100644 --- a/configure.ac +++ b/configure.ac @@ -17,15 +17,16 @@ AC_CHECK_FUNCS([setitimer sysconf]) AC_CHECK_FUNCS([execvpe]) # check for headers and functions used by bsd_closefrom.c -AC_CHECK_HEADERS([dirent.h fcntl.h libproc.h ndir.h sys/dir.h sys/ndir.h]) -AC_CHECK_FUNCS([ - closefrom - close_range - dirfd - proc_pid - proc_pidinfo - sysconf - ]) +AC_CHECK_HEADERS([dirent.h fcntl.h libproc.h linux/close_range.h ndir.h sys/dir.h sys/ndir.h]) +AC_CHECK_FUNCS([closefrom close_range dirfd proc_pidinfo sysconf]) +AC_MSG_CHECKING([for /proc/pid/fd directory]) +if test -d "/proc/$$/fd" ; then + AC_DEFINE([HAVE_PROC_PID], [1], [Define if you have /proc/$pid/fd]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + # posix_spawn checks AC_CHECK_HEADERS([spawn.h]) From 4514e424409206ee930aad13a722b9405cb3587d Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 22 Jul 2022 09:16:23 -0700 Subject: [PATCH 05/13] Try doing runtime close_range syscall --- cbits/posix/runProcess.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index db863b18..68bddcfa 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -13,6 +13,7 @@ #include #include +#include #include #ifdef HAVE_FCNTL_H @@ -23,23 +24,23 @@ #include #endif -#if defined(HAVE_LINUX_CLOSE_RANGE_H) -#define _GNU_SOURCE -#include -#endif - void closefrom_excluding(int lowfd, int excludingFd) { -#if defined(HAVE_CLOSE_RANGE) - close_range(lowfd, excludingFd - 1); - closefrom(excludingFd + 1); -#else - for (int i = lowfd; i < excludingFd; i++) { - close(i); - } + // Try using the close_range syscall, provided in Linux kernel >= 5.9. + // We do this directly because not all C libs provide a wrapper (like musl) + long ret = syscall(SYS_close_range, lowfd, excludingFd - 1); - closefrom(excludingFd + 1); -#endif + if (ret != -1) { + // If that worked, closefrom the remaining range + closefrom(excludingFd + 1); + } else { + // Otherwise, fall back to a loop + closefrom + for (int i = lowfd; i < excludingFd; i++) { + close(i); + } + + closefrom(excludingFd + 1); + } } // If a process was terminated by a signal, the exit status we return From 9ca73a1e42a109f0848fb86d250193873f278448 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 22 Jul 2022 09:20:24 -0700 Subject: [PATCH 06/13] Add flags to syscall --- cbits/posix/runProcess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index 68bddcfa..53a2c52c 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -28,7 +28,7 @@ void closefrom_excluding(int lowfd, int excludingFd) { // Try using the close_range syscall, provided in Linux kernel >= 5.9. // We do this directly because not all C libs provide a wrapper (like musl) - long ret = syscall(SYS_close_range, lowfd, excludingFd - 1); + long ret = syscall(SYS_close_range, lowfd, excludingFd - 1, 0); if (ret != -1) { // If that worked, closefrom the remaining range From f08162d175b2bf9c02bcb46095245ac1b8542cdf Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 22 Jul 2022 09:46:57 -0700 Subject: [PATCH 07/13] Try hardcoding close_range syscall number for now --- cbits/posix/runProcess.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index 53a2c52c..966abf07 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -24,11 +24,13 @@ #include #endif +#define CLOSE_RANGE_SYSCALL_NUMBER 436 + void closefrom_excluding(int lowfd, int excludingFd) { // Try using the close_range syscall, provided in Linux kernel >= 5.9. // We do this directly because not all C libs provide a wrapper (like musl) - long ret = syscall(SYS_close_range, lowfd, excludingFd - 1, 0); + long ret = syscall(CLOSE_RANGE_SYSCALL_NUMBER, lowfd, excludingFd - 1, 0); if (ret != -1) { // If that worked, closefrom the remaining range From ddb388b75ca0233f3c20647b932c89bd2cb79d89 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 22 Jul 2022 10:19:42 -0700 Subject: [PATCH 08/13] Try fixing includes --- process.cabal | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/process.cabal b/process.cabal index 3076fe00..859fa25e 100644 --- a/process.cabal +++ b/process.cabal @@ -57,6 +57,11 @@ library if os(windows) c-sources: cbits/win32/runProcess.c + includes: + runProcess.h + install-includes: + runProcess.h + processFlags.h other-modules: System.Process.Windows build-depends: Win32 >=2.4 && < 2.14 -- ole32 and rpcrt4 are needed to create GUIDs for unique named pipes @@ -70,15 +75,17 @@ library cbits/posix/fork_exec.c cbits/posix/posix_spawn.c cbits/posix/find_executable.c + includes: + runProcess.h + cbits/posix/bsd_closefrom.h + install-includes: + runProcess.h + processFlags.h + cbits/posix/bsd_closefrom.h other-modules: System.Process.Posix build-depends: unix >= 2.5 && < 2.9 include-dirs: include - includes: - runProcess.h - install-includes: - runProcess.h - processFlags.h ghc-options: -Wall From b29f1f690b821cb2c4f96a720e3d687d6ca601e6 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 06:11:28 -0700 Subject: [PATCH 09/13] Check for and use SYS_close_range from sys/syscall.h --- cbits/posix/runProcess.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index 966abf07..64eb1717 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -24,13 +24,15 @@ #include #endif -#define CLOSE_RANGE_SYSCALL_NUMBER 436 - void closefrom_excluding(int lowfd, int excludingFd) { +#ifdef SYS_close_range // Try using the close_range syscall, provided in Linux kernel >= 5.9. // We do this directly because not all C libs provide a wrapper (like musl) - long ret = syscall(CLOSE_RANGE_SYSCALL_NUMBER, lowfd, excludingFd - 1, 0); + long ret = syscall(SYS_close_range, lowfd, excludingFd - 1, 0); +#else + long ret = -1; +#endif if (ret != -1) { // If that worked, closefrom the remaining range From 14eace2b59a1c49ed443eaae5a5a87caf2606c11 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 17:37:57 -0700 Subject: [PATCH 10/13] Go back to original install-includes --- process.cabal | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/process.cabal b/process.cabal index 859fa25e..4ef3eb3f 100644 --- a/process.cabal +++ b/process.cabal @@ -59,9 +59,6 @@ library cbits/win32/runProcess.c includes: runProcess.h - install-includes: - runProcess.h - processFlags.h other-modules: System.Process.Windows build-depends: Win32 >=2.4 && < 2.14 -- ole32 and rpcrt4 are needed to create GUIDs for unique named pipes @@ -78,14 +75,13 @@ library includes: runProcess.h cbits/posix/bsd_closefrom.h - install-includes: - runProcess.h - processFlags.h - cbits/posix/bsd_closefrom.h other-modules: System.Process.Posix build-depends: unix >= 2.5 && < 2.9 include-dirs: include + install-includes: + runProcess.h + processFlags.h ghc-options: -Wall From 7382f1c6a5a5e0749955031f8a2e7cb2def432b6 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 24 Mar 2023 01:36:30 -0700 Subject: [PATCH 11/13] Prefix all the symbols with `hs_process_` --- cbits/posix/bsd_closefrom.c | 16 ++++++++-------- cbits/posix/bsd_closefrom.h | 2 +- cbits/posix/common.h | 2 +- cbits/posix/fork_exec.c | 2 +- cbits/posix/runProcess.c | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cbits/posix/bsd_closefrom.c b/cbits/posix/bsd_closefrom.c index 5a5779e7..f6e6b12d 100644 --- a/cbits/posix/bsd_closefrom.c +++ b/cbits/posix/bsd_closefrom.c @@ -61,7 +61,7 @@ __unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26 * Close all file descriptors greater than or equal to lowfd. */ static void -closefrom_fallback(int lowfd) +hs_process_closefrom_fallback(int lowfd) { long fd, maxfd; @@ -85,13 +85,13 @@ closefrom_fallback(int lowfd) #ifdef HAVE_FCNTL_CLOSEM void -closefrom(int lowfd) +hs_process_closefrom(int lowfd) { (void) fcntl(lowfd, F_CLOSEM, 0); } #elif defined(HAVE_LIBPROC_H) && defined(HAVE_PROC_PIDINFO) void -closefrom(int lowfd) +hs_process_closefrom(int lowfd) { int i, r, sz; pid_t pid = getpid(); @@ -115,12 +115,12 @@ closefrom(int lowfd) return; fallback: free(fdinfo_buf); - closefrom_fallback(lowfd); + hs_process_closefrom_fallback(lowfd); return; } #elif defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) void -closefrom(int lowfd) +hs_process_closefrom(int lowfd) { long fd; char fdpath[PATH_MAX], *endp; @@ -141,13 +141,13 @@ closefrom(int lowfd) return; } /* /proc/$$/fd strategy failed, fall back to brute force closure */ - closefrom_fallback(lowfd); + hs_process_closefrom_fallback(lowfd); } #else void -closefrom(int lowfd) +hs_process_closefrom(int lowfd) { - closefrom_fallback(lowfd); + hs_process_closefrom_fallback(lowfd); } #endif /* !HAVE_FCNTL_CLOSEM */ #endif /* HAVE_CLOSEFROM */ diff --git a/cbits/posix/bsd_closefrom.h b/cbits/posix/bsd_closefrom.h index 778f1fd2..db7eb427 100644 --- a/cbits/posix/bsd_closefrom.h +++ b/cbits/posix/bsd_closefrom.h @@ -1,6 +1,6 @@ #ifndef BSD_CLOSEFROM_H_ #define BSD_CLOSEFROM_H_ -void closefrom(int lowfd); +void hs_process_closefrom(int lowfd); #endif // BSD_CLOSEFROM_H_ diff --git a/cbits/posix/common.h b/cbits/posix/common.h index c8b77e00..e0063eb9 100644 --- a/cbits/posix/common.h +++ b/cbits/posix/common.h @@ -22,7 +22,7 @@ struct std_handle { }; }; -void closefrom_excluding(int from, int excluding); +void hs_process_closefrom_excluding(int from, int excluding); // defined in find_executable.c #if !defined(HAVE_EXECVPE) diff --git a/cbits/posix/fork_exec.c b/cbits/posix/fork_exec.c index 8ce6f339..b35e9b13 100644 --- a/cbits/posix/fork_exec.c +++ b/cbits/posix/fork_exec.c @@ -222,7 +222,7 @@ do_spawn_fork (char *const args[], setup_std_handle_fork(STDERR_FILENO, stdErrHdl, forkCommunicationFds[1]); if ((flags & RUN_PROCESS_IN_CLOSE_FDS) != 0) { - closefrom_excluding(3, forkCommunicationFds[1]); + hs_process_closefrom_excluding(3, forkCommunicationFds[1]); } /* Reset the SIGINT/SIGQUIT signal handlers in the child, if requested diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c index 64eb1717..a4e40e5a 100644 --- a/cbits/posix/runProcess.c +++ b/cbits/posix/runProcess.c @@ -25,7 +25,7 @@ #endif void -closefrom_excluding(int lowfd, int excludingFd) { +hs_process_closefrom_excluding(int lowfd, int excludingFd) { #ifdef SYS_close_range // Try using the close_range syscall, provided in Linux kernel >= 5.9. // We do this directly because not all C libs provide a wrapper (like musl) @@ -36,14 +36,14 @@ closefrom_excluding(int lowfd, int excludingFd) { if (ret != -1) { // If that worked, closefrom the remaining range - closefrom(excludingFd + 1); + hs_process_closefrom(excludingFd + 1); } else { // Otherwise, fall back to a loop + closefrom for (int i = lowfd; i < excludingFd; i++) { close(i); } - closefrom(excludingFd + 1); + hs_process_closefrom(excludingFd + 1); } } From 7c9915a78b29d2d19a98e5bb786e89e833acb813 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 24 Mar 2023 02:18:28 -0700 Subject: [PATCH 12/13] Pick up a couple more changes from openssh-portable See: https://github.com/openssh/openssh-portable/commit/10b899a1 https://github.com/openssh/openssh-portable/commit/715c892f This brings our copy up to match openssh-portable as of Dec 22, 2021 --- cbits/posix/bsd_closefrom.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cbits/posix/bsd_closefrom.c b/cbits/posix/bsd_closefrom.c index f6e6b12d..301fdb36 100644 --- a/cbits/posix/bsd_closefrom.c +++ b/cbits/posix/bsd_closefrom.c @@ -14,10 +14,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef HAVE_CLOSEFROM +#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) #include -#include #include #include #ifdef HAVE_FCNTL_H @@ -128,6 +127,11 @@ hs_process_closefrom(int lowfd) DIR *dirp; int len; +#ifdef HAVE_CLOSE_RANGE + if (close_range(lowfd, INT_MAX, 0) == 0) + return; +#endif + /* Check for a /proc/$$/fd directory. */ len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); if (len > 0 && (size_t)len < sizeof(fdpath) && (dirp = opendir(fdpath))) { From 86d4c011152c228fad0dbf43e270a2eca29cae71 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 1 Apr 2023 16:15:24 -0700 Subject: [PATCH 13/13] Respond to review (add cbits/posix to include-dirs) --- process.cabal | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/process.cabal b/process.cabal index 4ef3eb3f..8aff4a98 100644 --- a/process.cabal +++ b/process.cabal @@ -57,6 +57,8 @@ library if os(windows) c-sources: cbits/win32/runProcess.c + include-dirs: + include includes: runProcess.h other-modules: System.Process.Windows @@ -72,13 +74,15 @@ library cbits/posix/fork_exec.c cbits/posix/posix_spawn.c cbits/posix/find_executable.c + include-dirs: + include + cbits/posix includes: runProcess.h - cbits/posix/bsd_closefrom.h + bsd_closefrom.h other-modules: System.Process.Posix build-depends: unix >= 2.5 && < 2.9 - include-dirs: include install-includes: runProcess.h processFlags.h