From: deraadt Date: Tue, 6 Oct 2015 15:21:26 +0000 (+0000) Subject: Add new "tty" request, which allows TIOCGETA, TIOCGPGRP, TIOCGWINSZ, X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=8ef3921e4063d6630371d99f16513f4938c246de;p=openbsd Add new "tty" request, which allows TIOCGETA, TIOCGPGRP, TIOCGWINSZ, 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. --- diff --git a/sys/kern/kern_tame.c b/sys/kern/kern_tame.c index 0c36fb6293c..73f83a5c9fa 100644 --- a/sys/kern/kern_tame.c +++ b/sys/kern/kern_tame.c @@ -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 @@ -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 diff --git a/sys/sys/param.h b/sys/sys/param.h index 68c3ef4c117..8d7a7c32c2d 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -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 */ diff --git a/sys/sys/tame.h b/sys/sys/tame.h index c553729ce02..8cfbd036b6a 100644 --- a/sys/sys/tame.h +++ b/sys/sys/tame.h @@ -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 @@ -33,13 +33,16 @@ #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 */