From: Todd C. Miller Date: Sat, 9 Jun 2007 11:26:43 +0000 (+0000) Subject: Use /proc/self/fd instead of /proc/$$/fd X-Git-Tag: SUDO_1_7_0~565 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ae409b8f230eccada72cfe7a28876f283e99423;p=sudo Use /proc/self/fd instead of /proc/$$/fd Move old-style fd closing into closefrom_fallback() and call that if /proc/self/fd doesn't exist or the F_CLOSEM fcntl() fails --- diff --git a/closefrom.c b/closefrom.c index 03ee1b2c6..a6118b83b 100644 --- a/closefrom.c +++ b/closefrom.c @@ -51,31 +51,64 @@ __unused static const char rcsid[] = "$Sudo$"; #endif /* lint */ +#ifndef HAVE_FCNTL_CLOSEM +# ifndef HAVE_DIRFD +# define closefrom_fallback closefrom +# endif +#endif + /* * Close all file descriptors greater than or equal to lowfd. + * This is the expensive (ballback) method. + */ +void +closefrom_fallback(lowfd) + 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); +} + +/* + * Close all file descriptors greater than or equal to lowfd. + * We try the fast way first, falling back on the slow method. */ #ifdef HAVE_FCNTL_CLOSEM void closefrom(lowfd) int lowfd; { - (void) fcntl(lowfd, F_CLOSEM, 0); + if (fcntl(lowfd, F_CLOSEM, 0) == -1) + closefrom_fallback(lowfd); } #else +# ifdef HAVE_DIRFD void closefrom(lowfd) int lowfd; { - long fd, maxfd; -#ifdef HAVE_DIRFD - char fdpath[PATH_MAX], *endp; struct dirent *dent; DIR *dirp; - int len; + char *endp; + long fd; - /* 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))) { + /* Use /proc/self/fd directory if it exists. */ + if ((dirp = opendir("/proc/self/fd")) != NULL) { while ((dent = readdir(dirp)) != NULL) { fd = strtol(dent->d_name, &endp, 10); if (dent->d_name != endp && *endp == '\0' && @@ -84,23 +117,7 @@ closefrom(lowfd) } (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); - } + closefrom_fallback(lowfd); } -#endif /* !HAVE_FCNTL_CLOSEM */ +#endif /* HAVE_DIRFD */ +#endif /* HAVE_FCNTL_CLOSEM */