Add new "tty" request, which allows TIOCGETA, TIOCGPGRP, TIOCGWINSZ,
authorderaadt <deraadt@openbsd.org>
Tue, 6 Oct 2015 15:21:26 +0000 (15:21 +0000)
committerderaadt <deraadt@openbsd.org>
Tue, 6 Oct 2015 15:21:26 +0000 (15:21 +0000)
TIOCSBRK, TIOCCDTR, TIOCSETA, TIOCSETAW, and TIOCSETAF on tty
vnodes. This helps programs which call tcsetattr(), tcgetattr(), or
readpassphrase().  Especially the latter - tame's goal is to satisfy
the libc requirements of security-sensitive programs.

Remove TIOCSETAF from the basic "ioctl" request, because it is a "set"
option. "ioctl" is slowly turning into a "request information, cannot
set options" package.

Split the "cmsg" request into "sendfd" and "recvfd".  Non-SCM_RIGHTS
messages are currently flowing through freely and we'll need to think
about that.  This split lets us more strictly describe what our many
fd-passing programs will do.

sys/kern/kern_tame.c
sys/sys/param.h
sys/sys/tame.h

index 0c36fb6..73f83a5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_tame.c,v 1.61 2015/10/06 14:55:41 claudio Exp $  */
+/*     $OpenBSD: kern_tame.c,v 1.62 2015/10/06 15:21:26 deraadt Exp $  */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -142,7 +142,7 @@ const u_int tame_syscalls[SYS_MAXSYSCALL] = {
        [SYS_setresuid] = TAME_PROC,
 
        /* FIONREAD/FIONBIO, plus further checks in tame_ioctl_check() */
-       [SYS_ioctl] = TAME_RW | TAME_IOCTL,
+       [SYS_ioctl] = TAME_RW | TAME_IOCTL | TAME_TTY,
 
        [SYS_getentropy] = TAME_MALLOC,
        [SYS_madvise] = TAME_MALLOC,
@@ -226,10 +226,13 @@ static const struct {
        { "tmppath",            TAME_SELF | TAME_RW | TAME_TMPPATH },
        { "inet",               TAME_SELF | TAME_RW | TAME_INET },
        { "unix",               TAME_SELF | TAME_RW | TAME_UNIX },
-       { "cmsg",               TAME_SELF | TAME_RW | TAME_UNIX | TAME_CMSG },
        { "dns",                TAME_SELF | TAME_MALLOC | TAME_DNSPATH },
-       { "ioctl",              TAME_IOCTL },
        { "getpw",              TAME_SELF | TAME_MALLOC | TAME_RW | TAME_GETPW },
+/*X*/  { "cmsg",               TAME_UNIX | TAME_INET | TAME_SENDFD | TAME_RECVFD },
+       { "sendfd",             TAME_RW | TAME_SENDFD },
+       { "recvfd",             TAME_RW | TAME_RECVFD },
+       { "ioctl",              TAME_IOCTL },
+       { "tty",                TAME_TTY },
        { "proc",               TAME_PROC },
        { "cpath",              TAME_CPATH },
        { "abort",              TAME_ABORT },
@@ -671,7 +674,7 @@ tame_aftersyscall(struct proc *p, int code, int error)
  * 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
+ * If TAME_RECVFD is set SCM_RIGHTS is also allowed in 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
@@ -707,8 +710,8 @@ tame_cmsg_recv(struct proc *p, struct mbuf *control)
        if (cmsg == NULL)
                return (0);
 
-       if ((p->p_p->ps_tame & TAME_CMSG) == 0)
-               return tame_fail(p, EPERM, TAME_CMSG);
+       if ((p->p_p->ps_tame & TAME_RECVFD) == 0)
+               return tame_fail(p, EPERM, TAME_RECVFD);
 
        /* In OpenBSD, a CMSG only contains one SCM_RIGHTS.  Check it. */
        fdp = (int *)CMSG_DATA(cmsg);
@@ -720,7 +723,7 @@ tame_cmsg_recv(struct proc *p, struct mbuf *control)
                fd = *fdp++;
                fp = fd_getfile(p->p_fd, fd);
                if (fp == NULL)
-                       return tame_fail(p, EBADF, TAME_CMSG);
+                       return tame_fail(p, EBADF, TAME_RECVFD);
 
                /* Only allow passing of sockets, pipes, and pure files */
                switch (fp->f_type) {
@@ -735,7 +738,7 @@ tame_cmsg_recv(struct proc *p, struct mbuf *control)
                default:
                        break;
                }
-               return tame_fail(p, EPERM, TAME_CMSG);
+               return tame_fail(p, EPERM, TAME_RECVFD);
        }
        return (0);
 }
@@ -757,8 +760,8 @@ tame_cmsg_send(struct proc *p, struct mbuf *control)
        if ((p->p_p->ps_flags & PS_TAMED) == 0)
                return (0);
 
