opendoas

A portable version of the OpenBSD `doas` command
git clone https://pi.duncano.de/git/opendoas.git
Log | Files | Refs | README | LICENSE

commit 01a8fd6567f520a5e8b0d6262f05c645f02e69a1
parent fc4df78fd381731e8125ddd7afa251bd00975e60
Author: Duncaen <mail@duncano.de>
Date:   Tue,  6 Sep 2016 02:56:34 +0200

Add closefrom(2) from openssh-portable

Diffstat:
configure | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
doas.c | 2+-
libopenbsd/closefrom.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
libopenbsd/openbsd.h | 3+++
4 files changed, 222 insertions(+), 1 deletion(-)

diff --git a/configure b/configure @@ -351,6 +351,115 @@ check_func "pledge" "$src" || { } # +# Check for closefrom(). +# +src=' +#include <unistd.h> +int main(void) { + closefrom(0); + return 0; +}' +check_func "closefrom" "$src" || { + printf 'OPENBSD += closefrom.o\n' >>$CONFIG_MK +} + +# +# Check for sysconf(). +# +src=' +#include <unistd.h> +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 <dirent.h> +int main(void) { + (void)dirfd(0); + return 0; +}' +check_func "dirfd" "$src" + +# +# Check for fcntl.h. +# +src=' +#include <fcntl.h> +int main(void) { + return 0; +}' +check_func "fcntl_h" "$src" + +# +# Check for F_CLOSEM. +# +src=' +#include <fcntl.h> +#ifndef F_CLOSEM +#error no F_CLOSEM +#endif +int main(void) { + return 0; +}' +check_func "F_CLOSEM" "$src" + +# +# Check for dirent.h. +# +src=' +#include <dirent.h> +int main(void) { + return 0; +}' +check_func "dirent_h" "$src" + +# +# Check for sys/ndir.h. +# +src=' +#include <sys/ndir.h> +int main(void) { + return 0; +}' +check_func "sys_ndir_h" "$src" + +# +# Check for sys/dir.h. +# +src=' +#include <sys/dir.h> +int main(void) { + return 0; +}' +check_func "sys_dir_h" "$src" + +# +# Check for ndir.h. +# +src=' +#include <ndir.h> +int main(void) { + return 0; +}' +check_func "ndir_h" "$src" + +# # # src=' diff --git 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 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2004-2005 Todd C. Miller <Todd.Miller@courtesan.com> + * + * 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 <sys/types.h> +#include <sys/param.h> +#include <unistd.h> +#include <stdio.h> +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#endif +#include <limits.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <unistd.h> +#ifdef HAVE_DIRENT_H +# include <dirent.h> +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# ifdef HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# ifdef HAVE_NDIR_H +# include <ndir.h> +# 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 @@ -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