opendoas

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

commit f577047ea6e6f0e4e4225200504fd694681dbed2
parent 4f7ed3854a4db241401f5b84cbb6246a06a17561
Author: Duncaen <mail@duncano.de>
Date:   Wed,  8 Jun 2016 18:01:25 +0200

remove pledge seccomp shim

This will never work, seccomp can't filter for paths (pointer) and all
rules are inherited by child processes.
pledge does not limit processes executed by execve.

Diffstat:
configure | 27++-------------------------
libopenbsd/pledge-seccomp.c | 411-------------------------------------------------------------------------------
libopenbsd/pledge-seccomp.h | 49-------------------------------------------------
3 files changed, 2 insertions(+), 485 deletions(-)

diff --git a/configure b/configure @@ -22,7 +22,6 @@ usage: configure [options] --target=target-alias the machine that CC will produce code for --enable-debug enable debugging - --enable-seccomp enable seccomp --enable-static prepare for static build --help, -h display this help and exit @@ -45,7 +44,6 @@ for x; do --host) HOST=$var;; --target) TARGET=$var;; --enable-debug) DEBUG=yes;; - --enable-seccomp) BUILD_SECCOMP=yes;; --enable-static) BUILD_STATIC=yes;; --help|-h) usage;; *) die "Error: unknown option $opt";; @@ -316,27 +314,6 @@ int main(void) { pledge("", NULL); return 0; }' -check_func "pledge" "$src" && { - have_pledge=1 -} - -# -# Check for seccomp.h -# -src=' -#include <linux/seccomp.h> -#include <sys/prctl.h> -#include <unistd.h> -int main(void) { - prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL); - return 0; -}' -[ -z "$have_pledge" -a -n "$BUILD_SECCOMP" ] && \ - check_func "seccomp_h" "$src" && \ - { - have_pledge=1 - printf 'OPENBSD += pledge-seccomp.o\n' >>$CONFIG_MK - } - -[ -z "$have_pledge" ] && \ +check_func "pledge" "$src" || { printf 'OPENBSD += pledge-noop.o\n' >>$CONFIG_MK +} diff --git a/libopenbsd/pledge-seccomp.c b/libopenbsd/pledge-seccomp.c @@ -1,411 +0,0 @@ -/* $OpenBSD: kern_pledge.c,v 1.165 2016/04/28 14:25:08 beck Exp $ */ - -/* - * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org> - * Copyright (c) 2015 Theo de Raadt <deraadt@openbsd.org> - * - * 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 <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <seccomp.h> -#include <errno.h> -#include <unistd.h> -#include <sys/syscall.h> -#include <err.h> - -#include "openbsd.h" -#include "pledge.h" - -#define SYS_MAXSYSCALL 1000 - -/* - * Ordered in blocks starting with least risky and most required. - */ -const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = { - /* - * Minimum required - */ - [SYS_exit] = PLEDGE_ALWAYS, - // [SYS_kbind] = PLEDGE_ALWAYS, - // [SYS___get_tcb] = PLEDGE_ALWAYS, - // [SYS_pledge] = PLEDGE_ALWAYS, - // [SYS_sendsyslog] = PLEDGE_ALWAYS, /* stack protector reporting */ - // [SYS_osendsyslog] = PLEDGE_ALWAYS, /* obsolete sendsyslog */ - // [SYS_thrkill] = PLEDGE_ALWAYS, /* raise, abort, stack pro */ - // [SYS_utrace] = PLEDGE_ALWAYS, /* ltrace(1) from ld.so */ - - /* "getting" information about self is considered safe */ - [SYS_getuid] = PLEDGE_STDIO, - [SYS_geteuid] = PLEDGE_STDIO, - [SYS_getresuid] = PLEDGE_STDIO, - [SYS_getgid] = PLEDGE_STDIO, - [SYS_getegid] = PLEDGE_STDIO, - [SYS_getresgid] = PLEDGE_STDIO, - [SYS_getgroups] = PLEDGE_STDIO, - // [SYS_getlogin59] = PLEDGE_STDIO, - // [SYS_getlogin_r] = PLEDGE_STDIO, - [SYS_getpgrp] = PLEDGE_STDIO, - [SYS_getpgid] = PLEDGE_STDIO, - [SYS_getppid] = PLEDGE_STDIO, - [SYS_getsid] = PLEDGE_STDIO, - // [SYS_getthrid] = PLEDGE_STDIO, - [SYS_getrlimit] = PLEDGE_STDIO, - [SYS_gettimeofday] = PLEDGE_STDIO, - // [SYS_getdtablecount] = PLEDGE_STDIO, - [SYS_getrusage] = PLEDGE_STDIO, - // [SYS_issetugid] = PLEDGE_STDIO, - [SYS_clock_getres] = PLEDGE_STDIO, - [SYS_clock_gettime] = PLEDGE_STDIO, - [SYS_getpid] = PLEDGE_STDIO, - - /* - * Almost exclusively read-only, Very narrow subset. - * Use of "route", "inet", "dns", "ps", or "vminfo" - * expands access. - */ - // [SYS_sysctl] = PLEDGE_STDIO, - - /* Support for malloc(3) family of operations */ - // [SYS_getentropy] = PLEDGE_STDIO, - [SYS_madvise] = PLEDGE_STDIO, - // [SYS_minherit] = PLEDGE_STDIO, - [SYS_mmap] = PLEDGE_STDIO, - [SYS_mprotect] = PLEDGE_STDIO, - // [SYS_mquery] = PLEDGE_STDIO, - [SYS_munmap] = PLEDGE_STDIO, - [SYS_msync] = PLEDGE_STDIO, - // [SYS_break] = PLEDGE_STDIO, - - [SYS_umask] = PLEDGE_STDIO, - - /* read/write operations */ - [SYS_read] = PLEDGE_STDIO, - [SYS_readv] = PLEDGE_STDIO, - // [SYS_pread] = PLEDGE_STDIO, - [SYS_preadv] = PLEDGE_STDIO, - [SYS_write] = PLEDGE_STDIO, - [SYS_writev] = PLEDGE_STDIO, - // [SYS_pwrite] = PLEDGE_STDIO, - [SYS_pwritev] = PLEDGE_STDIO, - [SYS_recvmsg] = PLEDGE_STDIO, - [SYS_recvfrom] = PLEDGE_STDIO | PLEDGE_YPACTIVE, - [SYS_ftruncate] = PLEDGE_STDIO, - [SYS_lseek] = PLEDGE_STDIO, - // [SYS_fpathconf] = PLEDGE_STDIO, - - /* - * Address selection required a network pledge ("inet", - * "unix", "dns". - */ - [SYS_sendto] = PLEDGE_STDIO | PLEDGE_YPACTIVE, - - /* - * Address specification required a network pledge ("inet", - * "unix", "dns". SCM_RIGHTS requires "sendfd" or "recvfd". - */ - [SYS_sendmsg] = PLEDGE_STDIO, - - /* Common signal operations */ - [SYS_nanosleep] = PLEDGE_STDIO, - [SYS_sigaltstack] = PLEDGE_STDIO, - // [SYS_sigprocmask] = PLEDGE_STDIO, - // [SYS_sigsuspend] = PLEDGE_STDIO, - // [SYS_sigaction] = PLEDGE_STDIO, - // [SYS_sigreturn] = PLEDGE_STDIO, - // [SYS_sigpending] = PLEDGE_STDIO, - [SYS_getitimer] = PLEDGE_STDIO, - [SYS_setitimer] = PLEDGE_STDIO, - - /* - * To support event driven programming. - */ - [SYS_poll] = PLEDGE_STDIO, - [SYS_ppoll] = PLEDGE_STDIO, - // [SYS_kevent] = PLEDGE_STDIO, - // [SYS_kqueue] = PLEDGE_STDIO, - [SYS_select] = PLEDGE_STDIO, - // [SYS_pselect] = PLEDGE_STDIO, - [SYS_pselect6] = PLEDGE_STDIO, - [SYS_epoll_create] = PLEDGE_STDIO, - [SYS_epoll_create1] = PLEDGE_STDIO, - [SYS_epoll_ctl] = PLEDGE_STDIO, - [SYS_epoll_pwait] = PLEDGE_STDIO, - [SYS_epoll_wait] = PLEDGE_STDIO, - [SYS_eventfd] = PLEDGE_STDIO, - [SYS_eventfd2] = PLEDGE_STDIO, - - [SYS_fstat] = PLEDGE_STDIO, - [SYS_fsync] = PLEDGE_STDIO, - - [SYS_setsockopt] = PLEDGE_STDIO, /* narrow whitelist */ - [SYS_getsockopt] = PLEDGE_STDIO, /* narrow whitelist */ - - /* F_SETOWN requires PLEDGE_PROC */ - [SYS_fcntl] = PLEDGE_STDIO, - - [SYS_close] = PLEDGE_STDIO, - [SYS_dup] = PLEDGE_STDIO, - [SYS_dup2] = PLEDGE_STDIO, - [SYS_dup3] = PLEDGE_STDIO, - // [SYS_closefrom] = PLEDGE_STDIO, - [SYS_shutdown] = PLEDGE_STDIO, - [SYS_fchdir] = PLEDGE_STDIO, /* XXX consider tightening */ - - [SYS_pipe] = PLEDGE_STDIO, - [SYS_pipe2] = PLEDGE_STDIO, - [SYS_socketpair] = PLEDGE_STDIO, - - [SYS_wait4] = PLEDGE_STDIO, - - /* - * Can kill self with "stdio". Killing another pid - * requires "proc" - */ - // [SYS_o58_kill] = PLEDGE_STDIO, - [SYS_kill] = PLEDGE_STDIO, - - /* - * FIONREAD/FIONBIO for "stdio" - * A few non-tty ioctl available using "ioctl" - * tty-centric ioctl available using "tty" - */ - [SYS_ioctl] = PLEDGE_STDIO, - - /* - * Path access/creation calls encounter many extensive - * checks are done during namei() - */ - [SYS_open] = PLEDGE_STDIO, - [SYS_stat] = PLEDGE_STDIO, - [SYS_access] = PLEDGE_STDIO, - [SYS_readlink] = PLEDGE_STDIO, - - // [SYS_adjtime] = PLEDGE_STDIO, /* setting requires "settime" */ - // [SYS_adjfreq] = PLEDGE_SETTIME, - [SYS_settimeofday] = PLEDGE_SETTIME, - - /* - * Needed by threaded programs - * XXX should we have a new "threads"? - */ - // [SYS___tfork] = PLEDGE_STDIO, - [SYS_sched_yield] = PLEDGE_STDIO, - // [SYS___thrsleep] = PLEDGE_STDIO, - // [SYS___thrwakeup] = PLEDGE_STDIO, - // [SYS___threxit] = PLEDGE_STDIO, - // [SYS___thrsigdivert] = PLEDGE_STDIO, - - [SYS_fork] = PLEDGE_PROC, - [SYS_vfork] = PLEDGE_PROC, - [SYS_setpgid] = PLEDGE_PROC, - [SYS_setsid] = PLEDGE_PROC, - - [SYS_setrlimit] = PLEDGE_PROC | PLEDGE_ID, - [SYS_getpriority] = PLEDGE_PROC | PLEDGE_ID, - - [SYS_setpriority] = PLEDGE_PROC | PLEDGE_ID, - - [SYS_setuid] = PLEDGE_ID, - // [SYS_seteuid] = PLEDGE_ID, - [SYS_setreuid] = PLEDGE_ID, - [SYS_setresuid] = PLEDGE_ID, - [SYS_setgid] = PLEDGE_ID, - // [SYS_setegid] = PLEDGE_ID, - [SYS_setregid] = PLEDGE_ID, - [SYS_setresgid] = PLEDGE_ID, - [SYS_setgroups] = PLEDGE_ID, - // [SYS_setlogin] = PLEDGE_ID, - - [SYS_execve] = PLEDGE_EXEC, - - [SYS_chdir] = PLEDGE_RPATH, - [SYS_openat] = PLEDGE_RPATH | PLEDGE_WPATH, - // [SYS_fstatat] = PLEDGE_RPATH | PLEDGE_WPATH, - [SYS_newfstatat] = PLEDGE_RPATH | PLEDGE_WPATH, - [SYS_faccessat] = PLEDGE_RPATH | PLEDGE_WPATH, - [SYS_readlinkat] = PLEDGE_RPATH | PLEDGE_WPATH, - [SYS_lstat] = PLEDGE_RPATH | PLEDGE_WPATH | PLEDGE_TMPPATH, - [SYS_truncate] = PLEDGE_WPATH, - [SYS_rename] = PLEDGE_CPATH, - [SYS_rmdir] = PLEDGE_CPATH, - [SYS_renameat] = PLEDGE_CPATH, - [SYS_link] = PLEDGE_CPATH, - [SYS_linkat] = PLEDGE_CPATH, - [SYS_symlink] = PLEDGE_CPATH, - [SYS_unlink] = PLEDGE_CPATH | PLEDGE_TMPPATH, - [SYS_unlinkat] = PLEDGE_CPATH, - [SYS_mkdir] = PLEDGE_CPATH, - [SYS_mkdirat] = PLEDGE_CPATH, - - // [SYS_mkfifo] = PLEDGE_DPATH, - [SYS_mknod] = PLEDGE_DPATH, - - [SYS_chroot] = PLEDGE_ID, /* also requires PLEDGE_PROC */ - - // [SYS_revoke] = PLEDGE_TTY, /* also requires PLEDGE_RPATH */ - - /* - * Classify as RPATH|WPATH, because of path information leakage. - * WPATH due to unknown use of mk*temp(3) on non-/tmp paths.. - */ - // [SYS___getcwd] = PLEDGE_RPATH | PLEDGE_WPATH, - [SYS_getcwd] = PLEDGE_RPATH | PLEDGE_WPATH, - - /* Classify as RPATH, because these leak path information */ - [SYS_getdents] = PLEDGE_RPATH, - // [SYS_getfsstat] = PLEDGE_RPATH, - [SYS_statfs] = PLEDGE_RPATH, - [SYS_fstatfs] = PLEDGE_RPATH, - // [SYS_pathconf] = PLEDGE_RPATH, - - [SYS_utimes] = PLEDGE_FATTR, - // [SYS_futimes] = PLEDGE_FATTR, - [SYS_futimesat] = PLEDGE_FATTR, - [SYS_utimensat] = PLEDGE_FATTR, - // [SYS_futimens] = PLEDGE_FATTR, - [SYS_chmod] = PLEDGE_FATTR, - [SYS_fchmod] = PLEDGE_FATTR, - [SYS_fchmodat] = PLEDGE_FATTR, - // [SYS_chflags] = PLEDGE_FATTR, - //[SYS_chflagsat] = PLEDGE_FATTR, - // [SYS_fchflags] = PLEDGE_FATTR, - [SYS_chown] = PLEDGE_FATTR, - [SYS_fchownat] = PLEDGE_FATTR, - [SYS_lchown] = PLEDGE_FATTR, - [SYS_fchown] = PLEDGE_FATTR, - - [SYS_socket] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE, - [SYS_connect] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE, - [SYS_bind] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE, - [SYS_getsockname] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE, - - [SYS_listen] = PLEDGE_INET | PLEDGE_UNIX, - [SYS_accept4] = PLEDGE_INET | PLEDGE_UNIX, - [SYS_accept] = PLEDGE_INET | PLEDGE_UNIX, - [SYS_getpeername] = PLEDGE_INET | PLEDGE_UNIX, - - [SYS_flock] = PLEDGE_FLOCK | PLEDGE_YPACTIVE, - - // [SYS_swapctl] = PLEDGE_VMINFO, /* XXX should limit to "get" operations */ -}; - - -static const struct { - char *name; - int flags; -} pledgereq[] = { - { "audio", PLEDGE_AUDIO }, - { "cpath", PLEDGE_CPATH }, - { "disklabel", PLEDGE_DISKLABEL }, - { "dns", PLEDGE_DNS }, - { "dpath", PLEDGE_DPATH }, - { "drm", PLEDGE_DRM }, - { "exec", PLEDGE_EXEC }, - { "fattr", PLEDGE_FATTR }, - { "flock", PLEDGE_FLOCK }, - { "getpw", PLEDGE_GETPW }, - { "id", PLEDGE_ID }, - { "inet", PLEDGE_INET }, - { "ioctl", PLEDGE_IOCTL }, - { "mcast", PLEDGE_MCAST }, - { "pf", PLEDGE_PF }, - { "proc", PLEDGE_PROC }, - { "prot_exec", PLEDGE_PROTEXEC }, - { "ps", PLEDGE_PS }, - { "recvfd", PLEDGE_RECVFD }, - { "route", PLEDGE_ROUTE }, - { "rpath", PLEDGE_RPATH }, - { "sendfd", PLEDGE_SENDFD }, - { "settime", PLEDGE_SETTIME }, - { "stdio", PLEDGE_STDIO }, - { "tmppath", PLEDGE_TMPPATH }, - { "tty", PLEDGE_TTY }, - { "unix", PLEDGE_UNIX }, - { "vminfo", PLEDGE_VMINFO }, - { "vmm", PLEDGE_VMM }, - { "wpath", PLEDGE_WPATH }, -}; - -scmp_filter_ctx scmp_ctx = NULL; - -/* bsearch over pledgereq. return flags value if found, 0 else */ -static int -pledgereq_flags(const char *req_name) -{ - int base = 0, cmp, i, lim; - - for (lim = nitems(pledgereq); lim != 0; lim >>= 1) { - i = base + (lim >> 1); - cmp = strcmp(req_name, pledgereq[i].name); - if (cmp == 0) - return (pledgereq[i].flags); - if (cmp > 0) { /* not found before, move right */ - base = i + 1; - lim--; - } /* else move left */ - } - return (0); -} - -/* whitelists syscalls returns -1 on error */ -int -pledge(const char *promises, __UNUSED const char *paths[]) -{ - char *buf, *p; - int rv = 0; - uint64_t flags = 0; - - if (scmp_ctx == NULL) { - /* inintialize new seccomp whitelist */ - if ((scmp_ctx = seccomp_init(SCMP_ACT_KILL)) == NULL) - err(1, "seccomp_init"); - } else { - /* reset previous rules */ - if (seccomp_reset(scmp_ctx, SCMP_ACT_KILL) < 0) - err(1, "seccomp_reset"); - } - - /* make flags from prmises string */ - buf = strdup(promises); - for (p = strtok(buf, " "); p; - p = strtok(NULL, " ")) { - flags |= pledgereq_flags(p); - } - - for (int i = 0; i < SYS_MAXSYSCALL; i++) { - /* skip not defined syscalls */ - if (pledge_syscalls[i] == 0) - continue; - - /* skip not matching syscalls */ - if (!(pledge_syscalls[i] & flags)) - continue; - - /* seccomp whitelist syscall */ - if((rv = seccomp_rule_add_exact(scmp_ctx, SCMP_ACT_ALLOW, i, 0)) != 0) - goto out; - } - - /* seccomp_export_pfc(scmp_ctx, STDERR_FILENO); */ - -out: - free(buf); - free(p); - - /* seccomp_release(scmp_ctx); */ - - return (rv == 0 ? 0 : -1); -} diff --git a/libopenbsd/pledge-seccomp.h b/libopenbsd/pledge-seccomp.h @@ -1,49 +0,0 @@ - -#ifndef nitems -#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) -#endif - -/* - * pledge(2) requests - */ -#define PLEDGE_ALWAYS 0xffffffffffffffffULL -#define PLEDGE_RPATH 0x0000000000000001ULL /* allow open for read */ -#define PLEDGE_WPATH 0x0000000000000002ULL /* allow open for write */ -#define PLEDGE_CPATH 0x0000000000000004ULL /* allow creat, mkdir, unlink etc */ -#define PLEDGE_STDIO 0x0000000000000008ULL /* operate on own pid */ -#define PLEDGE_TMPPATH 0x0000000000000010ULL /* for mk*temp() */ -#define PLEDGE_DNS 0x0000000000000020ULL /* DNS services */ -#define PLEDGE_INET 0x0000000000000040ULL /* AF_INET/AF_INET6 sockets */ -#define PLEDGE_FLOCK 0x0000000000000080ULL /* file locking */ -#define PLEDGE_UNIX 0x0000000000000100ULL /* AF_UNIX sockets */ -#define PLEDGE_ID 0x0000000000000200ULL /* allow setuid, setgid, etc */ -#define PLEDGE_IOCTL 0x0000000000000400ULL /* Select ioctl */ -#define PLEDGE_GETPW 0x0000000000000800ULL /* YP enables if ypbind.lock */ -#define PLEDGE_PROC 0x0000000000001000ULL /* fork, waitpid, etc */ -#define PLEDGE_SETTIME 0x0000000000002000ULL /* able to set/adj time/freq */ -#define PLEDGE_FATTR 0x0000000000004000ULL /* allow explicit file st_* mods */ -#define PLEDGE_PROTEXEC 0x0000000000008000ULL /* allow use of PROT_EXEC */ -#define PLEDGE_TTY 0x0000000000010000ULL /* tty setting */ -#define PLEDGE_SENDFD 0x0000000000020000ULL /* AF_UNIX CMSG fd sending */ -#define PLEDGE_RECVFD 0x0000000000040000ULL /* AF_UNIX CMSG fd receiving */ -#define PLEDGE_EXEC 0x0000000000080000ULL /* execve, child is free of pledge */ -#define PLEDGE_ROUTE 0x0000000000100000ULL /* routing lookups */ -#define PLEDGE_MCAST 0x0000000000200000ULL /* multicast joins */ -#define PLEDGE_VMINFO 0x0000000000400000ULL /* vminfo listings */ -#define PLEDGE_PS 0x0000000000800000ULL /* ps listings */ -#define PLEDGE_DISKLABEL 0x0000000002000000ULL /* disklabels */ -#define PLEDGE_PF 0x0000000004000000ULL /* pf ioctls */ -#define PLEDGE_AUDIO 0x0000000008000000ULL /* audio ioctls */ -#define PLEDGE_DPATH 0x0000000010000000ULL /* mknod & mkfifo */ -#define PLEDGE_DRM 0x0000000020000000ULL /* drm ioctls */ -#define PLEDGE_VMM 0x0000000040000000ULL /* vmm ioctls */ - - -/* - * Bits outside PLEDGE_USERSET are used by the kernel itself - * to track program behaviours which have been observed. - */ -#define PLEDGE_USERSET 0x0fffffffffffffffULL -#define PLEDGE_STATLIE 0x4000000000000000ULL -#define PLEDGE_YPACTIVE 0x8000000000000000ULL /* YP use detected and allowed */ -