[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