]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
proc_pidinfo()-based closefrom() for OS X
authorDamien Miller <djm@mindrot.org>
Fri, 30 Aug 2019 03:21:38 +0000 (13:21 +1000)
committerDamien Miller <djm@mindrot.org>
Fri, 30 Aug 2019 03:23:04 +0000 (13:23 +1000)
Refactor closefrom() to use a single brute-force close() loop fallback.

Based on patch from likan_999.student@sina.com in bz#3049. ok dtucker@

configure.ac
openbsd-compat/bsd-closefrom.c

index 1c35b090b9e5572deef38ed9f0c0ec5c3ded9f30..8c6c4637c9cff0c8eb052cbee8993902730189fe 100644 (file)
@@ -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"
index b56476a2d85895d1d378ffeeba09da892552ce3f..8b9a5627878ef4645026eb1e6c7fef38a73e62a9 100644 (file)
@@ -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
 __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 */