1137015Sdes/* 2162852Sdes * Copyright (c) 2004-2005 Todd C. Miller <Todd.Miller@courtesan.com> 3137015Sdes * 4137015Sdes * Permission to use, copy, modify, and distribute this software for any 5137015Sdes * purpose with or without fee is hereby granted, provided that the above 6137015Sdes * copyright notice and this permission notice appear in all copies. 7137015Sdes * 8137015Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9137015Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10137015Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11137015Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12137015Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13137015Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14137015Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15137015Sdes */ 16137015Sdes 17137015Sdes#include "includes.h" 18137015Sdes 19137015Sdes#ifndef HAVE_CLOSEFROM 20137015Sdes 21137015Sdes#include <sys/types.h> 22137015Sdes#include <sys/param.h> 23137015Sdes#include <unistd.h> 24137015Sdes#include <stdio.h> 25162852Sdes#ifdef HAVE_FCNTL_H 26162852Sdes# include <fcntl.h> 27162852Sdes#endif 28137015Sdes#include <limits.h> 29137015Sdes#include <stdlib.h> 30137015Sdes#include <stddef.h> 31162852Sdes#include <string.h> 32162852Sdes#include <unistd.h> 33137015Sdes#ifdef HAVE_DIRENT_H 34137015Sdes# include <dirent.h> 35137015Sdes# define NAMLEN(dirent) strlen((dirent)->d_name) 36137015Sdes#else 37137015Sdes# define dirent direct 38137015Sdes# define NAMLEN(dirent) (dirent)->d_namlen 39137015Sdes# ifdef HAVE_SYS_NDIR_H 40137015Sdes# include <sys/ndir.h> 41137015Sdes# endif 42137015Sdes# ifdef HAVE_SYS_DIR_H 43137015Sdes# include <sys/dir.h> 44137015Sdes# endif 45137015Sdes# ifdef HAVE_NDIR_H 46137015Sdes# include <ndir.h> 47137015Sdes# endif 48137015Sdes#endif 49137015Sdes 50137015Sdes#ifndef OPEN_MAX 51137015Sdes# define OPEN_MAX 256 52137015Sdes#endif 53137015Sdes 54162852Sdes#if 0 55162852Sdes__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; 56137015Sdes#endif /* lint */ 57137015Sdes 58137015Sdes/* 59137015Sdes * Close all file descriptors greater than or equal to lowfd. 60137015Sdes */ 61162852Sdes#ifdef HAVE_FCNTL_CLOSEM 62137015Sdesvoid 63137015Sdesclosefrom(int lowfd) 64137015Sdes{ 65162852Sdes (void) fcntl(lowfd, F_CLOSEM, 0); 66162852Sdes} 67162852Sdes#else 68162852Sdesvoid 69162852Sdesclosefrom(int lowfd) 70162852Sdes{ 71137015Sdes long fd, maxfd; 72137015Sdes#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) 73137015Sdes char fdpath[PATH_MAX], *endp; 74137015Sdes struct dirent *dent; 75137015Sdes DIR *dirp; 76137015Sdes int len; 77137015Sdes 78137015Sdes /* Check for a /proc/$$/fd directory. */ 79137015Sdes len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); 80162852Sdes if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { 81137015Sdes while ((dent = readdir(dirp)) != NULL) { 82137015Sdes fd = strtol(dent->d_name, &endp, 10); 83137015Sdes if (dent->d_name != endp && *endp == '\0' && 84137015Sdes fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) 85137015Sdes (void) close((int) fd); 86137015Sdes } 87137015Sdes (void) closedir(dirp); 88137015Sdes } else 89137015Sdes#endif 90137015Sdes { 91137015Sdes /* 92137015Sdes * Fall back on sysconf() or getdtablesize(). We avoid checking 93137015Sdes * resource limits since it is possible to open a file descriptor 94137015Sdes * and then drop the rlimit such that it is below the open fd. 95137015Sdes */ 96137015Sdes#ifdef HAVE_SYSCONF 97137015Sdes maxfd = sysconf(_SC_OPEN_MAX); 98137015Sdes#else 99137015Sdes maxfd = getdtablesize(); 100137015Sdes#endif /* HAVE_SYSCONF */ 101137015Sdes if (maxfd < 0) 102137015Sdes maxfd = OPEN_MAX; 103137015Sdes 104137015Sdes for (fd = lowfd; fd < maxfd; fd++) 105137015Sdes (void) close((int) fd); 106137015Sdes } 107137015Sdes} 108162852Sdes#endif /* !HAVE_FCNTL_CLOSEM */ 109137015Sdes#endif /* HAVE_CLOSEFROM */ 110