From 01a8fd6567f520a5e8b0d6262f05c645f02e69a1 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Tue, 6 Sep 2016 02:56:34 +0200 Subject: [PATCH] Add closefrom(2) from openssh-portable --- configure | 109 +++++++++++++++++++++++++++++++++++++++++ doas.c | 2 +- libopenbsd/closefrom.c | 109 +++++++++++++++++++++++++++++++++++++++++ libopenbsd/openbsd.h | 3 ++ 4 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 libopenbsd/closefrom.c diff --git a/configure b/configure index c5a4c39..44879d4 100755 --- a/configure +++ b/configure @@ -350,6 +350,115 @@ check_func "pledge" "$src" || { printf 'OPENBSD += pledge-noop.o\n' >>$CONFIG_MK } +# +# Check for closefrom(). +# +src=' +#include +int main(void) { + closefrom(0); + return 0; +}' +check_func "closefrom" "$src" || { + printf 'OPENBSD += closefrom.o\n' >>$CONFIG_MK +} + +# +# Check for sysconf(). +# +src=' +#include +int main(void) { + (void)sysconf(0); + return 0; +}' +check_func "sysconf" "$src" + +# +# Check for /proc/$PID. +# +printf 'Checking for %-14s\t\t' "/proc/\$PID ..." >&2 +if test -d /proc/$$; then + printf 'yes.\n' >&2 + printf 'CFLAGS += -DHAVE_%s\n' "PROC_PID" >>$CONFIG_MK +else + printf 'no.\n' >&2 +fi + +# +# Check for dirfd(). +# +src=' +#include +int main(void) { + (void)dirfd(0); + return 0; +}' +check_func "dirfd" "$src" + +# +# Check for fcntl.h. +# +src=' +#include +int main(void) { + return 0; +}' +check_func "fcntl_h" "$src" + +# +# Check for F_CLOSEM. +# +src=' +#include +#ifndef F_CLOSEM +#error no F_CLOSEM +#endif +int main(void) { + return 0; +}' +check_func "F_CLOSEM" "$src" + +# +# Check for dirent.h. +# +src=' +#include +int main(void) { + return 0; +}' +check_func "dirent_h" "$src" + +# +# Check for sys/ndir.h. +# +src=' +#include +int main(void) { + return 0; +}' +check_func "sys_ndir_h" "$src" + +# +# Check for sys/dir.h. +# +src=' +#include +int main(void) { + return 0; +}' +check_func "sys_dir_h" "$src" + +# +# Check for ndir.h. +# +src=' +#include +int main(void) { + return 0; +}' +check_func "ndir_h" "$src" + # # # diff --git a/doas.c b/doas.c index 7494b07..d4d87cb 100644 --- a/doas.c +++ b/doas.c @@ -252,7 +252,7 @@ main(int argc, char **argv) if (pledge("stdio rpath getpw tty recvfd proc exec id", NULL) == -1) err(1, "pledge"); - /* closefrom(STDERR_FILENO + 1); */ + closefrom(STDERR_FILENO + 1); uid = getuid(); diff --git a/libopenbsd/closefrom.c b/libopenbsd/closefrom.c new file mode 100644 index 0000000..9380b33 --- /dev/null +++ b/libopenbsd/closefrom.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2004-2005 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifndef HAVE_CLOSEFROM + +#include +#include +#include +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif + +#ifndef OPEN_MAX +# define OPEN_MAX 256 +#endif + +#if 0 +__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; +#endif /* lint */ + +/* + * Close all file descriptors greater than or equal to lowfd. + */ +#ifdef HAVE_FCNTL_CLOSEM +void +closefrom(int lowfd) +{ + (void) fcntl(lowfd, F_CLOSEM, 0); +} +#else +void +closefrom(int lowfd) +{ + long fd, maxfd; +#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) + char fdpath[PATH_MAX], *endp; + struct dirent *dent; + DIR *dirp; + int len; + + /* 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))) { + while ((dent = readdir(dirp)) != NULL) { + fd = strtol(dent->d_name, &endp, 10); + if (dent->d_name != endp && *endp == '\0' && + fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) + (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); + } +} +#endif /* !HAVE_FCNTL_CLOSEM */ +#endif /* HAVE_CLOSEFROM */ diff --git a/libopenbsd/openbsd.h b/libopenbsd/openbsd.h index 0586844..d9d3c99 100644 --- a/libopenbsd/openbsd.h +++ b/libopenbsd/openbsd.h @@ -41,6 +41,9 @@ int setresuid(uid_t, uid_t, uid_t); #ifndef HAVE_PLEDGE int pledge(const char *promises, const char *paths[]); #endif /* !HAVE_PLEDGE */ +#ifndef HAVE_CLOSEFROM +void closefrom(int); +#endif /* !HAVE_CLOSEFROM */ /* err.h */ #ifndef HAVE_VERRC -- 2.39.2