I have been working for a while on a subsystem to restrict programs
into a "reduced feature operating model".

Other people have made such systems in the past, but I have never been
happy with them.  I don't think I am alone.

Generally there are two models of operation.  The first model requires
a major rewrite of application software for effective use
(ie. capsicum).  The other model in common use lacks granularity, and
allows or denies an operation throughout the entire lifetime of a
process.  As a result, they lack differentiation between program
"initialization" versus "main servicing loop".  systrace had the same
problem.  My observation is that programs need a large variety of
calls during initialization, but few in their main loops.

Some BPF-style approaches have showed up.  So you need to write a
program to observe your program, to keep things secure?  That is
insane.

So I asked myself if I could invent a simple system call, which people
would place directly into programs, between initialization and
main-loop.

Secondly, I wondered what kind of semantics such programs would need.
Not just directly themselves, but for DNS and other macro operations.

Anyways, enough explanation.  A manual page follows.

Then the kernel diff.

Finally, a sample of 29 userland programs protected to various
degrees by using it:
    cat pax ps dmesg ping ping6 dc diff finger from id kdump
    logger script sed signify uniq w wc whois arp authpf bgpd
    httpd ntpd relayd syslogd tcpdump traceroute

Not all these are perfect, but it shows the trend.  The changes
are fairly simple.  In the simplest non-network programs, network
access is disabled.  In simple network programs, file access goes
away.  That is the trend.

Sometimes a program is easily modified, making it better, because
the integration of tame hints at an improvement which will make it
tighter under tame.  sed is an example...


TAME(2)                       System Calls Manual                      TAME(2)

NAME
     tame - restrict system operations

SYNOPSIS
     #include <sys/tame.h>

     int
     tame(int flags);

DESCRIPTION
     The current process is forced into a restricted-service operating mode.
     A few subsets are available, roughly described as computation, memory
     management, read-write operations on file descriptors, opening of files,
     networking.  In general, these modes were selected by studying the
     operation of many programs using libc and other such interfaces.

     Use of tame in an application will require at least some study and
     understanding of the interfaces called.

     Subsequent calls to tame() can reduce abilities further, but abilities
     can never be regained.

     A process which attempts a restricted operation is killed with SIGKILL.
     If TAME_ABORT is set, then a non-blockable SIGABRT is delivered instead,
     possibly resulting in a core(5) file.

     A flags value of 0 restricts the process to the _exit(2) system call.
     This can be used for pure computation operating on memory shared with
     another process.

     All TAME_* options below (with the exception of TAME_ABORT) permit the
     following system calls:

           clock_getres(2), clock_gettime(2), fchdir(2), getdtablecount(2),
           getegid(2), geteuid(2), getgid(2), getgroups(2), getitimer(2),
           getlogin(2), getpgid(2), getpgrp(2), getpid(2), getppid(2),
           getresgid(2), getresuid(2), getrlimit(2), getsid(2), getthrid(2),
           gettimeofday(2), getuid(2), getuid(2), issetugid(2), nanosleep(2),
           sendsyslog(2), setitimer(2), sigaction(2), sigprocmask(2),
           sigreturn(2), umask(2), wait4(2).

     Calls allowed with restrictions include:
           sysctl(3)     A small set of read-only operations are allowed,
                         sufficient to support: getifaddrs(3),
                         getdomainname(3), gethostname(3), system sensor
                         readings.
           access(2)     May check for existance of /etc/localtime.
           adjtime(2)    Read-only, for ntpd(8).
           open(2)       May open /etc/localtime, any files below
                         /usr/share/zoneinfo and files ending in libc.cat in
                         below the directory /usr/share/nls/.
           readlink(2)   May operate on /etc/malloc.conf.
           tame(2)       Can only reduce permissions.

     The flags are specified as a bitwise OR of the following values:

           TAME_MALLOC   To allow use of the malloc(3) family of functions,
                         the following system calls are permitted:

                         getentropy(2), madvise(2), minherit(2), mmap(2),
                         mprotect(2), mquery(2), munmap(2).

           TAME_RW       The following system calls are permitted to allow
                         most types of IO operations on previously allocated
                         file descriptors, including libevent or handwritten
                         async IO loops:

                         poll(2), kevent(2), kqueue(2), select(2), close(2),
                         dup(2), dup2(2), dup3(2), closefrom(2), shutdown(2),
                         read(2), readv(2), pread(2), preadv(2), write(2),
                         writev(2), pwrite(2), pwritev(2), ftruncate(2),
                         lseek(2), utimes(2), futimes(2), utimensat(2),
                         futimens(2), fcntl(2), fsync(2), pipe(2), pipe2(2),
                         socketpair(2), getdents(2), sendto(2), sendmsg(2),
                         recvmsg(2), recvfrom(2), fstat(2).

           TAME_STDIO    This subset is simply the combination of TAME_MALLOC
                         and TAME_RW.  As a result, all functionalities of
                         libc stdio works.

           TAME_RPATH    A number of system calls are allowed if they only
                         cause read-only effects on the filesystem:

                         chdir(2), getcwd(3), openat(2), fstatat(2),
                         faccessat(2), readlinkat(2), lstat(2), chmod(2),
                         fchmod(2), fchmodat(2), chflags(2), chflagsat(2),
                         chown(2), fchown(2), fchownat(2), fstat(2).

           TAME_WPATH    A number of system calls are allowed and may cause
                         write-effects on the filesystem: read-only effects:

                         getcwd(3), openat(2), fstatat(2), faccessat(2),
                         readlinkat(2), lstat(2), chmod(2), fchmod(2),
                         fchmodat(2), chflags(2), chflagsat(2), chown(2),
                         fchown(2), fchownat(2), fstat(2), fstat(2).

           TAME_TMPPATH  A number of system calls are allowed to do operations
                         in the /tmp directory, including create, read, or
                         write:

                         lstat(2), chmod(2), chflags(2), chown(2), unlink(2),
                         fstat(2).

           TAME_CPATH    A number of system calls and sub-modes are allowed,
                         which may create new files or directories in the
                         filesystem:

                         rename(2), rmdir(2), renameat(2), link(2), linkat(2),
                         symlink(2), unlink(2), unlinkat(2), mkdir(2),
                         mkdirat(2).

           TAME_INET     The following system calls are allowed to operate in
                         the AF_INET and AF_INET6 domains:

                         socket(2), listen(2), bind(2), connect(2),
                         accept4(2), accept(2), getpeername(2),
                         getsockname(2), setsockopt(2), getsockopt(2).

                         setsockopt(2) has been reduced in functionality
                         substantially.
           TAME_UNIX     The following system calls are allowed to operate in
                         the AF_UNIX domain:

                         socket(2), listen(2), bind(2), connect(2),
                         accept4(2), accept(2), getpeername(2),
                         getsockname(2), setsockopt(2), getsockopt(2).

           TAME_DNSPATH  Subsequent to a succesfull open(2) of
                         /etc/resolv.conf, a few system calls become to allow
                         DNS network transactions:

                         sendto(2), recvfrom(2), socket(2), connect(2).

           TAME_GETPW    This allows read-only opening of files in /etc for
                         the getpwnam(3), getgrnam(3,) getgrouplist(3), and
                         initgroups(3) family of functions.  They may also
                         need to operate in a yp(8) environment, so a
                         succesfull open(2) of /var/run/ypbind.lock enables
                         the TAME_INET flag.

           TAME_CMSG     Allows passing of file descriptors using the
                         sendmsg(2) and recvmsg(2) functions.

           TAME_IOCTL    Allows a subset of ioctl(2) operations:

                         FIOCLEX, FIONCLEX, FIONREAD, FIONBIO, FIOGETOWN,
                         TIOCSWINSZ, TIOCSTI.

           TAME_PROC     Allows the following process relationship operations:

                         fork(2), vfork(2), kill(2), setresgid(2),
                         SYS_setresuid(2),

           TAME_ABORT    Deliver an unblockable SIGABRT upon violation instead
                         of SIGKILL.

RETURN VALUES
     Upon successful completion, the value 0 is returned; otherwise the
     value -1 is returned and the global variable errno is set to indicate the
     error.

ERRORS
     tame() will fail if:

     [EPERM]            This process is attempting to increase permissions.

HISTORY
     The tame() system call appeared in OpenBSD 5.8.

OpenBSD 5.8                      July 18, 2015                     OpenBSD 5.8


Index: sys/conf/files
===================================================================
RCS file: /cvs/src/sys/conf/files,v
retrieving revision 1.595
diff -u -p -u -r1.595 files
--- sys/conf/files      17 Jul 2015 22:52:29 -0000      1.595
+++ sys/conf/files      17 Jul 2015 22:57:21 -0000
@@ -666,6 +666,7 @@ file kern/kern_physio.c
 file kern/kern_proc.c
 file kern/kern_prot.c
 file kern/kern_resource.c
+file kern/kern_tame.c
 file kern/kern_sched.c
 file kern/kern_sensors.c
 file kern/kern_sig.c
Index: sys/kern/init_sysent.c
===================================================================
RCS file: /cvs/src/sys/kern/init_sysent.c,v
retrieving revision 1.166
diff -u -p -u -r1.166 init_sysent.c
--- sys/kern/init_sysent.c      6 May 2015 11:26:02 -0000       1.166
+++ sys/kern/init_sysent.c      26 May 2015 17:40:00 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: init_sysent.c,v 1.166 2015/05/06 11:26:02 jsg Exp $   */
+/*     $OpenBSD$       */
 
 /*
  * System call switch table.
@@ -248,8 +248,8 @@ struct sysent sysent[] = {
            sys_listen },                       /* 106 = listen */
        { 4, s(struct sys_chflagsat_args), 0,
            sys_chflagsat },                    /* 107 = chflagsat */
-       { 0, 0, 0,
-           sys_nosys },                        /* 108 = obsolete osigvec */
+       { 1, s(struct sys_tame_args), 0,
+           sys_tame },                         /* 108 = tame */
        { 4, s(struct sys_ppoll_args), 0,
            sys_ppoll },                        /* 109 = ppoll */
        { 6, s(struct sys_pselect_args), 0,
Index: sys/kern/kern_fork.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.180
diff -u -p -u -r1.180 kern_fork.c
--- sys/kern/kern_fork.c        14 Mar 2015 07:33:42 -0000      1.180
+++ sys/kern/kern_fork.c        21 May 2015 22:35:59 -0000
@@ -203,7 +203,7 @@ process_new(struct proc *p, struct proce
        if (pr->ps_textvp)
                vref(pr->ps_textvp);
 
-       pr->ps_flags = parent->ps_flags & (PS_SUGID | PS_SUGIDEXEC);
+       pr->ps_flags = parent->ps_flags & (PS_SUGID | PS_SUGIDEXEC | PS_TAMED);
        if (parent->ps_session->s_ttyvp != NULL)
                pr->ps_flags |= parent->ps_flags & PS_CONTROLT;
 
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.180
diff -u -p -u -r1.180 kern_sig.c
--- sys/kern/kern_sig.c 5 May 2015 02:13:46 -0000       1.180
+++ sys/kern/kern_sig.c 3 Jun 2015 00:59:59 -0000
@@ -1420,6 +1420,7 @@ sigexit(struct proc *p, int signum)
                    TAILQ_NEXT(p, p_thr_link) != NULL)
                        single_thread_set(p, SINGLE_SUSPEND, 0);
 
+               atomic_clearbits_int(&p->p_p->ps_flags, PS_TAMED);
                if (coredump(p) == 0)
                        signum |= WCOREFLAG;
        }
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.285
diff -u -p -u -r1.285 kern_sysctl.c
--- sys/kern/kern_sysctl.c      18 May 2015 19:10:35 -0000      1.285
+++ sys/kern/kern_sysctl.c      25 Jun 2015 01:14:24 -0000
@@ -70,6 +70,7 @@
 #include <sys/domain.h>
 #include <sys/protosw.h>
 #include <sys/timetc.h>
+#include <sys/tame.h>
 #include <sys/evcount.h>
 #include <sys/un.h>
 #include <sys/unpcb.h>
@@ -169,6 +170,9 @@ sys___sysctl(struct proc *p, void *v, re
                       SCARG(uap, namelen) * sizeof(int));
        if (error)
                return (error);
