Theo de Raadt <[email protected]> writes: > Back around 1989, Ken Stauffer and I found a kernel security hole in > SunOS (the "open 3" bug) and used it along with TIOCSTI. > > That bug was fixed at least twice: we reported it and it was fixed in > SunOS, then when *BSD code became available I found it was still > unfixed and fixed it myself, and I believe other systems have found it > much later and fixed it themselves. > > However even after that bug was fixed, there's always been the risk > that a program manages to retain tty association beyond it's intended > lifetime, and then it can perform injections with TIOCSTI. > > So I've always wanted to get rid of TIOCSTI. I consider it the most > dangerous tty ioctl. > > In base, the main consumers are csh file completion, and mail ~h > header editing. Anton has fixed those, by writing a new tenex-style > parser and causing those programs run in CBREAK mode instead. > > There are indications that a few ports use TIOCSTI. The list is > pretty small, and I have not reviewed whether the use of TIOCSTI > actually occurs during runtime on OpenBSD: > > x11vnc tcsh ucblogo brltty epic4 trn libsanitizer > jvim2.0r+onew2.2.10-wnn4
> emacs TIOCSTI is only used once in editors/emacs. The return value of ioctl(2) isn't checked. This is in the "suspend-emacs" function, ie what's called when pressing ^Z, can take an optional string to be sent to the parent process. I could spot only one place in emacs-25.2 where this optional string is used, lisp/obsolete/ledit.el, an obsolete mode for Franz Lisp: https://en.wikipedia.org/wiki/Franz_Lisp I don't think we care. > qemu TIOCSTI from /usr/include doesn't seem to be used. There are matches for TARGET_TIOCSTI defines in the linux-user/ directory. > ngspice > > I hope those programs get fixed quickly, because the following diff > will be commited soon to disable TIOCSTI. This diff is in snapshots. > > The proposal is to return EIO at first, and later on see if we can remove > the #define. > > Index: kern_pledge.c > =================================================================== > RCS file: /cvs/src/sys/kern/kern_pledge.c,v > retrieving revision 1.215 > diff -u -p -u -r1.215 kern_pledge.c > --- kern_pledge.c 21 Jun 2017 17:13:20 -0000 1.215 > +++ kern_pledge.c 21 Jun 2017 17:16:15 -0000 > @@ -1273,11 +1273,6 @@ pledge_ioctl(struct proc *p, long com, s > break; > return (0); > #endif /* NPTY > 0 */ > - case TIOCSTI: /* ksh? csh? */ > - if ((p->p_p->ps_pledge & PLEDGE_PROC) && > - fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY)) > - return (0); > - break; > case TIOCSPGRP: > if ((p->p_p->ps_pledge & PLEDGE_PROC) == 0) > break; > Index: tty.c > =================================================================== > RCS file: /cvs/src/sys/kern/tty.c,v > retrieving revision 1.133 > diff -u -p -u -r1.133 tty.c > --- tty.c 21 Jan 2017 05:42:03 -0000 1.133 > +++ tty.c 19 Jun 2017 21:12:57 -0000 > @@ -733,7 +733,6 @@ ttioctl(struct tty *tp, u_long cmd, cadd > case TIOCSETAW: > case TIOCSPGRP: > case TIOCSTAT: > - case TIOCSTI: > case TIOCSWINSZ: > while (isbackground(pr, tp) && > (pr->ps_flags & PS_PPWAIT) == 0 && > @@ -962,11 +961,7 @@ ttioctl(struct tty *tp, u_long cmd, cadd > splx(s); > break; > case TIOCSTI: /* simulate terminal input */ > - if (p->p_ucred->cr_uid && (flag & FREAD) == 0) > - return (EPERM); > - if (p->p_ucred->cr_uid && !isctty(pr, tp)) > - return (EACCES); > - (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp); > + return (EIO); > break; > case TIOCSTOP: /* stop output, like ^S */ > s = spltty(); > -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
