diff options
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | openbsd-compat/bsd-closefrom.c | 88 |
2 files changed, 70 insertions, 21 deletions
diff --git a/configure.ac b/configure.ac index 1c35b090b..8c6c4637c 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -679,6 +679,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) | |||
679 | AC_CHECK_LIB([sandbox], [sandbox_apply], [ | 679 | AC_CHECK_LIB([sandbox], [sandbox_apply], [ |
680 | SSHDLIBS="$SSHDLIBS -lsandbox" | 680 | SSHDLIBS="$SSHDLIBS -lsandbox" |
681 | ]) | 681 | ]) |
682 | # proc_pidinfo()-based closefrom() replacement. | ||
683 | AC_CHECK_HEADERS([libproc.h]) | ||
684 | AC_CHECK_FUNCS([proc_pidinfo]) | ||
682 | ;; | 685 | ;; |
683 | *-*-dragonfly*) | 686 | *-*-dragonfly*) |
684 | SSHDLIBS="$SSHDLIBS -lcrypt" | 687 | SSHDLIBS="$SSHDLIBS -lcrypt" |
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c index b56476a2d..8b9a56278 100644 --- a/openbsd-compat/bsd-closefrom.c +++ b/openbsd-compat/bsd-closefrom.c | |||
@@ -46,6 +46,9 @@ | |||
46 | # include <ndir.h> | 46 | # include <ndir.h> |
47 | # endif | 47 | # endif |
48 | #endif | 48 | #endif |
49 | #if defined(HAVE_LIBPROC_H) | ||
50 | # include <libproc.h> | ||
51 | #endif | ||
49 | 52 | ||
50 | #ifndef OPEN_MAX | 53 | #ifndef OPEN_MAX |
51 | # define OPEN_MAX 256 | 54 | # define OPEN_MAX 256 |
@@ -55,21 +58,73 @@ | |||
55 | __unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; | 58 | __unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; |
56 | #endif /* lint */ | 59 | #endif /* lint */ |
57 | 60 | ||
61 | #ifndef HAVE_FCNTL_CLOSEM | ||
58 | /* | 62 | /* |
59 | * Close all file descriptors greater than or equal to lowfd. | 63 | * Close all file descriptors greater than or equal to lowfd. |
60 | */ | 64 | */ |
65 | static void | ||
66 | closefrom_fallback(int lowfd) | ||
67 | { | ||
68 | long fd, maxfd; | ||
69 | |||
70 | /* | ||
71 | * Fall back on sysconf() or getdtablesize(). We avoid checking | ||
72 | * resource limits since it is possible to open a file descriptor | ||
73 | * and then drop the rlimit such that it is below the open fd. | ||
74 | */ | ||
75 | #ifdef HAVE_SYSCONF | ||
76 | maxfd = sysconf(_SC_OPEN_MAX); | ||
77 | #else | ||
78 | maxfd = getdtablesize(); | ||
79 | #endif /* HAVE_SYSCONF */ | ||
80 | if (maxfd < 0) | ||
81 | maxfd = OPEN_MAX; | ||
82 | |||
83 | for (fd = lowfd; fd < maxfd; fd++) | ||
84 | (void) close((int) fd); | ||
85 | } | ||
86 | #endif /* HAVE_FCNTL_CLOSEM */ | ||
87 | |||
61 | #ifdef HAVE_FCNTL_CLOSEM | 88 | #ifdef HAVE_FCNTL_CLOSEM |
62 | void | 89 | void |
63 | closefrom(int lowfd) | 90 | closefrom(int lowfd) |
64 | { | 91 | { |
65 | (void) fcntl(lowfd, F_CLOSEM, 0); | 92 | (void) fcntl(lowfd, F_CLOSEM, 0); |
66 | } | 93 | } |
67 | #else | 94 | #elif defined(HAVE_LIBPROC_H) && defined(HAVE_PROC_PIDINFO) |
68 | void | 95 | void |
69 | closefrom(int lowfd) | 96 | closefrom(int lowfd) |
70 | { | 97 | { |
71 | long fd, maxfd; | 98 | int i, r, sz; |
72 | #if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) | 99 | pid_t pid = getpid(); |
100 | struct proc_fdinfo *fdinfo_buf = NULL; | ||
101 | |||
102 | sz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); | ||
103 | if (sz == 0) | ||
104 | return; /* no fds, really? */ | ||
105 | else if (sz == -1) | ||
106 | goto fallback; | ||
107 | if ((fdinfo_buf = malloc(sz)) == NULL) | ||
108 | goto fallback; | ||
109 | r = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fdinfo_buf, sz); | ||
110 | if (r < 0 || r >= sz) | ||
111 | goto fallback; | ||
112 | for (i = 0; i < sz / (int)PROC_PIDLISTFD_SIZE; i++) { | ||
113 | if (fdinfo_buf[i].proc_fd >= lowfd) | ||
114 | close(fdinfo_buf[i].proc_fd); | ||
115 | } | ||
116 | free(fdinfo_buf); | ||
117 | return; | ||
118 | fallback: | ||
119 | free(fdinfo_buf); | ||
120 | closefrom_fallback(lowfd); | ||
121 | return; | ||
122 | } | ||
123 | #elif defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) | ||
124 | void | ||
125 | closefrom(int lowfd) | ||
126 | { | ||
127 | long fd; | ||
73 | char fdpath[PATH_MAX], *endp; | 128 | char fdpath[PATH_MAX], *endp; |
74 | struct dirent *dent; | 129 | struct dirent *dent; |
75 | DIR *dirp; | 130 | DIR *dirp; |
@@ -85,25 +140,16 @@ closefrom(int lowfd) | |||
85 | (void) close((int) fd); | 140 | (void) close((int) fd); |
86 | } | 141 | } |
87 | (void) closedir(dirp); | 142 | (void) closedir(dirp); |
88 | } else | 143 | return; |
89 | #endif | ||
90 | { | ||
91 | /* | ||
92 | * Fall back on sysconf() or getdtablesize(). We avoid checking | ||
93 | * resource limits since it is possible to open a file descriptor | ||
94 | * and then drop the rlimit such that it is below the open fd. | ||
95 | */ | ||
96 | #ifdef HAVE_SYSCONF | ||
97 | maxfd = sysconf(_SC_OPEN_MAX); | ||
98 | #else | ||
99 | maxfd = getdtablesize(); | ||
100 | #endif /* HAVE_SYSCONF */ | ||
101 | if (maxfd < 0) | ||
102 | maxfd = OPEN_MAX; | ||
103 | |||
104 | for (fd = lowfd; fd < maxfd; fd++) | ||
105 | (void) close((int) fd); | ||
106 | } | 144 | } |
145 | /* /proc/$$/fd strategy failed, fall back to brute force closure */ | ||
146 | closefrom_fallback(lowfd); | ||
147 | } | ||
148 | #else | ||
149 | void | ||
150 | closefrom(int lowfd) | ||
151 | { | ||
152 | closefrom_fallback(lowfd); | ||
107 | } | 153 | } |
108 | #endif /* !HAVE_FCNTL_CLOSEM */ | 154 | #endif /* !HAVE_FCNTL_CLOSEM */ |
109 | #endif /* HAVE_CLOSEFROM */ | 155 | #endif /* HAVE_CLOSEFROM */ |