summaryrefslogtreecommitdiff
path: root/sys/kern/tty_pty.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2008-04-10 19:55:42 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2008-04-10 19:55:42 +0000
commit08d3274a40ea6a5c7cd2bc6691ce5e0c9195f293 (patch)
tree0633404d708dccddda9e29e376a36cfc8bb4e679 /sys/kern/tty_pty.c
parent099be31700bff9c5d8ed7b9edf15da1a38267b09 (diff)
scrub local stack-based buffers in the tty subsystem. tested by a lot of
developers. if you notice tty weirdnesses in the next few months, talk to me
Diffstat (limited to 'sys/kern/tty_pty.c')
-rw-r--r--sys/kern/tty_pty.c69
1 files changed, 44 insertions, 25 deletions
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index a158a80b18a..0671ba7fe1b 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty_pty.c,v 1.35 2007/09/07 15:00:20 art Exp $ */
+/* $OpenBSD: tty_pty.c,v 1.36 2008/04/10 19:55:41 deraadt Exp $ */
/* $NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $ */
/*
@@ -456,7 +456,7 @@ ptcread(dev_t dev, struct uio *uio, int flag)
struct pt_softc *pti = pt_softc[minor(dev)];
struct tty *tp = pti->pt_tty;
char buf[BUFSIZ];
- int error = 0, cc;
+ int error = 0, cc, bufcc = 0;
/*
* We want to block until the slave
@@ -500,7 +500,10 @@ ptcread(dev_t dev, struct uio *uio, int flag)
if (pti->pt_flags & (PF_PKT|PF_UCNTL))
error = ureadc(0, uio);
while (uio->uio_resid > 0 && error == 0) {
- cc = q_to_b(&tp->t_outq, buf, min(uio->uio_resid, BUFSIZ));
+ cc = min(uio->uio_resid, BUFSIZ);
+ cc = q_to_b(&tp->t_outq, buf, cc);
+ if (cc > bufcc)
+ bufcc = cc;
if (cc <= 0)
break;
error = uiomove(buf, cc, uio);
@@ -512,6 +515,8 @@ ptcread(dev_t dev, struct uio *uio, int flag)
}
selwakeup(&tp->t_wsel);
}
+ if (bufcc)
+ bzero(buf, bufcc);
return (error);
}
@@ -522,8 +527,8 @@ ptcwrite(dev_t dev, struct uio *uio, int flag)
struct pt_softc *pti = pt_softc[minor(dev)];
struct tty *tp = pti->pt_tty;
u_char *cp = NULL;
- int cc = 0;
- u_char locbuf[BUFSIZ];
+ int cc = 0, bufcc = 0;
+ u_char buf[BUFSIZ];
int cnt = 0;
int error = 0;
@@ -537,13 +542,17 @@ again:
if (cc == 0) {
cc = min(uio->uio_resid, BUFSIZ);
cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
- cp = locbuf;
+ if (cc > bufcc)
+ bufcc = cc;
+ cp = buf;
error = uiomove(cp, cc, uio);
if (error)
- return (error);
+ goto done;
/* check again for safety */
- if ((tp->t_state&TS_ISOPEN) == 0)
- return (EIO);
+ if ((tp->t_state&TS_ISOPEN) == 0) {
+ error = EIO;
+ goto done;
+ }
}
if (cc)
(void) b_to_q((char *)cp, cc, &tp->t_canq);
@@ -552,19 +561,24 @@ again:
(void) putc(0, &tp->t_canq);
ttwakeup(tp);
wakeup(&tp->t_canq);
- return (0);
+ goto done;
}
while (uio->uio_resid > 0) {
if (cc == 0) {
cc = min(uio->uio_resid, BUFSIZ);
- cp = locbuf;
+ if (cc > bufcc)
+ bufcc = cc;
+ cp = buf;
error = uiomove(cp, cc, uio);
if (error)
- return (error);
+ goto done;
/* check again for safety */
- if ((tp->t_state&TS_ISOPEN) == 0)
- return (EIO);
+ if ((tp->t_state&TS_ISOPEN) == 0) {
+ error = EIO;
+ goto done;
+ }
}
+ bufcc = cc;
while (cc > 0) {
if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
(tp->t_canq.c_cc > 0 || !ISSET(tp->t_lflag, ICANON))) {
@@ -577,29 +591,34 @@ again:
}
cc = 0;
}
- return (0);
+ goto done;
block:
/*
* Come here to wait for slave to open, for space
* in outq, or space in rawq.
*/
- if ((tp->t_state&TS_CARR_ON) == 0)
- return (EIO);
+ if ((tp->t_state&TS_CARR_ON) == 0) {
+ error = EIO;
+ goto done;
+ }
if (flag & IO_NDELAY) {
/* adjust for data copied in but not written */
uio->uio_resid += cc;
if (cnt == 0)
- return (EWOULDBLOCK);
- return (0);
+ error = EWOULDBLOCK;
+ goto done;
}
error = tsleep(&tp->t_rawq.c_cf, TTOPRI | PCATCH,
ttyout, 0);
- if (error) {
- /* adjust for data copied in but not written */
- uio->uio_resid += cc;
- return (error);
- }
- goto again;
+ if (error == 0)
+ goto again;
+
+ /* adjust for data copied in but not written */
+ uio->uio_resid += cc;
+done:
+ if (bufcc)
+ bzero(buf, bufcc);
+ return (error);
}
int