[openssh-commits] [openssh] 01/01: proc_pidinfo()-based closefrom() for OS X

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Aug 30 13:23:11 AEST 2019


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 28744182cf90e0073b76a9e98de58a47e688b2c4
Author: Damien Miller <djm at mindrot.org>
Date:   Fri Aug 30 13:21:38 2019 +1000

    proc_pidinfo()-based closefrom() for OS X
    
    Refactor closefrom() to use a single brute-force close() loop fallback.
    
    Based on patch from likan_999.student at sina.com in bz#3049. ok dtucker@
---
 configure.ac                   |  3 ++
 openbsd-compat/bsd-closefrom.c | 88 ++++++++++++++++++++++++++++++++----------
 2 files changed, 70 insertions(+), 21 deletions(-)

diff --git a/configure.ac b/configure.ac
index 1c35b090..8c6c4637 100644
--- a/configure.ac
+++ b/configure.ac
@@ -679,6 +679,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
 	AC_CHECK_LIB([sandbox], [sandbox_apply], [
 	    SSHDLIBS="$SSHDLIBS -lsandbox"
 	])
+	# proc_pidinfo()-based closefrom() replacement.
+	AC_CHECK_HEADERS([libproc.h])
+	AC_CHECK_FUNCS([proc_pidinfo])
 	;;
 *-*-dragonfly*)
 	SSHDLIBS="$SSHDLIBS -lcrypt"
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
index b56476a2..8b9a5627 100644
--- a/openbsd-compat/bsd-closefrom.c
+++ b/openbsd-compat/bsd-closefrom.c
@@ -46,6 +46,9 @@
 #  include <ndir.h>
 # endif
 #endif
+#if defined(HAVE_LIBPROC_H)
+# include <libproc.h>
+#endif
 
 #ifndef OPEN_MAX
 # define OPEN_MAX	256
@@ -55,21 +58,73 @@
 __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);
 }
-#else
+#elif defined(HAVE_LIBPROC_H) && defined(HAVE_PROC_PIDINFO)
 void
 closefrom(int lowfd)
 {
-    long fd, maxfd;
-#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID)
+	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 < sz / (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;
@@ -85,25 +140,16 @@ closefrom(int lowfd)
 		(void) close((int) fd);
 	}
 	(void) closedir(dirp);
-    } else
-#endif
-    {
-	/*
-	 * 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);
+	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 */

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list