+
+       if (tame_sysctl_check(p, SCARG(uap, namelen), name, SCARG(uap, new)))
+               return (tame_fail(p, EPERM, _TM_SELF));
 
        switch (name[0]) {
        case CTL_KERN:
Index: sys/kern/kern_tame.c
===================================================================
RCS file: sys/kern/kern_tame.c
diff -N sys/kern/kern_tame.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/kern/kern_tame.c        18 Jul 2015 21:36:11 -0000
@@ -0,0 +1,788 @@
+/*     $OpenBSD$       */
+
+/*
+ * Copyright (c) 2015 Nicholas Marriott <n...@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 MIND, 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 <sys/param.h>
+#include <sys/types.h>
+
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/vnode.h>
+#include <sys/mbuf.h>
+#include <sys/sysctl.h>
+#include <sys/ktrace.h>
+
+#include <sys/ioctl.h>
+#include <sys/termios.h>
+#include <sys/mtio.h>
+#include <net/bpf.h>
+#include <net/route.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <sys/tame.h>
+
+#include <sys/signalvar.h>
+#include <sys/syscall.h>
+#include <sys/syscallargs.h>
+#include <sys/systm.h>
+
+const u_int tame_syscalls[SYS_MAXSYSCALL] = {
+       [SYS_exit] = 0xffffffff,
+
+       [SYS_getuid] = _TM_SELF,
+       [SYS_geteuid] = _TM_SELF,
+       [SYS_getresuid] = _TM_SELF,
+       [SYS_getgid] = _TM_SELF,
+       [SYS_getegid] = _TM_SELF,
+       [SYS_getresgid] = _TM_SELF,
+       [SYS_getgroups] = _TM_SELF,
+       [SYS_getlogin] = _TM_SELF,
+       [SYS_getpgrp] = _TM_SELF,
+       [SYS_getpgid] = _TM_SELF,
+       [SYS_getppid] = _TM_SELF,
+       [SYS_getsid] = _TM_SELF,
+       [SYS_getthrid] = _TM_SELF,
+       [SYS_getrlimit] = _TM_SELF,
+       [SYS_gettimeofday] = _TM_SELF,
+       [SYS_getdtablecount] = _TM_SELF,
+       [SYS_issetugid] = _TM_SELF,
+       [SYS_clock_getres] = _TM_SELF,
+       [SYS_clock_gettime] = _TM_SELF,
+       [SYS_getpid] = _TM_SELF,
+       [SYS_umask] = _TM_SELF,
+       [SYS___sysctl] = _TM_SELF,      /* read-only; narrow subset */
+       [SYS_adjtime] = _TM_SELF,       /* read-only */
+
+       [SYS_chdir] = _TM_RPATH,
+
+       [SYS_fchdir] = _TM_SELF,        /* careful of directory fd inside jails 
*/
+
+       [SYS_sendsyslog] = _TM_SELF,
+       [SYS_nanosleep] = _TM_SELF,
+       [SYS_sigprocmask] = _TM_SELF,
+       [SYS_sigaction] = _TM_SELF,
+       [SYS_sigreturn] = _TM_SELF,
+       [SYS_getitimer] = _TM_SELF,
+       [SYS_setitimer] = _TM_SELF,
+
+       [SYS_tame] = _TM_SELF,
+
+       [SYS_wait4] = _TM_SELF,
+
+       [SYS_poll] = _TM_RW,
+       [SYS_kevent] = _TM_RW,
+       [SYS_kqueue] = _TM_RW,
+       [SYS_select] = _TM_RW,
+
+       [SYS_close] = _TM_RW,
+       [SYS_dup] = _TM_RW,
+       [SYS_dup2] = _TM_RW,
+       [SYS_dup3] = _TM_RW,
+       [SYS_closefrom] = _TM_RW,
+       [SYS_shutdown] = _TM_RW,
+       [SYS_read] = _TM_RW,
+       [SYS_readv] = _TM_RW,
+       [SYS_pread] = _TM_RW,
+       [SYS_preadv] = _TM_RW,
+       [SYS_write] = _TM_RW,
+       [SYS_writev] = _TM_RW,
+       [SYS_pwrite] = _TM_RW,
+       [SYS_pwritev] = _TM_RW,
+       [SYS_ftruncate] = _TM_RW,
+       [SYS_lseek] = _TM_RW,
+
+       [SYS_utimes] = _TM_RW,
+       [SYS_futimes] = _TM_RW,
+       [SYS_utimensat] = _TM_RW,
+       [SYS_futimens] = _TM_RW,
+
+       [SYS_fcntl] = _TM_RW,
+       [SYS_fsync] = _TM_RW,
+       [SYS_pipe] = _TM_RW,
+       [SYS_pipe2] = _TM_RW,
+       [SYS_socketpair] = _TM_RW,
+
+       [SYS_getdents] = _TM_RW,
+
+       [SYS_sendto] = _TM_RW | _TM_DNS_ACTIVE | _TM_YP_ACTIVE,
+       [SYS_sendmsg] = _TM_RW,
+       [SYS_recvmsg] = _TM_RW,
+       [SYS_recvfrom] = _TM_RW | _TM_DNS_ACTIVE | _TM_YP_ACTIVE,
+
+       [SYS_fork] = _TM_PROC,
+       [SYS_vfork] = _TM_PROC,
+       [SYS_kill] = _TM_PROC,
+
+       [SYS_setresgid] = _TM_PROC,
+       [SYS_setresuid] = _TM_PROC,
+
+       [SYS_ioctl] = _TM_IOCTL,                /* very limited subset */
+
+       [SYS_getentropy] = _TM_MALLOC,
+       [SYS_madvise] = _TM_MALLOC,
+       [SYS_minherit] = _TM_MALLOC,
+       [SYS_mmap] = _TM_MALLOC,
+       [SYS_mprotect] = _TM_MALLOC,
+       [SYS_mquery] = _TM_MALLOC,
+       [SYS_munmap] = _TM_MALLOC,
+
+       [SYS___getcwd] = _TM_RPATH | _TM_WPATH,
+       [SYS_open] = _TM_SELF,
+       [SYS_openat] = _TM_RPATH | _TM_WPATH,
+       [SYS_stat] = _TM_SELF,
+       [SYS_fstatat] = _TM_RPATH | _TM_WPATH,
+       [SYS_access] = _TM_SELF,
+       [SYS_faccessat] = _TM_RPATH | _TM_WPATH,
+       [SYS_readlink] = _TM_SELF,
+       [SYS_readlinkat] = _TM_RPATH | _TM_WPATH,
+       [SYS_lstat] = _TM_RPATH | _TM_WPATH | _TM_TMPPATH | _TM_DNSPATH,
+       [SYS_chmod] = _TM_RPATH | _TM_WPATH | _TM_TMPPATH,
+       [SYS_fchmod] = _TM_RPATH | _TM_WPATH,
+       [SYS_fchmodat] = _TM_RPATH | _TM_WPATH,
+       [SYS_chflags] = _TM_RPATH | _TM_WPATH | _TM_TMPPATH,
+       [SYS_chflagsat] = _TM_RPATH | _TM_WPATH,
+       [SYS_chown] = _TM_RPATH | _TM_WPATH | _TM_TMPPATH,
+       [SYS_fchown] = _TM_RPATH | _TM_WPATH,
+       [SYS_fchownat] = _TM_RPATH | _TM_WPATH,
+       [SYS_rename] = _TM_CPATH,
+       [SYS_rmdir] = _TM_CPATH,
+       [SYS_renameat] = _TM_CPATH,
+       [SYS_link] = _TM_CPATH,
+       [SYS_linkat] = _TM_CPATH,
+       [SYS_symlink] = _TM_CPATH,
+       [SYS_unlink] = _TM_CPATH | _TM_TMPPATH,
+       [SYS_unlinkat] = _TM_CPATH,
+       [SYS_mkdir] = _TM_CPATH,
+       [SYS_mkdirat] = _TM_CPATH,
+
+       [SYS_fstat] = _TM_RW | _TM_RPATH | _TM_WPATH | _TM_TMPPATH,     /* rare 
*/
+
+       [SYS_socket] = _TM_INET | _TM_UNIX | _TM_DNS_ACTIVE | _TM_YP_ACTIVE,
+       [SYS_listen] = _TM_INET | _TM_UNIX,
+       [SYS_bind] = _TM_INET | _TM_UNIX,
+       [SYS_connect] = _TM_INET | _TM_UNIX | _TM_DNS_ACTIVE | _TM_YP_ACTIVE,
+       [SYS_accept4] = _TM_INET | _TM_UNIX,
+       [SYS_accept] = _TM_INET | _TM_UNIX,
+       [SYS_getpeername] = _TM_INET | _TM_UNIX,
+       [SYS_getsockname] = _TM_INET | _TM_UNIX,
+       [SYS_setsockopt] = _TM_INET | _TM_UNIX,         /* small subset */
+       [SYS_getsockopt] = _TM_INET | _TM_UNIX,
+
+       [SYS_flock] = _TM_GETPW,
+};
+
+int
+sys_tame(struct proc *p, void *v, register_t *retval)
+{
+       struct sys_tame_args /* {
+               syscallarg(int) flags;
+       } */    *uap = v;
+       int      flags = SCARG(uap, flags);
+
+       flags &= _TM_USERSET;
+       if ((p->p_p->ps_flags & PS_TAMED) == 0) {
+               p->p_p->ps_flags |= PS_TAMED;
+               p->p_p->ps_tame = flags;
+               return (0);
+       }
+
+       /* May not set new bits */
+       if (((flags | p->p_p->ps_tame) & _TM_USERSET) !=
+           (p->p_p->ps_tame & _TM_USERSET))
+               return (EPERM);
+
+       /* More tame bits being cleared.  Force re-learning of _ACTIVE things */
+       p->p_p->ps_tame &= flags;
+       p->p_p->ps_tame &= _TM_USERSET;
+       return (0);
+}
+
+int
+tame_check(struct proc *p, int code)
+{
+       p->p_tamenote = p->p_tameafter = 0;     /* XX optimise? */
+       p->p_tame_syscall = code;
+
+       if (code < 0 || code > SYS_MAXSYSCALL - 1)
+               return (0);
+
+       if (p->p_p->ps_tame == 0)
+               return (code == SYS_exit);
+       return (p->p_p->ps_tame & tame_syscalls[code]);
+}
+
+int
+tame_fail(struct proc *p, int error, int code)
+{
+       printf("tame: pid %d %s syscall %d\n", p->p_pid, p->p_comm,
+           p->p_tame_syscall);
+#ifdef KTRACE
+       if (KTRPOINT(p, KTR_PSIG)) {
+               siginfo_t si;
+
+               memset(&si, 0, sizeof(si));
+               if (p->p_p->ps_tame & _TM_ABORT)
+                       si.si_signo = SIGABRT;
+               else
+                       si.si_signo = SIGKILL;
+               si.si_code = code;
+               // si.si_syscall = p->p_tame_syscall;
+               /// si.si_nsysarg ...
+               ktrpsig(p, si.si_signo, SIG_DFL, p->p_sigmask, code, &si);
+       }
+#endif
+       if (p->p_p->ps_tame & _TM_ABORT) {
+               /* Core dump requested */
+               atomic_clearbits_int(&p->p_sigmask, sigmask(SIGABRT));
+               atomic_clearbits_int(&p->p_p->ps_flags, PS_TAMED);
+               psignal(p, SIGABRT);
+       } else
+               psignal(p, SIGKILL);
+       return (error);
+}
+
+/*
+ * Need to make it more obvious that one cannot get through here
+ * without the right flags set
+ */
+int
+tame_namei(struct proc *p, char *path)
+{
+       /* Detect what looks like a mkstemp(3) family operation */
+       if ((p->p_p->ps_tame & _TM_TMPPATH) &&
+           (p->p_tame_syscall == SYS_open) &&
+           (p->p_tamenote & (TMN_CREAT | TMN_IMODIFY)) == TMN_CREAT &&
+           strncmp(path, "/tmp/", 5) == 0) {
+               return (0);
+       }
+
+       /* Allow unlinking of a mkstemp(3) file...
+        * Good opportunity for strict checks here.
+        */
+       if ((p->p_p->ps_tame & _TM_TMPPATH) &&
+           (p->p_tame_syscall == SYS_unlink) &&
+           strncmp(path, "/tmp/", 5) == 0) {
+               return (0);
+       }
+
+       /* open, mkdir, or other path creation operation */
+       if ((p->p_tamenote & (TMN_CREAT | TMN_IMODIFY)) == TMN_CREAT &&
+           ((p->p_p->ps_tame & _TM_CPATH) == 0))
+               return (tame_fail(p, EPERM, TAME_CPATH));
+
+       /* inode change operation, issued against a path */
+       if ((p->p_tamenote & (TMN_CREAT | TMN_IMODIFY)) == TMN_IMODIFY &&
+           ((p->p_p->ps_tame & _TM_CPATH) == 0)) {
+               // XXX should _TM_CPATH be a seperate check?
+               return (tame_fail(p, EPERM, TAME_CPATH));
+       }
+
+       if ((p->p_tamenote & TMN_WRITE) &&
+           (p->p_p->ps_tame & _TM_WPATH) == 0)
+               return (tame_fail(p, EPERM, TAME_WPATH));
+
+       if (p->p_p->ps_tame & _TM_RPATH)
+               return (0);
+
+       if (p->p_p->ps_tame & _TM_WPATH)
+               return (0);
+
+       /* All remaining cases are RPATH */
+       switch (p->p_tame_syscall) {
+       case SYS_access:
+               /* tzset() needs this. */
+               if (strcmp(path, "/etc/localtime") == 0)
+                       return (0);
+               break;
+       case SYS_open:
+               /* getpw* and friends need a few files */
+               if (p->p_p->ps_tame & _TM_GETPW) {
+                       if (strcmp(path, "/etc/spwd.db") == 0)
+                               return (0);
+                       if (strcmp(path, "/etc/pwd.db") == 0)
+                               return (0);
+                       if (strcmp(path, "/etc/group") == 0)
+                               return (0);
+               }
+
+               /* DNS needs /etc/{resolv.conf,hosts,services}. */
+               if (p->p_p->ps_tame & _TM_DNSPATH) {
+                       if (strcmp(path, "/etc/resolv.conf") == 0) {
+                               p->p_tamenote |= TMN_DNSRESOLV;
+                               p->p_tameafter = 1;
+                               return (0);
+                       }
+                       if (strcmp(path, "/etc/hosts") == 0)
+                               return (0);
+                       if (strcmp(path, "/etc/services") == 0)
+                               return (0);
+               }
+               if (p->p_p->ps_tame & _TM_GETPW) {
+                       if (strcmp(path, "/var/run/ypbind.lock") == 0) {
+                               p->p_tamenote |= TMN_YPLOCK;
+                               p->p_tameafter = 1;
+                               return (0);
+                       }
+                       if (strncmp(path, "/var/yp/binding/", 14) == 0)
+                               return (0);
+               }
+               /* tzset() needs these. */
+               if (strncmp(path, "/usr/share/zoneinfo/", 20) == 0)
+                       return (0);
+               if (strcmp(path, "/etc/localtime") == 0)
+                       return (0);
+
+               /* /usr/share/nls/../libc.cat returns EPERM, for strerror(3). */
+               if (strncmp(path, "/usr/share/nls/", 15) == 0 &&
+                   strcmp(path + strlen(path) - 9, "/libc.cat") == 0)
+                       return (EPERM);
+               break;
+       case SYS_readlink:
+               /* Allow /etc/malloc.conf for malloc(3). */
+               if (strcmp(path, "/etc/malloc.conf") == 0)
+                       return (0);
+               break;
+       case SYS_stat:
+               /* DNS needs /etc/resolv.conf. */
+               if (p->p_p->ps_tame & _TM_DNSPATH) {
+                       if (strcmp(path, "/etc/resolv.conf") == 0) {
+                               p->p_tamenote |= TMN_DNSRESOLV;
+                               p->p_tameafter = 1;
+                               return (0);
+                       }
+               }
+               break;
+       }
+
+       return (tame_fail(p, EPERM, TAME_RPATH));
+}
+
+void
+tame_aftersyscall(struct proc *p, int code, int error)
+{
+       if ((p->p_tamenote & TMN_YPLOCK) && error == 0)
+               atomic_setbits_int(&p->p_p->ps_tame, _TM_YP_ACTIVE | TAME_INET);
+       if ((p->p_tamenote & TMN_DNSRESOLV) && error == 0)
+               atomic_setbits_int(&p->p_p->ps_tame, _TM_DNS_ACTIVE);
+}
+
+/*
+ * By default, only the advisory cmsg's can be received from the kernel,
+ * such as TIMESTAMP ntpd.
+ *
+ * If TAME_CMSG is set SCM_RIGHTS is also allowed through for a carefully
+ * selected set of descriptors (specifically to exclude directories).
+ *
+ * This results in a kill upon recv, if some other process on the system
+ * send a SCM_RIGHTS to an open socket of some sort.  That will discourage
+ * leaving such sockets lying around...
+ */
+int
+tame_cmsg_recv(struct proc *p, void *v, int controllen)
+{
+       struct mbuf *control = v;
+       struct msghdr tmp;
+       struct cmsghdr *cmsg;
+       struct file **rp, *fp;
+       int nfds, i;
+
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       /* Scan the cmsg */
+       memset(&tmp, 0, sizeof(tmp));
+       tmp.msg_control = mtod(control, struct cmsghdr *);
+       tmp.msg_controllen = controllen;
+       cmsg = CMSG_FIRSTHDR(&tmp);
+
+       while (cmsg != NULL) {
+               if (cmsg->cmsg_level == SOL_SOCKET &&
+                   cmsg->cmsg_type == SCM_RIGHTS)
+                       break;
+               cmsg = CMSG_NXTHDR(&tmp, cmsg);
+       }
+
+       /* No SCM_RIGHTS found -> OK */
+       if (cmsg == NULL)
+               return (0);
+
+       if ((p->p_p->ps_tame & _TM_CMSG) == 0)
+               return tame_fail(p, EPERM, TAME_CMSG);
+
+       /* In OpenBSD, a CMSG only contains one SCM_RIGHTS.  Check it. */ 
+       rp = (struct file **)CMSG_DATA(cmsg);
+       nfds = (cmsg->cmsg_len - CMSG_ALIGN(sizeof(*cmsg))) /
+           sizeof(struct file *);
+       for (i = 0; i < nfds; i++) {
+               struct vnode *vp;
+
+               fp = *rp++;
+
+               /* Only allow passing of sockets, pipes, and pure files */
+               printf("f_type %d\n", fp->f_type);
+               switch (fp->f_type) {
+               case DTYPE_SOCKET:
+               case DTYPE_PIPE:
+                       continue;
+               case DTYPE_VNODE:
+                       vp = (struct vnode *)fp->f_data;
+                       printf("v_type %d\n", vp->v_type);
+                       if (vp->v_type == VREG)
+                               continue;
+                       break;
+               default:
+                       break;
+               }
+               printf("bad fd type\n");
+               return tame_fail(p, EPERM, TAME_CMSG);
+       }
+       return (0);
+}
+
+/*
+ * When tamed, default prevents sending of a cmsg.
+ * If CMSG flag is set, 
+ */
+int
+tame_cmsg_send(struct proc *p, void *v, int controllen)
+{
+       struct mbuf *control = v;
+       struct msghdr tmp;
+       struct cmsghdr *cmsg;
+       struct file **rp, *fp;
+       int nfds, i;
+
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       if ((p->p_p->ps_tame & _TM_CMSG) == 0)
+               return tame_fail(p, EPERM, TAME_CMSG);
+
+       /* Scan the cmsg */
+       memset(&tmp, 0, sizeof(tmp));
+       tmp.msg_control = mtod(control, struct cmsghdr *);
+       tmp.msg_controllen = controllen;
+       cmsg = CMSG_FIRSTHDR(&tmp);
+
+       while (cmsg != NULL) {
+               if (cmsg->cmsg_level == SOL_SOCKET &&
+                   cmsg->cmsg_type == SCM_RIGHTS)
+                       break;
+               cmsg = CMSG_NXTHDR(&tmp, cmsg);
+       }
+
+       /* Contains no SCM_RIGHTS, so OK */
+       if (cmsg == NULL)
+               return (0);
+
+       /* In OpenBSD, a CMSG only contains one SCM_RIGHTS.  Check it. */ 
+       rp = (struct file **)CMSG_DATA(cmsg);
+       nfds = (cmsg->cmsg_len - CMSG_ALIGN(sizeof(*cmsg))) /
+           sizeof(struct file *);
+       for (i = 0; i < nfds; i++) {
+               struct vnode *vp;
+
+               fp = *rp++;
+
+               /* Only allow passing of sockets, pipes, and pure files */
+               printf("f_type %d\n", fp->f_type);
+               switch (fp->f_type) {
+               case DTYPE_SOCKET:
+               case DTYPE_PIPE:
+                       continue;
+               case DTYPE_VNODE:
+                       vp = (struct vnode *)fp->f_data;
+                       printf("v_type %d\n", vp->v_type);
+                       if (vp->v_type == VREG)
+                               continue;
+                       break;
+               default:
+                       break;
+               }
+               /* Not allowed to send a bad fd type */
+               return tame_fail(p, EPERM, TAME_CMSG);
+       }
+       return (0);
+}
+
+int
+tame_sysctl_check(struct proc *p, int namelen, int *name, void *new)
+{
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       if (new)
+               return (EFAULT);
+
+       /* getifaddrs() */
+       if ((p->p_p->ps_tame & _TM_INET) &&
+           namelen == 6 &&
+           name[0] == CTL_NET && name[1] == PF_ROUTE &&
+           name[2] == 0 && name[3] == 0 &&
+           name[4] == NET_RT_IFLIST && name[5] == 0)
+               return (0);
+
+       /* used by arp(8).  Exposes MAC addresses known on local nets */
+       /* XXX Put into a special catagory. */
+       if ((p->p_p->ps_tame & _TM_INET) &&
+           namelen == 7 &&
+           name[0] == CTL_NET && name[1] == PF_ROUTE &&
+           name[2] == 0 && name[3] == AF_INET &&
+           name[4] == NET_RT_FLAGS && name[5] == RTF_LLINFO)
+               return (0);
+
+       /* used by ntpd(8) to read sensors. */
+       /* XXX Put into a special catagory. */
+       if (namelen >= 3 &&
+           name[0] == CTL_HW && name[1] == HW_SENSORS)
+               return (0);
+
+       if (namelen == 2 &&
+           name[0] == CTL_KERN && name[1] == KERN_DOMAINNAME)
+               return (0);
+       if (namelen == 2 &&
+           name[0] == CTL_KERN && name[1] == KERN_HOSTNAME)
+               return (0);
+
+       printf("tame: pid %d %s sysctl %d: %d %d %d %d %d %d\n",
+           p->p_pid, p->p_comm, namelen, name[0], name[1],
+           name[2], name[3], name[4], name[5]);
+       return (EFAULT);
+}
+
+int
+tame_adjtime_check(struct proc *p, const void *v)
+{
+       const struct timeval *delta = v;
+
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       if (delta)
+               return (EFAULT);
+       return (0);
+}
+
+int
+tame_connect_check(struct proc *p)
+{
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       if ((p->p_p->ps_tame & _TM_DNS_ACTIVE))
+               return (0);     /* A port check happens inside sys_connect() */
+
+       if ((p->p_p->ps_tame & (_TM_INET | _TM_UNIX)))
+               return (0);
+       return (EPERM);
+}
+
+int
+tame_recvfrom_check(struct proc *p, void *v)
+{
+       struct sockaddr *from = v;
+
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       if ((p->p_p->ps_tame & _TM_DNS_ACTIVE) && from == NULL)
+               return (0);
+       if (p->p_p->ps_tame & _TM_INET)
+               return (0);
+       if (p->p_p->ps_tame & _TM_UNIX)
+               return (0);
+       if (from == NULL)
+               return (0);             /* behaves just like write */
+       return (EPERM);
+}
+
+int
+tame_sendto_check(struct proc *p, const void *v)
+{
+       const struct sockaddr *to = v;
+               
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       if ((p->p_p->ps_tame & _TM_DNS_ACTIVE) && to == NULL)
+               return (0);
+
+       if ((p->p_p->ps_tame & _TM_INET))
+               return (0);
+       if ((p->p_p->ps_tame & _TM_UNIX))
+               return (0);
+       if (to == NULL)
+               return (0);             /* behaves just like write */
+       return (EPERM);
+}
+
+int
+tame_socket_check(struct proc *p, int domain)
+{
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+       if ((p->p_p->ps_tame & (_TM_INET | _TM_UNIX)))
+               return (0);
+       if ((p->p_p->ps_tame & _TM_DNS_ACTIVE) && domain == AF_INET)
+               return (0);
+       return (EPERM);
+}
+
+int
+tame_bind_check(struct proc *p, const void *v)
+{
+
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+       if ((p->p_p->ps_tame & _TM_INET))
+               return (0);
+       return (EPERM);
+}
+
+int
+tame_ioctl_check(struct proc *p, long com, void *v)
+{
+       struct file *fp = v;
+       struct vnode *vp = (struct vnode *)fp->f_data;
+
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       switch (com) {
+
+       /*
+        * This is a set of "get" info ioctls at the top layer.  Hopefully
+        * a safe list, since they are used a lot.
+        */
+       case FIOCLEX:
+       case FIONCLEX:
+       case FIONREAD:
+       case FIONBIO:
+       case FIOGETOWN:
+               return (0);
+       case FIOASYNC:
+       case FIOSETOWN:
+               return (EPERM);
+
+       /* tty subsystem */
+       case TIOCSWINSZ:        /* various programs */
+       case TIOCSTI:           /* ksh? csh? */
+               if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
+                       return (0);
+               break;
+
+//     /* bpf read operations */
+//     case BIOCGSTATS:        /* tcpdump privsep on ^C */
+//             /* XXX should check type of vnode? */
+//             return (0);
+
+       default:
+               break;
+       }
+
+       if ((p->p_p->ps_tame & _TM_IOCTL) == 0)
+               return (EPERM);
+
+       /*
+        * Further sets of ioctl become available, but are checked a
+        * bit more carefully against the vnode.
+        */
+
+       switch (com) {
+       case TIOCSETAF:         /* tcsetattr TCSAFLUSH, script */
+               if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
+                       return (0);
+               break;
+
+
+       case MTIOCGET:
+       case MTIOCTOP:
+               /* for pax(1) and such, checking tapes... */
+               if (fp->f_type == DTYPE_VNODE &&
+                   (vp->v_type == VCHR || vp->v_type == VBLK))
+                       return (0);
+               break;
+
+       case SIOCGIFGROUP:
+               if ((p->p_p->ps_tame & _TM_INET) &&
+                   fp->f_type == DTYPE_SOCKET)
+                       return (0);
+               break;
+
+       default:
+               printf("ioctl %lx\n", com);
+               break;
+       }
+       return (EPERM);
+}
+
+int
+tame_setsockopt_check(struct proc *p, int level, int optname)
+{
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       switch (level) {
+       case SOL_SOCKET:
+               switch (optname) {
+               case SO_RTABLE:
+                       return (EPERM);
+               }
+               return (0);
+       case IPPROTO_TCP: 
+               switch (optname) {
+               case TCP_NODELAY:
+               case TCP_MD5SIG:
+               case TCP_SACK_ENABLE:
+               case TCP_MAXSEG:
+               case TCP_NOPUSH:
+                       return (0);
+               }
+       case IPPROTO_IP:
+               switch (optname) {
+               case IP_TOS:
+               case IP_TTL:
+               case IP_MINTTL:
+               case IP_PORTRANGE:
+               case IP_RECVDSTADDR:
+                       return (0);
+               }
+       case IPPROTO_ICMP:
+               break;
+       case IPPROTO_IPV6:
+       case IPPROTO_ICMPV6:
+               break;
+       }
+       return (EPERM);
+}
+
+int
+tame_dns_check(struct proc *p, in_port_t port)
+{
+       if ((p->p_p->ps_flags & PS_TAMED) == 0)
+               return (0);
+
+       if ((p->p_p->ps_tame & _TM_INET))
+               return (0);
+       if ((p->p_p->ps_tame & _TM_DNS_ACTIVE) && port == htons(53))
+               return (0);     /* Allow a DNS connect outbound */
+       return (EPERM);
+}
Index: sys/kern/kern_time.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_time.c,v
retrieving revision 1.90
diff -u -p -u -r1.90 kern_time.c
--- sys/kern/kern_time.c        28 Apr 2015 20:54:18 -0000      1.90
+++ sys/kern/kern_time.c        26 May 2015 20:12:46 -0000
@@ -40,6 +40,7 @@
 #include <sys/ktrace.h>
 #include <sys/vnode.h>
 #include <sys/signalvar.h>
