1bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2004-2005 Todd C. Miller <Todd.Miller@courtesan.com> 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Permission to use, copy, modify, and distribute this software for any 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * purpose with or without fee is hereby granted, provided that the above 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * copyright notice and this permission notice appear in all copies. 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifndef HAVE_CLOSEFROM 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/param.h> 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <unistd.h> 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdio.h> 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_FCNTL_H 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <fcntl.h> 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <limits.h> 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdlib.h> 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stddef.h> 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <unistd.h> 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_DIRENT_H 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <dirent.h> 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# define NAMLEN(dirent) strlen((dirent)->d_name) 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#else 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# define dirent direct 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# define NAMLEN(dirent) (dirent)->d_namlen 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# ifdef HAVE_SYS_NDIR_H 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <sys/ndir.h> 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# endif 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# ifdef HAVE_SYS_DIR_H 43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <sys/dir.h> 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# endif 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# ifdef HAVE_NDIR_H 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <ndir.h> 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# endif 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifndef OPEN_MAX 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# define OPEN_MAX 256 52bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#if 0 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* lint */ 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Close all file descriptors greater than or equal to lowfd. 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_FCNTL_CLOSEM 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanclosefrom(int lowfd) 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (void) fcntl(lowfd, F_CLOSEM, 0); 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#else 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanclosefrom(int lowfd) 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman long fd, maxfd; 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) 73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char fdpath[PATH_MAX], *endp; 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct dirent *dent; 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman DIR *dirp; 76bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int len; 77bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 78bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Check for a /proc/$$/fd directory. */ 79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { 81bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman while ((dent = readdir(dirp)) != NULL) { 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd = strtol(dent->d_name, &endp, 10); 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (dent->d_name != endp && *endp == '\0' && 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (void) close((int) fd); 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (void) closedir(dirp); 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 90bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman { 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Fall back on sysconf() or getdtablesize(). We avoid checking 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * resource limits since it is possible to open a file descriptor 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * and then drop the rlimit such that it is below the open fd. 95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_SYSCONF 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman maxfd = sysconf(_SC_OPEN_MAX); 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#else 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman maxfd = getdtablesize(); 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* HAVE_SYSCONF */ 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (maxfd < 0) 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman maxfd = OPEN_MAX; 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (fd = lowfd; fd < maxfd; fd++) 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (void) close((int) fd); 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* !HAVE_FCNTL_CLOSEM */ 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* HAVE_CLOSEFROM */ 110