I'm not sure if this makes sense, since tame(2) was designed to operate
on processes after they have already been initialized, and this would
set the allowed operations before initializing the process.

It's a fairly simple change to get the basics working as shown here,
but it's currently not very useful as more complex programs generally
can't start even if given all current tame(2) permissions.

I mostly did this to get more experience working in the kernel, not
because I think it is a good idea, but I welcome feedback all the same.

First the manual, followed by the code, then the kernel and tame(2)
manpage diff.

Thanks,
Jeremy

   TAME(1) General Commands Manual                                    TAME(1) 

   NAME

   tame - restrict system operations for process

   SYNOPSIS

   tame [-aCcdghIiRSptuw] utility [argument ...]                              

   DESCRIPTION

   tame restricts system operations using the tame(2) system call, then
   executes the utility with the given arguments. If the utility attempts to
   perform an operation which was not permitted, it will be killed by the
   system with SIGKILL.
   By default, tame restricts almost all system operations for the executed
   process, allowing only the execution of processes (TAME_EXEC), use of
   stdio (TAME_STDIO), and reading the file system (TAME_RPATH). All flags
   with the exception of -h, -R, and -S allow additional system operations.
   The options that allow additional system operations are as follows, with
   the tame(2) option that they enable:

   -a
           TAME_ABORT

   -C
           TAME_CMSG

   -c
           TAME_CPATH

   -d
           TAME_DNS

   -g
           TAME_GETPW

   -I
           TAME_IOCTL

   -i
           TAME_INET

   -p
           TAME_PROC

   -t
           TAME_TMPPATH

   -u
           TAME_UNIX

   -w
           TAME_WPATH

   The following options restrict system operations that are allowed by
   default:

   -R
           TAME_RW

   -r
           TAME_RPATH

   The -h option displays the usage.
   If the -r option is used, utilty must be the full path to the utility,
   tame will no longer search the PATH to find it, as it will have already
   restricted the permissions that would allow that.

   EXIT STATUS

   The tame utility exits with one of the following values:

   125
           An error occurred.

   126
           The utility was not found or could not be invoked.

   Otherwise, the exit status of tame shall be that of utility.

   EXAMPLES

   Only allow overwriting files that already exist, do not allow creating new
   files:

     $ tame -w cp from to

   SEE ALSO

   tame(2)

   HISTORY

   The tame() system call appeared in OpenBSD 5.8.

   $Mdocdate: $                         OpenBSD 5.8                       

tame.c:

/*      $OpenBSD: $     */

/*
 * Copyright (c) 2015 Jeremy Evans <jer...@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/tame.h>
#include <unistd.h>

__dead void usage(int);

int
main(int argc, char *argv[])
{
        char ch;
        char *file;
        /* TAME_RPATH needed to find process to execute
         * TAME_EXEC needed to execute the process
         * TAME_STDIO needed by almost all processes
         */
        int tame_flags = TAME_RPATH | TAME_STDIO | TAME_EXEC;

        while ((ch = getopt(argc, argv, "aCcdghIiRrptuw")) != -1)
                switch (ch) {
                case 'a':
                        tame_flags |= TAME_ABORT;
                        break;
                case 'C':
                        tame_flags |= TAME_CMSG;
                        break;
                case 'c':
                        tame_flags |= TAME_CPATH;
                        break;
                case 'd':
                        tame_flags |= TAME_DNS;
                        break;
                case 'g':
                        tame_flags |= TAME_GETPW;
                        break;
                case 'I':
                        tame_flags |= TAME_IOCTL;
                        break;
                case 'i':
                        tame_flags |= TAME_INET;
                        break;
                case 'p':
                        tame_flags |= TAME_PROC;
                        break;
                case 'R':
                        tame_flags &= ~TAME_RW;
                        break;
                case 'r':
                        tame_flags &= ~TAME_RPATH;
                        break;
                case 't':
                        tame_flags |= TAME_TMPPATH;
                        break;
                case 'u':
                        tame_flags |= TAME_UNIX;
                        break;
                case 'w':
                        tame_flags |= TAME_WPATH;
                        break;
                case 'h':
                        usage(0);
                        break;
                default:
                        usage(125);
                }

        argv += optind;
        argc -= optind;

        if(tame(tame_flags) == -1)
                err(125, NULL);

        if(tame_flags & TAME_RPATH) {
                if(execvp(argv[0], argv) == -1)
                        err(126, NULL);
        } else {
                if(execv(argv[0], argv) == -1)
                        err(126, NULL);
        }

}

void
usage(int status)
{
        fprintf(stderr, "usage: tame [-aCcdghIipRrtuw] cmd\n");
        exit(status);
}

kernel/manpage diff:

Index: sys/kern/kern_tame.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_tame.c,v
retrieving revision 1.3
diff -u -p -u -p -r1.3 kern_tame.c
--- sys/kern/kern_tame.c        20 Jul 2015 02:43:26 -0000      1.3
+++ sys/kern/kern_tame.c        20 Jul 2015 06:30:12 -0000
@@ -135,6 +135,8 @@ const u_int tame_syscalls[SYS_MAXSYSCALL
        [SYS_setresgid] = _TM_PROC,
        [SYS_setresuid] = _TM_PROC,
 
+       [SYS_execve] = _TM_EXEC,
+
        [SYS_ioctl] = _TM_IOCTL,                /* very limited subset */
 
        [SYS_getentropy] = _TM_MALLOC,
@@ -564,6 +566,12 @@ tame_sysctl_check(struct proc *p, int na
                return (0);
        if (namelen == 2 &&
            name[0] == CTL_KERN && name[1] == KERN_HOSTNAME)
+               return (0);
+
+       /* getpagesize() */
+       if ((p->p_p->ps_tame & _TM_EXEC) &&
+           namelen == 2 &&
+           name[0] == CTL_HW && name[1] == HW_PAGESIZE)
                return (0);
 
        printf("tame: pid %d %s sysctl %d: %d %d %d %d %d %d\n",
Index: sys/sys/tame.h
===================================================================
RCS file: /cvs/src/sys/sys/tame.h,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 tame.h
--- sys/sys/tame.h      19 Jul 2015 02:35:35 -0000      1.1
+++ sys/sys/tame.h      20 Jul 2015 05:43:06 -0000
@@ -36,6 +36,7 @@
 #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_EXEC       0x00004000      /* exec new processes */
 
 #define _TM_ABORT      0x08000000      /* SIGABRT instea of SIGKILL */
 
@@ -59,6 +60,7 @@
 #define TAME_GETPW     (TAME_STDIO | _TM_GETPW)
 #define TAME_PROC      (_TM_PROC)
 #define TAME_CPATH     (_TM_CPATH)
+#define TAME_EXEC      (_TM_EXEC)
 #define TAME_ABORT     (_TM_ABORT)
 
 #ifdef _KERNEL
Index: lib/libc/sys/tame.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/tame.2,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 tame.2
--- lib/libc/sys/tame.2 19 Jul 2015 17:08:35 -0000      1.9
+++ lib/libc/sys/tame.2 20 Jul 2015 07:11:57 -0000
@@ -166,6 +166,10 @@ a few system calls become able to allow 
 .Xr recvfrom 2 ,
 .Xr socket 2 ,
 .Xr connect 2 .
+.It Ar TAME_EXEC
+Allows the execution of processes via the
+.Xr execve 2
+function.
 .It Ar TAME_GETPW
 This allows read-only opening of files in
 .Pa /etc

Reply via email to