+#include <sys/tame.h>
 #include <sys/timetc.h>
 
 #include <sys/mount.h>
@@ -431,6 +432,9 @@ sys_adjtime(struct proc *p, void *v, reg
        struct timeval *olddelta = SCARG(uap, olddelta);
        struct timeval atv;
        int error;
+
+       if (tame_adjtime_check(p, delta))
+               return (EPERM);
 
        if (olddelta) {
                memset(&atv, 0, sizeof(atv));
Index: sys/kern/sys_generic.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_generic.c,v
retrieving revision 1.98
diff -u -p -u -r1.98 sys_generic.c
--- sys/kern/sys_generic.c      10 May 2015 22:35:38 -0000      1.98
+++ sys/kern/sys_generic.c      25 Jun 2015 01:14:53 -0000
@@ -52,6 +52,7 @@
 #include <sys/stat.h>
 #include <sys/malloc.h>
 #include <sys/poll.h>
+#include <sys/tame.h>
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
@@ -384,7 +385,7 @@ sys_ioctl(struct proc *p, void *v, regis
        } */ *uap = v;
        struct file *fp;
        struct filedesc *fdp;
-       u_long com;
+       u_long com = SCARG(uap, com);
        int error;
        u_int size;
        caddr_t data, memp;
@@ -393,10 +394,15 @@ sys_ioctl(struct proc *p, void *v, regis
        long long stkbuf[STK_PARAMS / sizeof(long long)];
 
        fdp = p->p_fd;
-       if ((fp = fd_getfile_mode(fdp, SCARG(uap, fd), FREAD|FWRITE)) == NULL)
+       fp = fd_getfile_mode(fdp, SCARG(uap, fd), FREAD|FWRITE);
+
+       if (tame_ioctl_check(p, com, fp))
+               return (tame_fail(p, EPERM, _TM_IOCTL));
+
+       if (fp == NULL)
                return (EBADF);
 
-       switch (com = SCARG(uap, com)) {
+       switch (com) {
        case FIONCLEX:
        case FIOCLEX:
                fdplock(fdp);
Index: sys/kern/syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/syscalls.c,v
retrieving revision 1.165
diff -u -p -u -r1.165 syscalls.c
--- sys/kern/syscalls.c 6 May 2015 11:26:02 -0000       1.165
+++ sys/kern/syscalls.c 26 May 2015 17:40:00 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syscalls.c,v 1.165 2015/05/06 11:26:02 jsg Exp $      */
+/*     $OpenBSD$       */
 
 /*
  * System call names.
@@ -128,7 +128,7 @@ char *syscallnames[] = {
        "setsockopt",                   /* 105 = setsockopt */
        "listen",                       /* 106 = listen */
        "chflagsat",                    /* 107 = chflagsat */
-       "#108 (obsolete osigvec)",              /* 108 = obsolete osigvec */
+       "tame",                 /* 108 = tame */
        "ppoll",                        /* 109 = ppoll */
        "pselect",                      /* 110 = pselect */
        "sigsuspend",                   /* 111 = sigsuspend */
Index: sys/kern/syscalls.master
===================================================================
RCS file: /cvs/src/sys/kern/syscalls.master,v
retrieving revision 1.153
diff -u -p -u -r1.153 syscalls.master
--- sys/kern/syscalls.master    6 May 2015 11:20:07 -0000       1.153
+++ sys/kern/syscalls.master    21 May 2015 22:35:59 -0000
@@ -224,7 +224,7 @@
 106    STD             { int sys_listen(int s, int backlog); }
 107    STD             { int sys_chflagsat(int fd, const char *path, \
                            u_int flags, int atflags); }
-108    OBSOL           osigvec
+108    STD             { int sys_tame(int flags); }
 109    STD             { int sys_ppoll(struct pollfd *fds, \
                            u_int nfds, const struct timespec *ts, \
                            const sigset_t *mask); }
Index: sys/kern/uipc_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.103
diff -u -p -u -r1.103 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c    17 Jul 2015 15:23:59 -0000      1.103
+++ sys/kern/uipc_syscalls.c    17 Jul 2015 21:35:51 -0000
@@ -45,6 +45,7 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/signalvar.h>
+#include <sys/tame.h>
 #include <sys/unpcb.h>
 #include <sys/un.h>
 #ifdef KTRACE
@@ -78,6 +79,9 @@ sys_socket(struct proc *p, void *v, regi
        int type = SCARG(uap, type);
        int fd, error;
 
+       if (tame_socket_check(p, SCARG(uap, domain)))
+               return (tame_fail(p, EPERM, _TM_UNIX));
+
        fdplock(fdp);
        error = falloc(p, &fp, &fd);
        if (error == 0 && (type & SOCK_CLOEXEC))
@@ -120,6 +124,9 @@ sys_bind(struct proc *p, void *v, regist
        struct mbuf *nam;
        int error;
 
+       if (tame_bind_check(p, SCARG(uap, name)))
+               return (tame_fail(p, EPERM, _TM_UNIX));
+
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
                return (error);
        error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
@@ -315,6 +322,9 @@ sys_connect(struct proc *p, void *v, reg
        struct mbuf *nam = NULL;
        int error, s;
 
+       if (tame_connect_check(p))
+               return (tame_fail(p, EPERM, _TM_UNIX));
+
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
                return (error);
        so = fp->f_data;
@@ -455,6 +465,9 @@ sys_sendto(struct proc *p, void *v, regi
        struct msghdr msg;
        struct iovec aiov;
 
+       if (tame_sendto_check(p, SCARG(uap, to)))
+               return (tame_fail(p, EPERM, _TM_UNIX));
+
        msg.msg_name = (caddr_t)SCARG(uap, to);
        msg.msg_namelen = SCARG(uap, tolen);
        msg.msg_iov = &aiov;
@@ -479,6 +492,10 @@ sys_sendmsg(struct proc *p, void *v, reg
        int error;
 
        error = copyin(SCARG(uap, msg), &msg, sizeof (msg));
+
+       if (tame_sendto_check(p, msg.msg_name))
+               return (tame_fail(p, EPERM, _TM_UNIX));
+
        if (error)
                return (error);
        if (msg.msg_iovlen > IOV_MAX)
@@ -555,6 +572,11 @@ sendit(struct proc *p, int s, struct msg
                    mp->msg_controllen, MT_CONTROL);
                if (error)
                        goto bad;
+
+               if (tame_cmsg_send(p, control, mp->msg_controllen)) {
+                       m_free(control);
+                       goto bad;
+               }
        } else
                control = 0;
 #ifdef KTRACE
@@ -609,6 +631,9 @@ sys_recvfrom(struct proc *p, void *v, re
        struct iovec aiov;
        int error;
 
+       if (tame_recvfrom_check(p, SCARG(uap, from)))
+               return (tame_fail(p, EPERM, _TM_UNIX));
+
        if (SCARG(uap, fromlenaddr)) {
                error = copyin(SCARG(uap, fromlenaddr),
                    &msg.msg_namelen, sizeof (msg.msg_namelen));
@@ -640,6 +665,10 @@ sys_recvmsg(struct proc *p, void *v, reg
        int error;
 
        error = copyin(SCARG(uap, msg), &msg, sizeof (msg));
+
+       if (tame_recvfrom_check(p, msg.msg_name))
+               return (tame_fail(p, EPERM, _TM_UNIX));
+
        if (error)
                return (error);
        if (msg.msg_iovlen > IOV_MAX)
@@ -767,6 +796,8 @@ recvit(struct proc *p, int s, struct msg
                                        mp->msg_flags |= MSG_CTRUNC;
                                        i = len;
                                }
+                               if (tame_cmsg_recv(p, control, 
mp->msg_controllen))
+                                       goto out;
                                error = copyout(mtod(m, caddr_t), cp, i);
                                if (m->m_next)
                                        i = ALIGN(i);
@@ -824,6 +855,9 @@ sys_setsockopt(struct proc *p, void *v, 
        struct file *fp;
        struct mbuf *m = NULL;
        int error;
+
+       if (tame_setsockopt_check(p, SCARG(uap, level), SCARG(uap, name)))
+               return (tame_fail(p, EPERM, _TM_INET));
 
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
                return (error);
Index: sys/kern/vfs_lookup.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_lookup.c,v
retrieving revision 1.53
diff -u -p -u -r1.53 vfs_lookup.c
--- sys/kern/vfs_lookup.c       23 Apr 2015 02:55:15 -0000      1.53
+++ sys/kern/vfs_lookup.c       17 Jul 2015 23:27:18 -0000
@@ -51,6 +51,7 @@
 #include <sys/proc.h>
 #include <sys/file.h>
 #include <sys/fcntl.h>
+#include <sys/tame.h>
 
 #ifdef KTRACE
 #include <sys/ktrace.h>
@@ -126,6 +127,7 @@ namei(struct nameidata *ndp)
                error = ENOENT;
 
        if (error) {
+fail:
                pool_put(&namei_pool, cnp->cn_pnbuf);
                ndp->ni_vp = NULL;
                return (error);
@@ -164,6 +166,12 @@ namei(struct nameidata *ndp)
         */
        if ((ndp->ni_rootdir = fdp->fd_rdir) == NULL)
                ndp->ni_rootdir = rootvnode;
+       if ((p->p_p->ps_flags & PS_TAMED)) {
+               error = tame_namei(p, cnp->cn_pnbuf);
+               if (error)
+                       goto fail;
+       }
+
        /*
         * Check if starting from root directory or current directory.
         */
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.220
diff -u -p -u -r1.220 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c     7 May 2015 08:53:33 -0000       1.220
+++ sys/kern/vfs_syscalls.c     14 Jun 2015 19:54:27 -0000
@@ -812,6 +812,16 @@ sys_open(struct proc *p, void *v, regist
                syscallarg(int) flags;
                syscallarg(mode_t) mode;
        } */ *uap = v;
+       int flags = SCARG(uap, flags);
+
+       switch (flags & O_ACCMODE) {
+       case O_WRONLY:
+       case O_RDWR:
+               p->p_tamenote |= TMN_WRITE;
+               break;
+       }
+       if (flags & O_CREAT)
+               p->p_tamenote |= TMN_CREAT;
 
        return (doopenat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, flags),
            SCARG(uap, mode), retval));
@@ -1186,6 +1196,7 @@ sys_mknod(struct proc *p, void *v, regis
                syscallarg(int) dev;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_IMODIFY;
        return (domknodat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode),
            SCARG(uap, dev)));
 }
@@ -1280,6 +1291,7 @@ sys_mkfifo(struct proc *p, void *v, regi
                syscallarg(mode_t) mode;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_CREAT;
        return (domknodat(p, AT_FDCWD, SCARG(uap, path),
            (SCARG(uap, mode) & ALLPERMS) | S_IFIFO, 0));
 }
@@ -1309,6 +1321,7 @@ sys_link(struct proc *p, void *v, regist
                syscallarg(const char *) link;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_CREAT;
        return (dolinkat(p, AT_FDCWD, SCARG(uap, path), AT_FDCWD,
            SCARG(uap, link), AT_SYMLINK_FOLLOW));
 }
@@ -1382,6 +1395,7 @@ sys_symlink(struct proc *p, void *v, reg
                syscallarg(const char *) link;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_CREAT;
        return (dosymlinkat(p, SCARG(uap, path), AT_FDCWD, SCARG(uap, link)));
 }
 
@@ -1442,6 +1456,7 @@ sys_unlink(struct proc *p, void *v, regi
                syscallarg(const char *) path;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_CREAT;
        return (dounlinkat(p, AT_FDCWD, SCARG(uap, path), 0));
 }
 
@@ -1835,6 +1850,7 @@ sys_chflags(struct proc *p, void *v, reg
                syscallarg(u_int) flags;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_IMODIFY;
        return (dochflagsat(p, AT_FDCWD, SCARG(uap, path),
            SCARG(uap, flags), 0));
 }
@@ -1933,6 +1949,7 @@ sys_chmod(struct proc *p, void *v, regis
                syscallarg(mode_t) mode;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_IMODIFY;
        return (dofchmodat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode), 0));
 }
 
@@ -2028,6 +2045,7 @@ sys_chown(struct proc *p, void *v, regis
                syscallarg(gid_t) gid;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_IMODIFY;
        return (dofchownat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, uid),
            SCARG(uap, gid), 0));
 }
@@ -2111,6 +2129,7 @@ sys_lchown(struct proc *p, void *v, regi
        uid_t uid = SCARG(uap, uid);
        gid_t gid = SCARG(uap, gid);
 
+       p->p_tamenote |= TMN_IMODIFY;
        NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
        if ((error = namei(&nd)) != 0)
                return (error);
@@ -2207,6 +2226,7 @@ sys_utimes(struct proc *p, void *v, regi
        const struct timeval *tvp;
        int error;
 
+       p->p_tamenote |= TMN_IMODIFY;
        tvp = SCARG(uap, tptr);
        if (tvp != NULL) {
                error = copyin(tvp, tv, sizeof(tv));
@@ -2402,6 +2422,7 @@ sys_truncate(struct proc *p, void *v, re
        int error;
        struct nameidata nd;
 
+       p->p_tamenote |= TMN_IMODIFY;
        NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
        if ((error = namei(&nd)) != 0)
                return (error);
@@ -2501,6 +2522,7 @@ sys_rename(struct proc *p, void *v, regi
                syscallarg(const char *) to;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_IMODIFY;
        return (dorenameat(p, AT_FDCWD, SCARG(uap, from), AT_FDCWD,
            SCARG(uap, to)));
 }
@@ -2609,6 +2631,7 @@ sys_mkdir(struct proc *p, void *v, regis
                syscallarg(mode_t) mode;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_CREAT;
        return (domkdirat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode)));
 }
 
@@ -2667,6 +2690,7 @@ sys_rmdir(struct proc *p, void *v, regis
                syscallarg(const char *) path;
        } */ *uap = v;
 
+       p->p_tamenote |= TMN_CREAT;
        return (dounlinkat(p, AT_FDCWD, SCARG(uap, path), AT_REMOVEDIR));
 }
 
@@ -2761,6 +2785,7 @@ sys_revoke(struct proc *p, void *v, regi
        int error;
        struct nameidata nd;
 
+       p->p_tamenote |= TMN_CREAT;
        NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
        if ((error = namei(&nd)) != 0)
                return (error);
Index: sys/netinet/in_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.171
diff -u -p -u -r1.171 in_pcb.c
--- sys/netinet/in_pcb.c        15 Jul 2015 22:16:42 -0000      1.171
+++ sys/netinet/in_pcb.c        17 Jul 2015 20:44:57 -0000
@@ -79,6 +79,7 @@
 #include <sys/proc.h>
 #include <sys/domain.h>
 #include <sys/pool.h>
+#include <sys/tame.h>
 
 #include <net/if.h>
 #include <net/if_var.h>
@@ -442,6 +443,7 @@ in_pcbconnect(struct inpcb *inp, struct 
 {
        struct in_addr *ina = NULL;
        struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+       struct proc *p = curproc;
        int error;
 
 #ifdef INET6
@@ -457,6 +459,9 @@ in_pcbconnect(struct inpcb *inp, struct 
                return (EAFNOSUPPORT);
        if (sin->sin_port == 0)
                return (EADDRNOTAVAIL);
+
+       if (tame_dns_check(p, sin->sin_port))
+               return (tame_fail(p, EPERM, TAME_DNS));
 
        error = in_selectsrc(&ina, sin, inp->inp_moptions, &inp->inp_route,
            &inp->inp_laddr, inp->inp_rtableid);
Index: sys/netinet6/in6_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.68
diff -u -p -u -r1.68 in6_pcb.c
--- sys/netinet6/in6_pcb.c      8 Jun 2015 22:19:28 -0000       1.68
+++ sys/netinet6/in6_pcb.c      17 Jul 2015 20:45:14 -0000
@@ -108,6 +108,8 @@
 #include <sys/socketvar.h>
 #include <sys/errno.h>
 #include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/tame.h>
 
 #include <net/if.h>
 #include <net/if_var.h>
@@ -388,6 +390,7 @@ in6_pcbconnect(struct inpcb *inp, struct
        struct in6_addr *in6a = NULL;
        struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *);
        struct ifnet *ifp = NULL;       /* outgoing interface */
+       struct proc *p = curproc;
        int error = 0;
        struct sockaddr_in6 tmp;
 
@@ -399,6 +402,9 @@ in6_pcbconnect(struct inpcb *inp, struct
                return (EAFNOSUPPORT);
        if (sin6->sin6_port == 0)
                return (EADDRNOTAVAIL);
+
+       if (tame_dns_check(p, sin6->sin6_port))
+               return (tame_fail(p, EPERM, TAME_DNS));
 
        /* reject IPv4 mapped address, we have no support for it */
        if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
Index: sys/sys/proc.h
===================================================================
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.199
diff -u -p -u -r1.199 proc.h
--- sys/sys/proc.h      10 Feb 2015 05:28:18 -0000      1.199
+++ sys/sys/proc.h      14 Jun 2015 20:14:06 -0000
@@ -214,6 +214,8 @@ struct process {
 
        u_short ps_acflag;              /* Accounting flags. */
 
+       u_int   ps_tame;
+
 /* End area that is copied on creation. */
 #define ps_endcopy     ps_refcnt
        int     ps_refcnt;              /* Number of references. */
@@ -251,13 +253,14 @@ struct process {
 #define        PS_EMBRYO       0x00020000      /* New process, not yet fledged 
*/
 #define        PS_ZOMBIE       0x00040000      /* Dead and ready to be waited 
for */
 #define        PS_NOBROADCASTKILL 0x00080000   /* Process excluded from kill 
-1. */
+#define PS_TAMED       0x00100000      /* Has called tame(2) */
 
 #define        PS_BITS \
     ("\20" "\01CONTROLT" "\02EXEC" "\03INEXEC" "\04EXITING" "\05SUGID" \
      "\06SUGIDEXEC" "\07PPWAIT" "\010ISPWAIT" "\011PROFIL" "\012TRACED" \
      "\013WAITED" "\014COREDUMP" "\015SINGLEEXIT" "\016SINGLEUNWIND" \
      "\017NOZOMBIE" "\020STOPPED" "\021SYSTEM" "\022EMBRYO" "\023ZOMBIE" \
-     "\024NOBROADCASTKILL")
+     "\024NOBROADCASTKILL" "\025TAMED")
 
 
 struct proc {
@@ -321,6 +324,15 @@ struct proc {
        u_char  p_usrpri;       /* User-priority based on p_cpu and ps_nice. */
        char    p_comm[MAXCOMLEN+1];
 
+       int     p_tame_syscall; /* Cache of current syscall */
+       int     p_tamenote;     /* Observance during syscall */
+#define TMN_CREAT      0x00000001
+#define TMN_WRITE      0x00000002
+#define TMN_IMODIFY    0x00000004
+#define TMN_YPLOCK     0x00000008
+#define TMN_DNSRESOLV  0x00000010
+       int     p_tameafter;
+
 #ifndef        __HAVE_MD_TCB
        void    *p_tcb;         /* user-space thread-control-block address */
 # define TCB_SET(p, addr)      ((p)->p_tcb = (addr))
@@ -361,22 +373,22 @@ struct proc {
 /*
  * These flags are per-thread and kept in p_flag
  */
-#define        P_INKTR         0x000001        /* In a ktrace op, don't 
recurse */
-#define        P_PROFPEND      0x000002        /* SIGPROF needs to be posted */
-#define        P_ALRMPEND      0x000004        /* SIGVTALRM needs to be posted 
*/
-#define        P_SIGSUSPEND    0x000008        /* Need to restore 
before-suspend mask*/
-#define        P_CANTSLEEP     0x000010        /* insomniac thread */
-#define        P_SELECT        0x000040        /* Selecting; wakeup/waiting 
danger. */
-#define        P_SINTR         0x000080        /* Sleep is interruptible. */
-#define        P_SYSTEM        0x000200        /* No sigs, stats or swapping. 
*/
-#define        P_TIMEOUT       0x000400        /* Timing out during sleep. */
-#define        P_WEXIT         0x002000        /* Working on exiting. */
-#define        P_OWEUPC        0x008000        /* Owe proc an addupc() at next 
ast. */
-#define        P_SUSPSINGLE    0x080000        /* Need to stop for single 
threading. */
-#define P_SYSTRACE     0x400000        /* Process system call tracing active*/
-#define P_CONTINUED    0x800000        /* Proc has continued from a stopped 
state. */
-#define        P_THREAD        0x4000000       /* Only a thread, not a real 
process */
-#define        P_SUSPSIG       0x8000000       /* Stopped from signal. */
+#define        P_INKTR         0x00000001      /* In a ktrace op, don't 
recurse */
+#define        P_PROFPEND      0x00000002      /* SIGPROF needs to be posted */
+#define        P_ALRMPEND      0x00000004      /* SIGVTALRM needs to be posted 
*/
+#define        P_SIGSUSPEND    0x00000008      /* Need to restore 
before-suspend mask*/
+#define        P_CANTSLEEP     0x00000010      /* insomniac thread */
+#define        P_SELECT        0x00000040      /* Selecting; wakeup/waiting 
danger. */
+#define        P_SINTR         0x00000080      /* Sleep is interruptible. */
+#define        P_SYSTEM        0x00000200      /* No sigs, stats or swapping. 
*/
+#define        P_TIMEOUT       0x00000400      /* Timing out during sleep. */
+#define        P_WEXIT         0x00002000      /* Working on exiting. */
+#define        P_OWEUPC        0x00008000      /* Owe proc an addupc() at next 
ast. */
+#define        P_SUSPSINGLE    0x00080000      /* Need to stop for single 
threading. */
+#define P_SYSTRACE     0x00400000      /* Process system call tracing active*/
+#define P_CONTINUED    0x00800000      /* Proc has continued from a stopped 
state. */
+#define        P_THREAD        0x04000000      /* Only a thread, not a real 
process */
+#define        P_SUSPSIG       0x08000000      /* Stopped from signal. */
 #define        P_SOFTDEP       0x10000000      /* Stuck processing softdep 
worklist */
 #define P_CPUPEG       0x40000000      /* Do not move to another cpu. */
 
Index: sys/sys/syscall.h
===================================================================
RCS file: /cvs/src/sys/sys/syscall.h,v
retrieving revision 1.164
diff -u -p -u -r1.164 syscall.h
--- sys/sys/syscall.h   6 May 2015 11:26:02 -0000       1.164
+++ sys/sys/syscall.h   26 May 2015 17:40:00 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syscall.h,v 1.164 2015/05/06 11:26:02 jsg Exp $       */
+/*     $OpenBSD$       */
 
 /*
  * System call numbers.
@@ -329,7 +329,9 @@
 /* syscall: "chflagsat" ret: "int" args: "int" "const char *" "u_int" "int" */
 #define        SYS_chflagsat   107
 
-                               /* 108 is obsolete osigvec */
+/* syscall: "tame" ret: "int" args: "int" */
+#define        SYS_tame        108
+
 /* syscall: "ppoll" ret: "int" args: "struct pollfd *" "u_int" "const struct 
timespec *" "const sigset_t *" */
 #define        SYS_ppoll       109
 
Index: sys/sys/syscall_mi.h
===================================================================
RCS file: /cvs/src/sys/sys/syscall_mi.h,v
retrieving revision 1.5
diff -u -p -u -r1.5 syscall_mi.h
--- sys/sys/syscall_mi.h        11 May 2014 00:12:44 -0000      1.5
+++ sys/sys/syscall_mi.h        18 Jul 2015 00:02:54 -0000
@@ -33,6 +33,7 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/tame.h>
 #include <sys/proc.h>
 
 #ifdef KTRACE
@@ -53,7 +54,7 @@ mi_syscall(struct proc *p, register_t co
     register_t *argp, register_t retval[2])
 {
        int lock = !(callp->sy_flags & SY_NOLOCK);
-       int error;
+       int error, tamed, tval;
 
        /* refresh the thread's cache of the process's creds */
        refreshcreds(p);
@@ -76,15 +77,27 @@ mi_syscall(struct proc *p, register_t co
                KERNEL_LOCK();
                error = systrace_redirect(code, p, argp, retval);
                KERNEL_UNLOCK();
-       } else
+               return (error);
+       }
 #endif
-       {
-               if (lock)
+
+       if (lock)
+               KERNEL_LOCK();
+       tamed = (p->p_p->ps_flags & PS_TAMED);
+       if (tamed && !(tval = tame_check(p, code))) {
+               if (!lock)
                        KERNEL_LOCK();
-               error = (*callp->sy_call)(p, argp, retval);
-               if (lock)
+               error = tame_fail(p, EPERM, tval);
+               if (!lock)
                        KERNEL_UNLOCK();
+               }
+       else {
+               error = (*callp->sy_call)(p, argp, retval);
+               if (tamed && p->p_tameafter)
+                       tame_aftersyscall(p, code, error);
        }
+       if (lock)
+               KERNEL_UNLOCK();
 
        return (error);
 }
Index: sys/sys/syscallargs.h
===================================================================
RCS file: /cvs/src/sys/sys/syscallargs.h,v
retrieving revision 1.166
diff -u -p -u -r1.166 syscallargs.h
--- sys/sys/syscallargs.h       6 May 2015 11:26:02 -0000       1.166
+++ sys/sys/syscallargs.h       26 May 2015 17:40:00 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syscallargs.h,v 1.166 2015/05/06 11:26:02 jsg Exp $   */
+/*     $OpenBSD$       */
 
 /*
  * System call argument lists.
@@ -538,6 +538,10 @@ struct sys_chflagsat_args {
        syscallarg(int) atflags;
 };
 
+struct sys_tame_args {
+       syscallarg(int) flags;
+};
+
 struct sys_ppoll_args {
        syscallarg(struct pollfd *) fds;
        syscallarg(u_int) nfds;
@@ -1189,6 +1193,7 @@ int       sys_bind(struct proc *, void *, regi
 int    sys_setsockopt(struct proc *, void *, register_t *);
 int    sys_listen(struct proc *, void *, register_t *);
 int    sys_chflagsat(struct proc *, void *, register_t *);
+int    sys_tame(struct proc *, void *, register_t *);
 int    sys_ppoll(struct proc *, void *, register_t *);
 int    sys_pselect(struct proc *, void *, register_t *);
 int    sys_sigsuspend(struct proc *, void *, register_t *);
Index: sys/sys/tame.h
===================================================================
RCS file: sys/sys/tame.h
diff -N sys/sys/tame.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/sys/tame.h      18 Jul 2015 20:52:00 -0000
@@ -0,0 +1,89 @@
+/*     $OpenBSD$       */
+
+/*
+ * Copyright (c) 2015 Nicholas Marriott <n...@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 MIND, 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.
+ */
+
+#ifndef _SYS_TAME_H_
+#define _SYS_TAME_H_
+
+#include <sys/cdefs.h>
+
+#define _TM_SELF       0x00000001      /* operate on own pid */
+#define _TM_RW         0x00000002      /* basic io operations */
+#define _TM_MALLOC     0x00000004      /* enough for malloc */
+#define _TM_DNSPATH    0x00000008      /* access to DNS pathnames */
+#define _TM_RPATH      0x00000010      /* allow open for read */
+#define _TM_WPATH      0x00000020      /* allow open for write */
+#define _TM_TMPPATH    0x00000040      /* for mk*temp() */
+#define _TM_INET       0x00000080      /* AF_INET/AF_INET6 sockets */
+#define _TM_UNIX       0x00000100      /* AF_UNIX sockets */
+#define _TM_CMSG       0x00000200      /* AF_UNIX CMSG fd passing */
+#define _TM_IOCTL      0x00000400      /* scary */
+#define _TM_GETPW      0x00000800      /* enough to enable YP */
+#define _TM_PROC       0x00001000      /* fork, waitpid, etc */
+#define _TM_CPATH      0x00002000      /* allow create, mkdir, or inode mods */
+
+#define _TM_ABORT      0x08000000      /* SIGABRT instea of SIGKILL */
+
+/* Following flags are set by kernel, as it learns things.
+ * Not user settable. Should be moved to a seperate variable */
+#define _TM_USERSET    0x0fffffff
+#define _TM_YP_ACTIVE  0x10000000      /* YP use detected and allowed */
+#define _TM_DNS_ACTIVE 0x20000000      /* DNS use detected and allowed */
+
+#define TAME_MALLOC    (_TM_SELF | _TM_MALLOC)
+#define TAME_RW                (_TM_SELF | _TM_RW)
+#define TAME_STDIO     (_TM_SELF | _TM_MALLOC | _TM_RW)
+#define TAME_RPATH     (_TM_SELF | _TM_RW | _TM_RPATH)
+#define TAME_WPATH     (_TM_SELF | _TM_RW | _TM_WPATH)
+#define TAME_TMPPATH   (_TM_SELF | _TM_RW | _TM_TMPPATH)
+#define TAME_INET      (_TM_SELF | _TM_RW | _TM_INET)
+#define TAME_UNIX      (_TM_SELF | _TM_RW | _TM_UNIX)
+#define TAME_CMSG      (TAME_UNIX | _TM_CMSG)
+#define TAME_DNS       (TAME_MALLOC | _TM_DNSPATH)
+#define TAME_IOCTL     (_TM_IOCTL)
+#define TAME_GETPW     (TAME_STDIO | _TM_GETPW)
+#define TAME_PROC      (_TM_PROC)
+#define TAME_CPATH     (_TM_CPATH)
+#define TAME_ABORT     (_TM_ABORT)
+
+#ifdef _KERNEL
+
+int    tame_check(struct proc *, int);
+int    tame_fail(struct proc *, int, int);
+int    tame_namei(struct proc *, char *);
+void   tame_aftersyscall(struct proc *, int, int);
+
+int    tame_cmsg_send(struct proc *p, void *v, int controllen);
+int    tame_cmsg_recv(struct proc *p, void *v, int controllen);
+int    tame_sysctl_check(struct proc *p, int namelen, int *name, void *new);
+int    tame_adjtime_check(struct proc *p, const void *v);
+int    tame_recvfrom_check(struct proc *p, void *from);
+int    tame_sendto_check(struct proc *p, const void *to);
+int    tame_bind_check(struct proc *p, const void *v);
+int    tame_connect_check(struct proc *p);
+int    tame_socket_check(struct proc *p, int domain);
+int    tame_setsockopt_check(struct proc *p, int level, int optname);
+int    tame_dns_check(struct proc *p, in_port_t port);
+int    tame_ioctl_check(struct proc *p, long com, void *);
+
+#else /* _KERNEL */
+
+int    tame(int);
+
+#endif /* _KERNEL */
+
+#endif /* _SYS_TAME_H_ */
Index: bin/cat/cat.c
===================================================================
RCS file: /cvs/src/bin/cat/cat.c,v
retrieving revision 1.21
diff -u -p -u -r1.21 cat.c
--- bin/cat/cat.c       16 Jan 2015 06:39:28 -0000      1.21
+++ bin/cat/cat.c       24 May 2015 01:03:25 -0000
@@ -35,6 +35,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/tame.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -65,6 +66,8 @@ main(int argc, char *argv[])
        int ch;
 
        setlocale(LC_ALL, "");
+
+       tame(TAME_STDIO | TAME_RPATH);
 
        while ((ch = getopt(argc, argv, "benstuv")) != -1)
                switch (ch) {
Index: bin/pax/pax.c
===================================================================
RCS file: /cvs/src/bin/pax/pax.c,v
retrieving revision 1.41
diff -u -p -u -r1.41 pax.c
--- bin/pax/pax.c       9 Mar 2015 04:23:29 -0000       1.41
+++ bin/pax/pax.c       4 Jun 2015 20:54:58 -0000
@@ -38,6 +38,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/tame.h>
 #include <signal.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -255,6 +256,10 @@ main(int argc, char **argv)
        options(argc, argv);
        if ((gen_init() < 0) || (tty_init() < 0))
                return(exit_val);
+
+       if (gzip_program == NULL)
+               tame(TAME_STDIO | TAME_GETPW | TAME_IOCTL | TAME_PROC |
+                   TAME_CPATH | TAME_WPATH | TAME_RPATH);
 
        /*
         * select a primary operation mode
Index: bin/ps/print.c
===================================================================
RCS file: /cvs/src/bin/ps/print.c,v
retrieving revision 1.61
diff -u -p -u -r1.61 print.c
--- bin/ps/print.c      29 Jun 2015 15:03:33 -0000      1.61
+++ bin/ps/print.c      14 Jul 2015 18:35:53 -0000
@@ -269,6 +269,8 @@ state(const struct kinfo_proc *kp, VAREN
                *cp++ = 's';
        if ((kp->p_psflags & PS_CONTROLT) && kp->p__pgid == kp->p_tpgid)
                *cp++ = '+';
+       if (kp->p_psflags & PS_TAMED)
+               *cp++ = 't';
        *cp = '\0';
 
        if (state == 'R' && kp->p_cpuid != KI_NOCPU) {
Index: bin/ps/ps.1
===================================================================
RCS file: /cvs/src/bin/ps/ps.1,v
retrieving revision 1.99
diff -u -p -u -r1.99 ps.1
--- bin/ps/ps.1 29 Jun 2015 15:03:33 -0000      1.99
+++ bin/ps/ps.1 14 Jul 2015 18:35:53 -0000
@@ -341,6 +341,7 @@ PS_SYSTEM          0x10000 No signals, s
 PS_EMBRYO          0x20000 New process, not yet fledged
 PS_ZOMBIE          0x40000 Dead and ready to be waited for
 PS_NOBROADCASTKILL 0x80000 Process excluded from kill -1
+PS_TAMED          0x100000 process has called tame(2)
 .Ed
 .It Cm re
 Core residency time (in seconds; 127 = infinity).
@@ -463,6 +464,9 @@ scheduling priority.
 .\" sequentially address voluminous data).
 .It s
 The process is a session leader.
+.It t
+The process has called
+.Xr tame 2 .
 .It V
 The process is suspended during a
 .Xr vfork 2 .
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.125
diff -u -p -u -r1.125 Makefile.inc
--- lib/libc/sys/Makefile.inc   7 Apr 2015 01:27:07 -0000       1.125
+++ lib/libc/sys/Makefile.inc   21 May 2015 22:35:59 -0000
@@ -56,7 +56,7 @@ ASM=  __get_tcb.o __getcwd.o __semctl.o _
        settimeofday.o setuid.o shmat.o shmctl.o shmdt.o \
        shmget.o shutdown.o sigaction.o sigaltstack.o socket.o \
        socketpair.o stat.o statfs.o swapctl.o symlink.o \
-       symlinkat.o sync.o sysarch.o umask.o unlink.o unlinkat.o \
+       symlinkat.o sync.o sysarch.o tame.o umask.o unlink.o unlinkat.o \
        unmount.o utimensat.o utimes.o utrace.o wait4.o write.o writev.o
 
 SRCS+= ${SRCS_${MACHINE_CPU}}
@@ -218,7 +218,7 @@ MAN+=       __get_tcb.2 __thrsigdivert.2 __thr
        shmctl.2 shmget.2 shutdown.2 sigaction.2 sigaltstack.2 sigpending.2 \
        sigprocmask.2 sigreturn.2 sigsuspend.2 socket.2 \
        socketpair.2 stat.2 statfs.2 swapctl.2 symlink.2 \
-       sync.2 sysarch.2 syscall.2 truncate.2 umask.2 unlink.2 \
+       sync.2 sysarch.2 syscall.2 tame.2 truncate.2 umask.2 unlink.2 \
        utimes.2 utrace.2 vfork.2 wait.2 write.2
 
 MLINKS+=__get_tcb.2 __set_tcb.2
Index: lib/libc/sys/tame.2
===================================================================
RCS file: lib/libc/sys/tame.2
diff -N lib/libc/sys/tame.2
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/libc/sys/tame.2 18 Jul 2015 22:16:20 -0000
@@ -0,0 +1,381 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2015 Nicholas Marriott <n...@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.
+.\"
+.Dd $Mdocdate$
+.Dt TAME 2
+.Os
+.Sh NAME
+.Nm tame
+.Nd restrict system operations
+.Sh SYNOPSIS
+.In sys/tame.h
+.Ft int
+.Fn tame "int flags"
+.Sh DESCRIPTION
+The current process is forced into a restricted-service operating mode.
+A few subsets are available, roughly described as computation, memory
+management, read-write operations on file descriptors, opening of files,
+networking.  In general, these modes were selected by studying the operation
+of many programs using libc and other such interfaces.
+.Pp
+Use of
+.Nm tame
+in an application will require at least some study and understanding
+of the interfaces called.
+.Pp
+Subsequent calls to
+.Fn tame
+can reduce abilities further, but abilities can never be regained.
+.Pp
+A process which attempts a restricted operation is killed with
+.Dv SIGKILL .
+If
+.Va TAME_ABORT
+is set, then a non-blockable SIGABRT is delivered instead, possibly
+resulting in a
+.Xr core 5
+file.
+.Pp
+A
+.Fa flags
+value of 0 restricts the process to the
+.Xr _exit 2
+system call.
+This can be used for pure computation operating on memory shared
+with another process.
+.Pp
+All
+.Ar TAME_*
+options below (with the exception of
+.Ar TAME_ABORT )
+permit the following system calls: 
+.Pp
+.Bd -ragged -offset indent
+.Xr clock_getres 2 ,
+.Xr clock_gettime 2 ,
+.Xr fchdir 2 ,
+.Xr getdtablecount 2 ,
+.Xr getegid 2 ,
+.Xr geteuid 2 ,
+.Xr getgid 2 ,
+.Xr getgroups 2 ,
+.Xr getitimer 2 ,
+.Xr getlogin 2 ,
+.Xr getpgid 2 ,
+.Xr getpgrp 2 ,
+.Xr getpid 2 ,
+.Xr getppid 2 ,
+.Xr getresgid 2 ,
+.Xr getresuid 2 ,
+.Xr getrlimit 2 ,
+.Xr getsid 2 ,
+.Xr getthrid 2 ,
+.Xr gettimeofday 2 ,
+.Xr getuid 2 ,
+.Xr getuid 2 ,
+.Xr issetugid 2 ,
+.Xr nanosleep 2 ,
+.Xr sendsyslog 2 ,
+.Xr setitimer 2 ,
+.Xr sigaction 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigreturn 2 ,
+.Xr umask 2 ,
+.Xr wait4 2 .
+.Ed
+.Pp
+Calls allowed with restrictions include:
+.Bl -tag -width TAME_TMPPATH -offset indent -compact
+.It Xr sysctl 3
+A small set of read-only operations are allowed, sufficient to
+support:
+.Xr getifaddrs 3 ,
+.Xr getdomainname 3 ,
+.Xr gethostname 3 ,
+system sensor readings.
+.It Xr access 2
+May check for existance of
+.Pa /etc/localtime .
+.It Xr adjtime 2
+Read-only, for
+.Xr ntpd 8 .
+.It Xr open 2
+May open
+.Pa /etc/localtime ,
+any files below
+.Pa /usr/share/zoneinfo
+and files ending in
+.Pa libc.cat
+in below the directory
+.Pa /usr/share/nls/ .
+.It Xr readlink 2
+May operate on
+.Pa /etc/malloc.conf .
+.It Xr tame 2
+Can only reduce permissions.
+.El
+.Pp
+The
+.Ar flags
+are specified as a bitwise OR of the following values:
+.Bl -tag -width TAME_TMPPATH -offset indent -compact
+.Pp
+.It Ar TAME_MALLOC
+To allow use of the
+.Xr malloc 3
+family of functions, the following system calls are permitted:
+.Pp
+.Xr getentropy 2 ,
+.Xr madvise 2 ,
+.Xr minherit 2 ,
+.Xr mmap 2 ,
+.Xr mprotect 2 ,
+.Xr mquery 2 ,
+.Xr munmap 2 .
+.Pp
+.It Ar TAME_RW
+The following system calls are permitted to allow most types of IO
+operations on previously allocated file descriptors, including
+libevent or handwritten async IO loops:
+.Pp
+.Xr poll 2 ,
+.Xr kevent 2 ,
+.Xr kqueue 2 ,
+.Xr select 2 ,
+.Xr close 2 ,
+.Xr dup 2 ,
+.Xr dup2 2 ,
+.Xr dup3 2 ,
+.Xr closefrom 2 ,
+.Xr shutdown 2 ,
+.Xr read 2 ,
+.Xr readv 2 ,
+.Xr pread 2 ,
+.Xr preadv 2 ,
+.Xr write 2 ,
+.Xr writev 2 ,
+.Xr pwrite 2 ,
+.Xr pwritev 2 ,
+.Xr ftruncate 2 ,
+.Xr lseek 2 ,
+.Xr utimes 2 ,
+.Xr futimes 2 ,
+.Xr utimensat 2 ,
+.Xr futimens 2 ,
+.Xr fcntl 2 ,
+.Xr fsync 2 ,
+.Xr pipe 2 ,
+.Xr pipe2 2 ,
+.Xr socketpair 2 ,
+.Xr getdents 2 ,
+.Xr sendto 2 ,
+.Xr sendmsg 2 ,
+.Xr recvmsg 2 ,
+.Xr recvfrom 2 ,
+.Xr fstat 2 .
+.Pp
+.It Ar TAME_STDIO
+This subset is simply the combination of
+.Ar TAME_MALLOC
+and
+.Ar TAME_RW .
+As a result, all functionalities of libc 
+stdio works.
+.Pp
+.It Ar TAME_RPATH
+A number of system calls are allowed if they only cause
+read-only effects on the filesystem:
+.Pp
+.Xr chdir 2 ,
+.Xr getcwd 3 ,
+.Xr openat 2 ,
+.Xr fstatat 2 ,
+.Xr faccessat 2 ,
+.Xr readlinkat 2 ,
+.Xr lstat 2 ,
+.Xr chmod 2 ,
+.Xr fchmod 2 ,
+.Xr fchmodat 2 ,
+.Xr chflags 2 ,
+.Xr chflagsat 2 ,
+.Xr chown 2 ,
+.Xr fchown 2 ,
+.Xr fchownat 2 ,
+.Xr fstat 2 .
+.Pp
+.It Ar TAME_WPATH
+A number of system calls are allowed and may cause
+write-effects on the filesystem:
+read-only effects:
+.Pp
+.Xr getcwd 3 ,
+.Xr openat 2 ,
+.Xr fstatat 2 ,
+.Xr faccessat 2 ,
+.Xr readlinkat 2 ,
+.Xr lstat 2 ,
+.Xr chmod 2 ,
+.Xr fchmod 2 ,
+.Xr fchmodat 2 ,
+.Xr chflags 2 ,
+.Xr chflagsat 2 ,
+.Xr chown 2 ,
+.Xr fchown 2 ,
+.Xr fchownat 2 ,
+.Xr fstat 2 ,
+.Xr fstat 2 .
+.Pp
+.It Ar TAME_TMPPATH
+A number of system calls are allowed to do operations in the
+.Pa /tmp
+directory, including create, read, or write:
+.Pp
+.Xr lstat 2 ,
+.Xr chmod 2 ,
+.Xr chflags 2 ,
+.Xr chown 2 ,
+.Xr unlink 2 ,
+.Xr fstat 2 .
+.Pp
+.It Ar TAME_CPATH
+A number of system calls and sub-modes are allowed, which may
+create new files or directories in the filesystem:
+.Pp
+.Xr rename 2 ,
+.Xr rmdir 2 ,
+.Xr renameat 2 ,
+.Xr link 2 ,
+.Xr linkat 2 ,
+.Xr symlink 2 ,
+.Xr unlink 2 ,
+.Xr unlinkat 2 ,
+.Xr mkdir 2 ,
+.Xr mkdirat 2 .
+.Pp
+.It Ar TAME_INET
+The following system calls are allowed to operate in the
+.Ar AF_INET
+and
+.Ar AF_INET6
+domains:
+.Pp
+.Xr socket 2 ,
+.Xr listen 2 ,
+.Xr bind 2 ,
+.Xr connect 2 ,
+.Xr accept4 2 ,
+.Xr accept 2 ,
+.Xr getpeername 2 ,
+.Xr getsockname 2 ,
+.Xr setsockopt 2 ,
+.Xr getsockopt 2 .
+.Pp
+.Xr setsockopt 2
+has been reduced in functionality substantially.
+.It Ar TAME_UNIX
+The following system calls are allowed to operate in the
+.Ar AF_UNIX
+domain:
+.Pp
+.Xr socket 2 ,
+.Xr listen 2 ,
+.Xr bind 2 ,
+.Xr connect 2 ,
+.Xr accept4 2 ,
+.Xr accept 2 ,
+.Xr getpeername 2 ,
+.Xr getsockname 2 ,
+.Xr setsockopt 2 ,
+.Xr getsockopt 2 .
+.Pp
+.It Ar TAME_DNSPATH
+Subsequent to a succesfull
+.Xr open 2
+of
+.Pa /etc/resolv.conf ,
+a few system calls become to allow DNS network transactions:
+.Pp
+.Xr sendto 2 ,
+.Xr recvfrom 2 ,
+.Xr socket 2 ,
+.Xr connect 2 .
+.Pp
+.It Ar TAME_GETPW
+This allows read-only opening of files in
+.Pa /etc
+for the
+.Xr getpwnam 3 ,
+.Xr getgrnam 3,
+.Xr getgrouplist 3 ,
+and
+.Xr initgroups 3
+family of functions.
+They may also need to operate in a
+.Xr yp 8
+environment, so a succesfull
+.Xr open 2
+of
+.Pa /var/run/ypbind.lock
+enables the
+.Ar TAME_INET
+flag.
+.Pp
+.It Ar TAME_CMSG
+Allows passing of file descriptors using the
+.Xr sendmsg 2
+and
+.Xr recvmsg 2
+functions.
+.Pp
+.It Ar TAME_IOCTL
+Allows a subset of
+.Xr ioctl 2
+operations:
+.Pp
+.Va FIOCLEX ,
+.Va FIONCLEX ,
+.Va FIONREAD ,
+.Va FIONBIO ,
+.Va FIOGETOWN ,
+.Va TIOCSWINSZ ,
+.Va TIOCSTI .
+.Pp
+.It Ar TAME_PROC
+Allows the following process relationship operations:
+.Pp
+.Xr fork 2 ,
+.Xr vfork 2 ,
+.Xr kill 2 ,
+.Xr setresgid 2 ,
+.Xr SYS_setresuid 2 ,
+.Pp
+.It Ar TAME_ABORT
+Deliver an unblockable SIGABRT upon violation instead of SIGKILL.
+.El
+.Sh RETURN VALUES
+.Rv -std
+.Sh ERRORS
+.Fn tame
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+This process is attempting to increase permissions.
+.El
+.Sh HISTORY
+The
+.Fn tame
+system call appeared in
+.Ox 5.8 .
Index: regress/etc/Makefile
===================================================================
RCS file: /cvs/src/regress/etc/Makefile,v
retrieving revision 1.2
diff -u -p -u -r1.2 Makefile
--- regress/etc/Makefile        23 Feb 2002 01:25:10 -0000      1.2
+++ regress/etc/Makefile        28 May 2015 23:12:08 -0000
@@ -1,6 +1,6 @@
 #      $OpenBSD: Makefile,v 1.2 2002/02/23 01:25:10 art Exp $
 
-SUBDIR+= MAKEDEV
+#SUBDIR+= MAKEDEV
 
 install:
 
Index: regress/sys/kern/Makefile
===================================================================
RCS file: /cvs/src/regress/sys/kern/Makefile,v
retrieving revision 1.63
diff -u -p -u -r1.63 Makefile
--- regress/sys/kern/Makefile   10 Feb 2015 00:45:31 -0000      1.63
+++ regress/sys/kern/Makefile   15 Jun 2015 01:22:40 -0000
@@ -14,7 +14,7 @@ SUBDIR+= rlimit-file signal signal-stres
 SUBDIR+= sosplice
 SUBDIR+= syscall sysvmsg sysvsem
 SUBDIR+= sysvshm unalign unfdpass wait
-SUBDIR+= sig-stop
+#SUBDIR+= sig-stop
 SUBDIR+= unixsock bind
 
 install:
Index: regress/usr.bin/signify/Makefile
===================================================================
RCS file: /cvs/src/regress/usr.bin/signify/Makefile,v
retrieving revision 1.4
diff -u -p -u -r1.4 Makefile
--- regress/usr.bin/signify/Makefile    17 Mar 2014 02:49:02 -0000      1.4
+++ regress/usr.bin/signify/Makefile    15 Jun 2015 00:55:33 -0000
@@ -4,7 +4,7 @@ CLEANFILES += test.sig confirmorders con
 REGRESS_TARGETS = t1
 
 t1:
-       @sh ${.CURDIR}/signify.sh ${.CURDIR}
+       sh ${.CURDIR}/signify.sh ${.CURDIR}
 
 .PHONY: t1
 
Index: sbin/dmesg/dmesg.c
===================================================================
RCS file: /cvs/src/sbin/dmesg/dmesg.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 dmesg.c
--- sbin/dmesg/dmesg.c  16 Jan 2015 06:39:57 -0000      1.25
+++ sbin/dmesg/dmesg.c  28 May 2015 08:58:51 -0000
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <sys/msgbuf.h>
 #include <sys/sysctl.h>
+#include <sys/tame.h>
 
 #include <err.h>
 #include <fcntl.h>
@@ -107,6 +108,8 @@ main(int argc, char *argv[])
                len = msgbufsize;
                if (sysctl(mib, 2, bufdata, &len, NULL, 0))
                        err(1, "sysctl: KERN_MSGBUF");
+
+               tame(TAME_STDIO);
 
                memcpy(&cur, bufdata, sizeof(cur));
                bufdata = ((struct msgbuf *)bufdata)->msg_bufc;
Index: sbin/ping/ping.c
===================================================================
RCS file: /cvs/src/sbin/ping/ping.c,v
retrieving revision 1.123
diff -u -p -u -r1.123 ping.c
--- sbin/ping/ping.c    2 May 2015 18:03:37 -0000       1.123
+++ sbin/ping/ping.c    26 May 2015 21:25:52 -0000
@@ -55,6 +55,7 @@
 #include <sys/queue.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <netinet/ip.h>
@@ -347,15 +348,6 @@ main(int argc, char *argv[])
        if (argc != 1)
                usage();
 
-       arc4random_buf(&tv64_offset, sizeof(tv64_offset));
-       arc4random_buf(&mac_key, sizeof(mac_key));
-
-       memset(&interstr, 0, sizeof(interstr));
-
-       interstr.it_value.tv_sec = interval;
-       interstr.it_value.tv_usec =
-               (long) ((interval - interstr.it_value.tv_sec) * 1000000);
-
        target = *argv;
 
        memset(&whereto, 0, sizeof(whereto));
@@ -374,6 +366,33 @@ main(int argc, char *argv[])
                hostname = hnamebuf;
        }
 
+       if (options & F_SADDR) {
+               if (IN_MULTICAST(ntohl(to->sin_addr.s_addr)))
+                       moptions |= MULTICAST_IF;
+               else {
+                       memset(&whence, 0, sizeof(whence));
+                       whence.sin_len = sizeof(whence);
+                       whence.sin_family = AF_INET;
+                       memcpy(&whence.sin_addr.s_addr, &saddr, sizeof(saddr));
+                       if (bind(s, (struct sockaddr *)&whence,
+                           sizeof(whence)) < 0)
+                               err(1, "bind");
+               }
+       }
+
+       if (options & F_SO_DEBUG)
+               (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, &optval,
+                   sizeof(optval));
+
+       arc4random_buf(&tv64_offset, sizeof(tv64_offset));
+       arc4random_buf(&mac_key, sizeof(mac_key));
+
+       memset(&interstr, 0, sizeof(interstr));
+
+       interstr.it_value.tv_sec = interval;
+       interstr.it_value.tv_usec =
+               (long) ((interval - interstr.it_value.tv_sec) * 1000000);
+
        if (options & F_FLOOD && options & F_INTERVAL)
                errx(1, "-f and -i options are incompatible");
 
@@ -393,24 +412,6 @@ main(int argc, char *argv[])
 
        ident = getpid() & 0xFFFF;
 
-       if (options & F_SADDR) {
-               if (IN_MULTICAST(ntohl(to->sin_addr.s_addr)))
-                       moptions |= MULTICAST_IF;
-               else {
-                       memset(&whence, 0, sizeof(whence));
-                       whence.sin_len = sizeof(whence);
-                       whence.sin_family = AF_INET;
-                       memcpy(&whence.sin_addr.s_addr, &saddr, sizeof(saddr));
-                       if (bind(s, (struct sockaddr *)&whence,
-                           sizeof(whence)) < 0)
-                               err(1, "bind");
-               }
-       }
-
-       if (options & F_SO_DEBUG)
-               (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, &optval,
-                   sizeof(optval));
-
        if (options & F_TTL) {
                if (IN_MULTICAST(ntohl(to->sin_addr.s_addr)))
                        moptions |= MULTICAST_TTL;
@@ -500,6 +501,11 @@ main(int argc, char *argv[])
                    datalen);
        else
                (void)printf("PING %s: %d data bytes\n", hostname, datalen);
+
+       if (options & F_NUMERIC)
+               tame(TAME_STDIO | TAME_INET);
+       else
+               tame(TAME_STDIO | TAME_INET | TAME_DNS);
 
        (void)signal(SIGINT, finish);
        (void)signal(SIGALRM, catcher);
Index: sbin/ping6/ping6.c
===================================================================
RCS file: /cvs/src/sbin/ping6/ping6.c,v
retrieving revision 1.108
diff -u -p -u -r1.108 ping6.c
--- sbin/ping6/ping6.c  2 May 2015 17:19:42 -0000       1.108
+++ sbin/ping6/ping6.c  26 May 2015 21:26:23 -0000
@@ -83,6 +83,7 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
+#include <sys/tame.h>
 
 #include <net/if.h>
 #include <net/route.h>
@@ -772,6 +773,11 @@ main(int argc, char *argv[])
 
                close(dummy);
        }
+
+       if (options & F_HOSTNAME)
+               tame(TAME_INET | TAME_DNS);
+       else
+               tame(TAME_INET);
 
        if (sockbufsize) {
                if (datalen > sockbufsize)
Index: usr.bin/dc/dc.c
===================================================================
RCS file: /cvs/src/usr.bin/dc/dc.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 dc.c
--- usr.bin/dc/dc.c     26 Nov 2014 18:34:51 -0000      1.13
+++ usr.bin/dc/dc.c     26 May 2015 19:28:31 -0000
@@ -48,6 +48,9 @@ main(int argc, char *argv[])
        struct stat     st;
 
 
+#include <sys/tame.h>
+       tame(TAME_STDIO | TAME_RW);
+
        if ((buf = strdup("")) == NULL)
                err(1, NULL);
        /* accept and ignore a single dash to be 4.4BSD dc(1) compatible */
Index: usr.bin/diff/diff.c
===================================================================
RCS file: /cvs/src/usr.bin/diff/diff.c,v
retrieving revision 1.59
diff -u -p -u -r1.59 diff.c
--- usr.bin/diff/diff.c 29 Apr 2015 04:00:25 -0000      1.59
+++ usr.bin/diff/diff.c 5 Jun 2015 00:07:31 -0000
@@ -21,6 +21,7 @@
  */
 
 #include <sys/stat.h>
+#include <sys/tame.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -216,6 +217,9 @@ main(int argc, char **argv)
        }
        argc -= optind;
        argv += optind;
+
+       if (lflag == 0)
+               tame(TAME_STDIO | TAME_WPATH | TAME_RPATH | TAME_TMPPATH);
 
        /*
         * Do sanity checks, fill in stb1 and stb2 and call the appropriate
Index: usr.bin/finger/finger.c
===================================================================
RCS file: /cvs/src/usr.bin/finger/finger.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 finger.c
--- usr.bin/finger/finger.c     16 Jan 2015 06:40:07 -0000      1.19
+++ usr.bin/finger/finger.c     25 May 2015 21:51:46 -0000
@@ -58,6 +58,7 @@
 
 #include <sys/file.h>
 #include <sys/stat.h>
+#include <sys/tame.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -125,6 +126,8 @@ main(int argc, char *argv[])
                if (sb.st_size > 1048576)
                        mflag++;
        }
+
+       tame(TAME_STDIO | TAME_GETPW | TAME_RPATH);
 
        (void)time(&now);
        setpassent(1);
Index: usr.bin/from/from.c
===================================================================
RCS file: /cvs/src/usr.bin/from/from.c,v
retrieving revision 1.20
diff -u -p -u -r1.20 from.c
--- usr.bin/from/from.c 3 Jun 2015 18:08:54 -0000       1.20
+++ usr.bin/from/from.c 3 Jun 2015 19:15:43 -0000
@@ -31,6 +31,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/tame.h>
 #include <ctype.h>
 #include <pwd.h>
 #include <stdio.h>
@@ -74,12 +75,14 @@ main(int argc, char *argv[])
        }
        argv += optind;
 
+       tame(TAME_STDIO | TAME_RPATH);
        file = mail_spool(file, *argv);
        if ((fp = fopen(file, "r")) == NULL) {
                if (!fflag && errno == ENOENT)
                        exit(EXIT_SUCCESS);
                err(1, "%s", file);
        }
+       tame(TAME_STDIO);
        for (newline = 1; (linelen = getline(&line, &linesize, fp)) != -1;) {
                if (*line == '\n') {
                        newline = 1;
@@ -98,6 +101,8 @@ char *
 mail_spool(char *file, const char *user)
 {
        struct passwd *pwd;
+
+       tame(TAME_STDIO | TAME_RPATH | TAME_GETPW);
 
        /*
         * We find the mailbox by:
Index: usr.bin/id/id.c
===================================================================
RCS file: /cvs/src/usr.bin/id/id.c,v
retrieving revision 1.23
diff -u -p -u -r1.23 id.c
--- usr.bin/id/id.c     19 May 2015 16:03:19 -0000      1.23
+++ usr.bin/id/id.c     26 May 2015 19:19:45 -0000
@@ -29,6 +29,7 @@
  * SUCH DAMAGE.
  */
 
+#include <sys/tame.h>
 #include <err.h>
 #include <errno.h>
 #include <grp.h>
@@ -104,6 +105,8 @@ main(int argc, char *argv[])
                }
        argc -= optind;
        argv += optind;
+
+       tame(TAME_STDIO | TAME_GETPW);
 
        switch (cflag + Gflag + gflag + pflag + uflag) {
        case 1:
Index: usr.bin/kdump/kdump.c
===================================================================
RCS file: /cvs/src/usr.bin/kdump/kdump.c,v
retrieving revision 1.101
diff -u -p -u -r1.101 kdump.c
--- usr.bin/kdump/kdump.c       18 Apr 2015 18:28:37 -0000      1.101
+++ usr.bin/kdump/kdump.c       25 Jun 2015 01:33:20 -0000
@@ -46,6 +46,7 @@
 #include <sys/vmmeter.h>
 #include <sys/tty.h>
 #include <sys/wait.h>
+#include <sys/tame.h>
 #define _KERNEL
 #include <errno.h>
 #undef _KERNEL
@@ -164,6 +165,8 @@ static void clockname(int);
 static void sockoptlevelname(int);
 static void ktraceopname(int);
 
+static int screenwidth;
+
 int
 main(int argc, char *argv[])
 {
@@ -175,6 +178,16 @@ main(int argc, char *argv[])
 
        def_emul = current = &emulations[0];    /* native */
 
+       if (screenwidth == 0) {
+               struct winsize ws;
+
+               if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
+                   ws.ws_col > 8)
+                       screenwidth = ws.ws_col;
+               else
+                       screenwidth = 80;
+       }
+
        while ((ch = getopt(argc, argv, "e:f:dHlm:nRp:Tt:xX")) != -1)
                switch (ch) {
                case 'e':
@@ -229,6 +242,8 @@ main(int argc, char *argv[])
        if (argc > optind)
                usage();
 
+       tame(TAME_MALLOC | TAME_RPATH);
+
        m = malloc(size = 1025);
        if (m == NULL)
                err(1, NULL);
@@ -1177,19 +1192,9 @@ static void
 showbuf(unsigned char *dp, size_t datalen)
 {
        int i, j;
-       static int screenwidth;
        int col = 0, width, bpl;
        unsigned char visbuf[5], *cp, c;
 
-       if (screenwidth == 0) {
-               struct winsize ws;
-
-               if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
-                   ws.ws_col > 8)
-                       screenwidth = ws.ws_col;
-               else
-                       screenwidth = 80;
-       }
        if (iohex == 1) {
                putchar('\t');
                col = 8;
Index: usr.bin/logger/logger.c
===================================================================
RCS file: /cvs/src/usr.bin/logger/logger.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 logger.c
--- usr.bin/logger/logger.c     18 Apr 2015 18:28:37 -0000      1.14
+++ usr.bin/logger/logger.c     3 Jun 2015 17:36:15 -0000
@@ -30,6 +30,7 @@
  * SUCH DAMAGE.
  */
 
+#include <sys/tame.h>
 #include <errno.h>
 #include <unistd.h>
 #include <limits.h>
@@ -91,6 +92,8 @@ main(int argc, char *argv[])
        /* setup for logging */
        openlog(tag ? tag : getlogin(), logflags, 0);
        (void) fclose(stdout);
+
+       tame(TAME_STDIO);
 
        /* log input line if appropriate */
        if (argc > 0) {
Index: usr.bin/script/script.c
===================================================================
RCS file: /cvs/src/usr.bin/script/script.c,v
retrieving revision 1.26
diff -u -p -u -r1.26 script.c
--- usr.bin/script/script.c     15 Mar 2015 00:41:28 -0000      1.26
+++ usr.bin/script/script.c     3 Jun 2015 01:20:42 -0000
@@ -60,6 +60,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
+#include <sys/tame.h>
 
 #include <errno.h>
 #include <fcntl.h>
@@ -137,11 +138,6 @@ main(int argc, char *argv[])
        rtt.c_lflag &= ~ECHO;
        (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
 
-       bzero(&sa, sizeof sa);
-       sigemptyset(&sa.sa_mask);
-       sa.sa_handler = finish;
-       (void)sigaction(SIGCHLD, &sa, NULL);
-
        sa.sa_handler = handlesigwinch;
        sa.sa_flags = SA_RESTART;
        (void)sigaction(SIGWINCH, &sa, NULL);
@@ -163,6 +159,13 @@ main(int argc, char *argv[])
                        doshell();
        }
 
+       bzero(&sa, sizeof sa);
+       sigemptyset(&sa.sa_mask);
+       sa.sa_handler = finish;
+       (void)sigaction(SIGCHLD, &sa, NULL);
+
+       tame(TAME_STDIO | TAME_IOCTL);
+
        (void)fclose(fscript);
        while (1) {
                if (dead)
@@ -240,6 +243,13 @@ dooutput(void)
        sigemptyset(&sa.sa_mask);
        sa.sa_handler = scriptflush;
        (void)sigaction(SIGALRM, &sa, NULL);
+
+       bzero(&sa, sizeof sa);
+       sigemptyset(&sa.sa_mask);
+       sa.sa_handler = SIG_IGN;
+       (void)sigaction(SIGCHLD, &sa, NULL);
+
+       tame(TAME_STDIO);
 
        value.it_interval.tv_sec = 30;
        value.it_interval.tv_usec = 0;
Index: usr.bin/sed/main.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.21
diff -u -p -u -r1.21 main.c
--- usr.bin/sed/main.c  17 Jul 2015 21:54:26 -0000      1.21
+++ usr.bin/sed/main.c  17 Jul 2015 22:57:24 -0000
@@ -34,6 +34,8 @@
  */
 
 #include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/tame.h>
 #include <sys/stat.h>
 
 #include <ctype.h>
@@ -102,6 +104,8 @@ static void add_compunit(enum e_cut, cha
 static void add_file(char *);
 static int next_files_have_lines(void);
 
+int termwidth = -1;
+
 int
 main(int argc, char *argv[])
 {
@@ -144,6 +148,23 @@ main(int argc, char *argv[])
                }
        argc -= optind;
        argv += optind;
+
+       if (termwidth == -1) {
+               struct winsize win;
+               char *p;
+
+               termwidth = 0;
+               if ((p = getenv("COLUMNS")))
+                       termwidth = strtonum(p, 0, INT_MAX, NULL);
+               if (termwidth == 0 &&
+                   ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
+                   win.ws_col > 0)
+                       termwidth = win.ws_col;
+               if (termwidth == 0)
+                       termwidth = 60;
+       }
+
+       tame(TAME_STDIO | TAME_WPATH | TAME_RPATH | TAME_CPATH);
 
        /* First usage case; script is the first arg */
        if (!eflag && !fflag && *argv) {
Index: usr.bin/sed/process.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/process.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 process.c
--- usr.bin/sed/process.c       17 Jul 2015 20:38:57 -0000      1.24
+++ usr.bin/sed/process.c       17 Jul 2015 21:27:04 -0000
@@ -35,7 +35,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/ioctl.h>
 #include <sys/uio.h>
 
 #include <ctype.h>
@@ -473,25 +472,8 @@ static void
 lputs(char *s)
 {
        int count;
-       const char *escapes;
-       char *p;
-       struct winsize win;
-       static int termwidth = -1;
-
-       if (outfile != stdout)
-               termwidth = 60;
-
-       if (termwidth == -1) {
-               termwidth = 0;
-               if ((p = getenv("COLUMNS")))
-                       termwidth = strtonum(p, 0, INT_MAX, NULL);
-               if (termwidth == 0 &&
-                   ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
-                   win.ws_col > 0)
-                       termwidth = win.ws_col;
-               if (termwidth == 0)
-                       termwidth = 60;
-       }
+       extern int termwidth;
+       char *escapes, *p;
 
        for (count = 0; *s; ++s) { 
                if (count >= termwidth) {
Index: usr.bin/signify/signify.c
===================================================================
RCS file: /cvs/src/usr.bin/signify/signify.c,v
retrieving revision 1.100
diff -u -p -u -r1.100 signify.c
--- usr.bin/signify/signify.c   16 Jan 2015 06:16:12 -0000      1.100
+++ usr.bin/signify/signify.c   15 Jun 2015 00:55:45 -0000
@@ -15,6 +15,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include <sys/stat.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <resolv.h>
Index: usr.bin/uniq/uniq.c
===================================================================
RCS file: /cvs/src/usr.bin/uniq/uniq.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 uniq.c
--- usr.bin/uniq/uniq.c 26 Nov 2013 19:25:39 -0000      1.19
+++ usr.bin/uniq/uniq.c 3 Jun 2015 22:09:03 -0000
@@ -33,6 +33,7 @@
  * SUCH DAMAGE.
  */
 
+#include <sys/tame.h>
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
@@ -61,6 +62,8 @@ main(int argc, char *argv[])
        int ch;
        char *prevline, *thisline;
 
+       tame(TAME_STDIO | TAME_RPATH | TAME_WPATH);
+
        obsolete(argv);
        while ((ch = getopt(argc, argv, "cdf:s:u")) != -1) {
                const char *errstr;
@@ -118,6 +121,8 @@ main(int argc, char *argv[])
        default:
                usage();
        }
+
+       tame(TAME_STDIO);
 
        prevline = malloc(MAXLINELEN);
        thisline = malloc(MAXLINELEN);
Index: usr.bin/w/w.c
===================================================================
RCS file: /cvs/src/usr.bin/w/w.c,v
retrieving revision 1.58
diff -u -p -u -r1.58 w.c
--- usr.bin/w/w.c       15 Mar 2015 00:41:28 -0000      1.58
+++ usr.bin/w/w.c       26 May 2015 19:26:58 -0000
@@ -219,6 +219,20 @@ main(int argc, char *argv[])
        kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(*kp), &nentries);
        if (kp == NULL)
                errx(1, "%s", kvm_geterr(kd));
+
+       if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 &&
+           ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 &&
+           ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) || ws.ws_col == 0)
+               ttywidth = 79;
+       else
+               ttywidth = ws.ws_col - 1;
+       argwidth = ttywidth - WUSED;
+       if (argwidth < 4)
+               argwidth = 8;
+
+#include <sys/tame.h>
+//     tame(TAME_STDIO | TAME_GETPW | TAME_RPATH);
+
        for (i = 0; i < nentries; i++, kp++) {
                if (kp->p_psflags & (PS_EMBRYO | PS_ZOMBIE))
                        continue;
@@ -247,15 +261,6 @@ main(int argc, char *argv[])
                        }
                }
        }
-       if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 &&
-           ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 &&
-           ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) || ws.ws_col == 0)
-               ttywidth = 79;
-       else
-               ttywidth = ws.ws_col - 1;
-       argwidth = ttywidth - WUSED;
-       if (argwidth < 4)
-               argwidth = 8;
        /* sort by idle time */
        if (sortidle && ehead != NULL) {
                struct entry *from = ehead, *save;
Index: usr.bin/wc/wc.c
===================================================================
RCS file: /cvs/src/usr.bin/wc/wc.c,v
retrieving revision 1.17
diff -u -p -u -r1.17 wc.c
--- usr.bin/wc/wc.c     16 Jan 2015 06:40:14 -0000      1.17
+++ usr.bin/wc/wc.c     23 May 2015 18:11:59 -0000
@@ -32,6 +32,7 @@
 #include <sys/param.h> /* MAXBSIZE */
 #include <sys/stat.h>
 #include <sys/file.h>
+#include <sys/tame.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -56,6 +57,8 @@ main(int argc, char *argv[])
        int ch;
 
        setlocale(LC_ALL, "");
+
+       tame(TAME_STDIO | TAME_RPATH);
 
        while ((ch = getopt(argc, argv, "lwchm")) != -1)
                switch(ch) {
Index: usr.bin/whois/whois.c
===================================================================
RCS file: /cvs/src/usr.bin/whois/whois.c,v
retrieving revision 1.47
diff -u -p -u -r1.47 whois.c
--- usr.bin/whois/whois.c       9 Apr 2015 19:29:53 -0000       1.47
+++ usr.bin/whois/whois.c       3 Jun 2015 22:09:48 -0000
@@ -31,6 +31,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -137,6 +138,8 @@ main(int argc, char *argv[])
 
        if (!argc || (country != NULL && host != NULL))
                usage();
+
+       tame(TAME_STDIO | TAME_DNS | TAME_INET);
 
        if (host == NULL && country == NULL && !(flags & WHOIS_QUICK))
                flags |= WHOIS_RECURSE;
Index: usr.sbin/arp/arp.c
===================================================================
RCS file: /cvs/src/usr.sbin/arp/arp.c,v
retrieving revision 1.64
diff -u -p -u -r1.64 arp.c
--- usr.sbin/arp/arp.c  3 Jun 2015 08:10:53 -0000       1.64
+++ usr.sbin/arp/arp.c  3 Jun 2015 18:05:03 -0000
@@ -41,6 +41,7 @@
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 #include <sys/ioctl.h>
+#include <sys/tame.h>
 #include <net/bpf.h>
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -160,8 +161,11 @@ main(int argc, char *argv[])
                func = F_GET;
        rtn = 0;
 
+       getsocket();
+
        switch (func) {
        case F_GET:
+               tame(TAME_STDIO | TAME_DNS | TAME_INET);
                if (aflag && argc == 0)
                        dump();
                else if (!aflag && argc == 1)
@@ -177,6 +181,7 @@ main(int argc, char *argv[])
                rtn = set(argc, argv) ? 1 : 0;
                break;
        case F_DELETE:
+               tame(TAME_STDIO | TAME_DNS | TAME_INET);
                if (aflag && argc == 0)
                        search(0, nuke_entry);
                else if (!aflag && argc == 1)
Index: usr.sbin/authpf/authpf.c
===================================================================
RCS file: /cvs/src/usr.sbin/authpf/authpf.c,v
retrieving revision 1.123
diff -u -p -u -r1.123 authpf.c
--- usr.sbin/authpf/authpf.c    21 Jan 2015 21:50:32 -0000      1.123
+++ usr.sbin/authpf/authpf.c    24 May 2015 01:09:52 -0000
@@ -23,6 +23,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -147,6 +148,8 @@ main(int argc, char *argv[])
                shell = pw->pw_shell;
 
        login_close(lc);
+
+       tame(TAME_STDIO | TAME_WPATH);
 
        if (strcmp(shell, PATH_AUTHPF_SHELL) &&
            strcmp(shell, PATH_AUTHPF_SHELL_NOIP)) {
Index: usr.sbin/bgpd/rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.333
diff -u -p -u -r1.333 rde.c
--- usr.sbin/bgpd/rde.c 16 Jul 2015 17:26:57 -0000      1.333
+++ usr.sbin/bgpd/rde.c 17 Jul 2015 21:15:24 -0000
@@ -20,6 +20,7 @@
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/tame.h>
 
 #include <errno.h>
 #include <ifaddrs.h>
@@ -193,6 +194,8 @@ rde_main(int pipe_m2r[2], int pipe_s2r[2
            setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
            setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
                fatal("can't drop privileges");
+
+       tame(TAME_MALLOC | TAME_UNIX | TAME_CMSG);
 
        signal(SIGTERM, rde_sighdlr);
        signal(SIGINT, rde_sighdlr);
Index: usr.sbin/bgpd/session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.338
diff -u -p -u -r1.338 session.c
--- usr.sbin/bgpd/session.c     9 Feb 2015 11:37:31 -0000       1.338
+++ usr.sbin/bgpd/session.c     27 May 2015 21:04:35 -0000
@@ -17,12 +17,13 @@
  */
 
 #include <sys/types.h>
-
 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/un.h>
+#include <sys/tame.h>
+
 #include <net/if_types.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
@@ -229,6 +230,8 @@ session_main(int pipe_m2s[2], int pipe_s
            setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
            setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
                fatal("can't drop privileges");
+
+       tame(TAME_MALLOC | TAME_INET | TAME_CMSG);
 
        signal(SIGTERM, session_sighdlr);
        signal(SIGINT, session_sighdlr);
Index: usr.sbin/httpd/httpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.c,v
retrieving revision 1.37
diff -u -p -u -r1.37 httpd.c
--- usr.sbin/httpd/httpd.c      3 Jun 2015 02:24:36 -0000       1.37
+++ usr.sbin/httpd/httpd.c      13 Jun 2015 14:56:53 -0000
@@ -23,6 +23,7 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <sys/resource.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -246,6 +247,9 @@ main(int argc, char *argv[])
        proc_init(ps, procs, nitems(procs));
 
        setproctitle("parent");
+
+       tame(TAME_MALLOC | TAME_INET | TAME_CMSG | TAME_RPATH | TAME_WPATH |
+           TAME_PROC | TAME_IOCTL);
 
        event_init();
 
Index: usr.sbin/httpd/logger.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/logger.c,v
retrieving revision 1.12
diff -u -p -u -r1.12 logger.c
--- usr.sbin/httpd/logger.c     11 Apr 2015 14:52:49 -0000      1.12
+++ usr.sbin/httpd/logger.c     13 Jun 2015 14:58:06 -0000
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <sys/uio.h>
+#include <sys/tame.h>
 
 #include <limits.h>
 #include <stdio.h>
@@ -70,6 +71,8 @@ logger_shutdown(void)
 void
 logger_init(struct privsep *ps, struct privsep_proc *p, void *arg)
 {
+       tame(TAME_MALLOC | TAME_CMSG);
+
        if (config_init(ps->ps_env) == -1)
                fatal("failed to initialize configuration");
 
Index: usr.sbin/httpd/server.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server.c,v
retrieving revision 1.70
diff -u -p -u -r1.70 server.c
--- usr.sbin/httpd/server.c     16 Jul 2015 16:29:25 -0000      1.70
+++ usr.sbin/httpd/server.c     17 Jul 2015 21:15:25 -0000
@@ -24,6 +24,7 @@
 #include <sys/socket.h>
 #include <sys/uio.h>
 #include <sys/tree.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <netinet/tcp.h>
@@ -243,6 +244,14 @@ server_init(struct privsep *ps, struct p
 
        /* Unlimited file descriptors (use system limits) */
        socket_rlimit(-1);
+
+       /*
+        * XXX TAME_INET and TAME_UNIX are only needed for fcgi
+        * however if fcgi is used or not can change on config reload
+        * should we re-fork the children and tame again on reload
+        */
+       tame(TAME_MALLOC | TAME_CMSG | TAME_RPATH | TAME_PROC |
+           TAME_INET | TAME_UNIX | TAME_IOCTL);
 
 #if 0
        /* Schedule statistics timer */
Index: usr.sbin/ntpd/ntp.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp.c,v
retrieving revision 1.132
diff -u -p -u -r1.132 ntp.c
--- usr.sbin/ntpd/ntp.c 25 May 2015 14:58:34 -0000      1.132
+++ usr.sbin/ntpd/ntp.c 28 May 2015 06:08:44 -0000
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/stat.h>
+#include <sys/tame.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <paths.h>
@@ -164,6 +165,9 @@ ntp_main(int pipe_prnt[2], int fd_ctl, s
                fatal("can't drop privileges");
 
        endservent();
+
+       /* TAME_DNS for constraint.c */
+       tame(TAME_STDIO | TAME_RW | TAME_INET | TAME_DNS | TAME_PROC);
 
        signal(SIGTERM, ntp_sighdlr);
        signal(SIGINT, ntp_sighdlr);
Index: usr.sbin/ntpd/ntp_dns.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp_dns.c,v
retrieving revision 1.10
diff -u -p -u -r1.10 ntp_dns.c
--- usr.sbin/ntpd/ntp_dns.c     24 Mar 2015 18:25:27 -0000      1.10
+++ usr.sbin/ntpd/ntp_dns.c     28 May 2015 17:29:24 -0000
@@ -19,6 +19,7 @@
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <sys/time.h>
+#include <sys/tame.h>
 
 #include <err.h>
 #include <errno.h>
@@ -89,6 +90,8 @@ ntp_dns(int pipe_ntp[2], struct ntpd_con
        if ((ibuf_dns = malloc(sizeof(struct imsgbuf))) == NULL)
                fatal(NULL);
        imsg_init(ibuf_dns, pipe_ntp[1]);
+
+       tame(TAME_DNS | TAME_RW);
 
        while (quit_dns == 0) {
                pfd[0].fd = ibuf_dns->fd;
Index: usr.sbin/ntpd/ntpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.c,v
retrieving revision 1.93
diff -u -p -u -r1.93 ntpd.c
--- usr.sbin/ntpd/ntpd.c        11 Mar 2015 19:38:48 -0000      1.93
+++ usr.sbin/ntpd/ntpd.c        28 May 2015 17:24:43 -0000
@@ -22,6 +22,7 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <sys/un.h>
+#include <sys/tame.h>
 #include <netinet/in.h>
 #include <errno.h>
 #include <poll.h>
@@ -196,6 +197,9 @@ main(int argc, char *argv[])
        setproctitle("[priv]");
        readfreq();
 
+//     XXX missing: adjtime() to change time
+//     tame(TAME_STDIO | TAME_UNIX | TAME_PROC);
+
        signal(SIGTERM, sighdlr);
        signal(SIGINT, sighdlr);
        signal(SIGHUP, sighdlr);
@@ -564,6 +568,8 @@ ctl_main(int argc, char *argv[])
                errx(1, "ctl socket name too long");
        if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1)
                err(1, "connect: %s", sockname);
+
+       tame(TAME_STDIO);
 
        if ((ibuf_ctl = malloc(sizeof(struct imsgbuf))) == NULL)
                err(1, NULL);
Index: usr.sbin/relayd/ca.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/ca.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 ca.c
--- usr.sbin/relayd/ca.c        2 May 2015 13:15:24 -0000       1.13
+++ usr.sbin/relayd/ca.c        11 Jun 2015 13:59:32 -0000
@@ -19,6 +19,7 @@
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <sys/uio.h>
+#include <sys/tame.h>
 
 #include <unistd.h>
 #include <string.h>
@@ -73,6 +74,8 @@ ca(struct privsep *ps, struct privsep_pr
 void
 ca_init(struct privsep *ps, struct privsep_proc *p, void *arg)
 {
+       tame(TAME_MALLOC | TAME_RW | TAME_CMSG);
+
        if (config_init(ps->ps_env) == -1)
                fatal("failed to initialize configuration");
 
Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.173
diff -u -p -u -r1.173 syslogd.c
--- usr.sbin/syslogd/syslogd.c  16 Jul 2015 23:29:14 -0000      1.173
+++ usr.sbin/syslogd/syslogd.c  17 Jul 2015 21:15:27 -0000
@@ -75,6 +75,7 @@
 #include <sys/un.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <netdb.h>
@@ -584,6 +585,8 @@ main(int argc, char *argv[])
        /* Privilege separation begins here */
        if (priv_init(ConfFile, NoDNS, lockpipe[1], nullfd, argv) < 0)
                errx(1, "unable to privsep");
+
+       tame(TAME_MALLOC | TAME_RPATH | TAME_UNIX | TAME_INET | TAME_CMSG);
 
        /* Process is now unprivileged and inside a chroot */
        event_init();
Index: usr.sbin/tcpdump/privsep.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/privsep.c,v
retrieving revision 1.34
diff -u -p -u -r1.34 privsep.c
--- usr.sbin/tcpdump/privsep.c  14 Jul 2015 20:23:40 -0000      1.34
+++ usr.sbin/tcpdump/privsep.c  14 Jul 2015 20:25:36 -0000
@@ -21,6 +21,7 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <sys/ioctl.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <net/if.h>
@@ -258,6 +259,10 @@ priv_init(int argc, char **argv)
        setproctitle("[priv]");
        close(socks[1]);
 
+       /* rpath for the device
+        * plus: resolv.conf, hosts, services, protocols, ethers, etc etc
+        * Unlikely to need YP?
+        */
        for (;;) {
                if (may_read(socks[0], &cmd, sizeof(int)))
                        break;
@@ -281,6 +286,8 @@ priv_init(int argc, char **argv)
                case PRIV_INIT_DONE:
                        test_state(cmd, STATE_RUN);
                        impl_init_done(socks[0], &bpfd);
+                       tame(TAME_MALLOC | TAME_CMSG | TAME_INET |
+                           TAME_IOCTL | TAME_DNS | TAME_RPATH);
                        break;
                case PRIV_GETHOSTBYADDR:
                        test_state(cmd, STATE_RUN);
Index: usr.sbin/tcpdump/tcpdump.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/tcpdump.c,v
retrieving revision 1.72
diff -u -p -u -r1.72 tcpdump.c
--- usr.sbin/tcpdump/tcpdump.c  14 Jul 2015 20:23:40 -0000      1.72
+++ usr.sbin/tcpdump/tcpdump.c  14 Jul 2015 20:25:20 -0000
@@ -33,6 +33,7 @@
 #include <sys/time.h>
 #include <sys/ioctl.h>
 #include <sys/wait.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 
@@ -490,6 +491,7 @@ main(int argc, char **argv)
        if (tflag > 0)
                thiszone = gmt2local(0);
 
+       tame(TAME_STDIO);
 
        if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {
                (void)fprintf(stderr, "%s: pcap_loop: %s\n",
Index: usr.sbin/traceroute/traceroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/traceroute/traceroute.c,v
retrieving revision 1.140
diff -u -p -u -r1.140 traceroute.c
--- usr.sbin/traceroute/traceroute.c    16 Jul 2015 22:47:46 -0000      1.140
+++ usr.sbin/traceroute/traceroute.c    17 Jul 2015 21:15:27 -0000
@@ -239,6 +239,7 @@
 #include <sys/file.h>
 #include <sys/ioctl.h>
 #include <sys/sysctl.h>
+#include <sys/tame.h>
 
 #include <netinet/in.h>
 #include <netinet/ip.h>
@@ -843,6 +844,11 @@ main(int argc, char *argv[])
        if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
            sizeof(datalen)) < 0)
                err(6, "SO_SNDBUF");
+
+       if (nflag)
+               tame(TAME_STDIO | TAME_INET);
+       else
+               tame(TAME_STDIO | TAME_INET | TAME_DNS);
 
        if (getnameinfo(to, to->sa_len, hbuf,
            sizeof(hbuf), NULL, 0, NI_NUMERICHOST))

Reply via email to