diff options
author | ache <ache@FreeBSD.org> | 1995-04-02 04:21:09 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1995-04-02 04:21:09 +0000 |
commit | 6f677cd55ffde3b5321cf399a1a3813321bb0914 (patch) | |
tree | c1fba52874005955bcb30dd7ba4eeb79b34aa6c8 /sys/dev/sio | |
parent | 6aac130fa405b94d53b2c70d0466f5d0546fb9c0 (diff) | |
download | FreeBSD-src-6f677cd55ffde3b5321cf399a1a3813321bb0914.zip FreeBSD-src-6f677cd55ffde3b5321cf399a1a3813321bb0914.tar.gz |
Fix error:
old type (stty) ioctls can easily bypass locking bits.
It involves manual conversion from old ioctls to new ones,
large piece of code duplicated from tty_compat.c
Diffstat (limited to 'sys/dev/sio')
-rw-r--r-- | sys/dev/sio/sio.c | 90 |
1 files changed, 83 insertions, 7 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index 7b67e4c..2908442 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.83 1995/04/01 23:56:08 ache Exp $ + * $Id: sio.c,v 1.84 1995/04/02 01:47:06 ache Exp $ */ #include "sio.h" @@ -1249,13 +1249,88 @@ sioioctl(dev, cmd, data, flag, p) int mcr; int msr; int mynor; - int s; + int s, tiocset; int tiocm_xxx; struct tty *tp; + struct termios term; mynor = minor(dev); com = com_addr(MINOR_TO_UNIT(mynor)); iobase = com->iobase; + + tp = com->tp; +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + if (cmd == TIOCSETP || cmd == TIOCSETN) { +#define MAX_SPEED 17 + register struct sgttyb *sg = (struct sgttyb *)data; + int speed; + extern int compatspcodes[]; + extern void ttcompatsetflags __P((struct tty *tp, struct termios *t)); + + term = tp->t_termios; + if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0) + return (EINVAL); + else + term.c_ispeed = compatspcodes[speed]; + if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0) + return (EINVAL); + else + term.c_ospeed = compatspcodes[speed]; + term.c_cc[VERASE] = sg->sg_erase; + term.c_cc[VKILL] = sg->sg_kill; + tp->t_flags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff); + ttcompatsetflags(tp, &term); + cmd = (cmd == TIOCSETP ? TIOCSETAF : TIOCSETA); + } else if (cmd == TIOCLBIS || cmd == TIOCLBIC || cmd == TIOCLSET) { + extern int ttcompatgetflags __P((struct tty *tp)); + extern void ttcompatsetlflags __P((struct tty *tp, struct termios *t)); + + term = tp->t_termios; + if (cmd == TIOCLSET) + tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; + else { + tp->t_flags = + (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); + if (cmd == TIOCLBIS) + tp->t_flags |= *(int *)data<<16; + else + tp->t_flags &= ~(*(int *)data<<16); + } + ttcompatsetlflags(tp, &term); + cmd = TIOCSETA; + } else if (cmd == TIOCSETC) { + struct tchars *tc = (struct tchars *)data; + register cc_t *cc; + + term = tp->t_termios; + cc = term.c_cc; + cc[VINTR] = tc->t_intrc; + cc[VQUIT] = tc->t_quitc; + cc[VSTART] = tc->t_startc; + cc[VSTOP] = tc->t_stopc; + cc[VEOF] = tc->t_eofc; + cc[VEOL] = tc->t_brkc; + if (tc->t_brkc == -1) + cc[VEOL2] = _POSIX_VDISABLE; + cmd = TIOCSETA; + } else if (cmd == TIOCSLTC) { + struct ltchars *ltc = (struct ltchars *)data; + register cc_t *cc; + + term = tp->t_termios; + cc = term.c_cc; + cc[VSUSP] = ltc->t_suspc; + cc[VDSUSP] = ltc->t_dsuspc; + cc[VREPRINT] = ltc->t_rprntc; + cc[VDISCARD] = ltc->t_flushc; + cc[VWERASE] = ltc->t_werasc; + cc[VLNEXT] = ltc->t_lnextc; + cmd = TIOCSETA; + } else +#endif /* 43 or SunOS */ + if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) + term = *(struct termios *)data; + if (mynor & CONTROL_MASK) { struct termios *ct; @@ -1274,7 +1349,7 @@ sioioctl(dev, cmd, data, flag, p) error = suser(p->p_ucred, &p->p_acflag); if (error != 0) return (error); - *ct = *(struct termios *)data; + *ct = term; return (0); case TIOCGETA: *(struct termios *)data = *ct; @@ -1317,10 +1392,10 @@ sioioctl(dev, cmd, data, flag, p) return (ENOTTY); } } - tp = com->tp; + tiocset = 0; if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) { int cc; - struct termios *dt = (struct termios *)data; + struct termios *dt = &term; struct termios *lt = mynor & CALLOUT_MASK ? &com->lt_out : &com->lt_in; @@ -1339,12 +1414,13 @@ sioioctl(dev, cmd, data, flag, p) dt->c_ispeed = tp->t_ispeed; if (lt->c_ospeed != 0) dt->c_ospeed = tp->t_ospeed; + tiocset = 1; } - error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, tiocset ? (caddr_t) &term : data, flag, p); if (error >= 0) return (error); s = spltty(); - error = ttioctl(tp, cmd, data, flag); + error = ttioctl(tp, cmd, tiocset ? (caddr_t) &term : data, flag); set_bypass(tp, &(tp->t_termios)); if (error >= 0) { splx(s); |