-       if ((p->p_p->ps_tame & TAME_CMSG) == 0)
-               return tame_fail(p, EPERM, TAME_CMSG);
+       if ((p->p_p->ps_tame & TAME_SENDFD) == 0)
+               return tame_fail(p, EPERM, TAME_SENDFD);
 
        /* Scan the cmsg */
        cmsg = mtod(control, struct cmsghdr *);
@@ -778,7 +781,7 @@ tame_cmsg_send(struct proc *p, struct mbuf *control)
                fd = *fdp++;
                fp = fd_getfile(p->p_fd, fd);
                if (fp == NULL)
-                       return tame_fail(p, EBADF, TAME_CMSG);
+                       return tame_fail(p, EBADF, TAME_SENDFD);
 
                /* Only allow passing of sockets, pipes, and pure files */
                switch (fp->f_type) {
@@ -794,7 +797,7 @@ tame_cmsg_send(struct proc *p, struct mbuf *control)
                        break;
                }
                /* Not allowed to send a bad fd type */
-               return tame_fail(p, EPERM, TAME_CMSG);
+               return tame_fail(p, EPERM, TAME_SENDFD);
        }
        return (0);
 }
@@ -996,9 +999,6 @@ tame_ioctl_check(struct proc *p, long com, void *v)
                case TIOCGETA:
                case TIOCGPGRP:
                case TIOCGWINSZ:        /* various programs */
-               case TIOCSTI:           /* ksh? csh? */
-               case TIOCSBRK:          /* cu */
-               case TIOCCDTR:          /* cu */
                        if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
                                return (0);
                        break;
@@ -1007,10 +1007,6 @@ tame_ioctl_check(struct proc *p, long com, void *v)
                            fp->f_ops->fo_ioctl == vn_ioctl)
                                return (0);
                        break;
-               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... */
@@ -1026,8 +1022,26 @@ tame_ioctl_check(struct proc *p, long com, void *v)
                }
        }
 
-       printf("tame: ioctl %lx\n", com);
-       return (EPERM);
+       if ((p->p_p->ps_tame & TAME_TTY)) {
+               switch (com) {
+               case TIOCGETA:
+               case TIOCGPGRP:
+               case TIOCGWINSZ:        /* various programs */
+#if notyet
+               case TIOCSTI:           /* ksh? csh? */
+#endif
+               case TIOCSBRK:          /* cu */
+               case TIOCCDTR:          /* cu */
+               case TIOCSETA:          /* cu, ... */
+               case TIOCSETAW:         /* cu, ... */
+               case TIOCSETAF:         /* tcsetattr TCSAFLUSH, script */
+                       if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
+                               return (0);
+                       break;
+               }
+       }
+
+       return tame_fail(p, EPERM, TAME_IOCTL);
 }
 
 int
index 68c3ef4..8d7a7c3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: param.h,v 1.118 2015/07/02 01:34:00 dlg Exp $ */
+/*     $OpenBSD: param.h,v 1.119 2015/10/06 15:21:26 deraadt Exp $     */
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -38,8 +38,6 @@
 #define        _SYS_PARAM_H_
 
 #define        BSD     199306          /* System version (year & month). */
-#define BSD4_3 1
-#define BSD4_4 1
 
 #define OpenBSD        201510          /* OpenBSD version (year & month). */
 #define OpenBSD5_8 1           /* OpenBSD 5.8 */
index c553729..8cfbd03 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tame.h,v 1.9 2015/10/06 14:55:41 claudio Exp $        */
+/*     $OpenBSD: tame.h,v 1.10 2015/10/06 15:21:26 deraadt Exp $       */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
 #define TAME_TMPPATH   0x00000040      /* for mk*temp() */
 #define TAME_INET      0x00000080      /* AF_INET/AF_INET6 sockets */
 #define TAME_UNIX      0x00000100      /* AF_UNIX sockets */
-#define TAME_CMSG      0x00000200      /* AF_UNIX CMSG fd passing */
-#define TAME_IOCTL     0x00000400      /* scary */
-#define TAME_GETPW     0x00000800      /* enough to enable YP */
+// reuse, old CMSG     0x00000200
+#define TAME_IOCTL     0x00000400      /* Select ioctl */
+#define TAME_GETPW     0x00000800      /* YP enables if ypbind.lock */
 #define TAME_PROC      0x00001000      /* fork, waitpid, etc */
 #define TAME_CPATH     0x00002000      /* allow creat, mkdir, path creations */
 #define TAME_FATTR     0x00004000      /* allow explicit file st_* mods */
 #define TAME_PROTEXEC  0x00008000      /* allow use of PROT_EXEC */
+#define TAME_TTY       0x00010000      /* tty setting */
+#define TAME_SENDFD    0x00020000      /* AF_UNIX CMSG fd sending */
+#define TAME_RECVFD    0x00040000      /* AF_UNIX CMSG fd receiving */
 
 #define TAME_ABORT     0x08000000      /* SIGABRT instead of SIGKILL */