From 65e925d16fbbdfd36efba3644f208330e423b16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Mon, 11 Nov 1996 22:21:03 +0000 Subject: [PATCH] 1. Avoid a race in scclose(). tty.c has kludges so that the race is actually harmless. 2. Fixed code to match comment in scintr(). 3. Don't allow even root to take control of the machine when securelevel > 0. I've secured the accesses to PSL_IOPL in all drivers and asked pst to review it, but he seems to be busy. Write access to /dev/kmem and other critival devices currently leaks across raisings of securelevel via open fd's, so there may as well be a similar leak for PSL_IOPL. 4. (Most important.) Don't corrupt memory beyond the screen buffers if the cursor happens to be off the 80x25 screen when syscons starts. 5. Fix console cursor update (not perfect yet). Submitted by: bruce ~ --- sys/dev/syscons/syscons.c | 20 +++++++++++++++----- sys/i386/isa/syscons.c | 20 +++++++++++++++----- sys/isa/syscons.c | 20 +++++++++++++++----- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index fefed148698..ef95daa3297 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.184 1996/11/10 16:44:09 nate Exp $ + * $Id: syscons.c,v 1.185 1996/11/11 22:01:56 nate Exp $ */ #include "sc.h" @@ -541,8 +541,10 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) scp->smode.mode = VT_AUTO; #endif } + spltty(); (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); + spl0(); return(0); } @@ -590,7 +592,7 @@ scintr(int unit) cur_tty = VIRTUAL_TTY(get_scr_num()); if (!(cur_tty->t_state & TS_ISOPEN)) if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN)) - return; + continue; switch (c & 0xff00) { case 0x0000: /* normal key */ @@ -601,7 +603,7 @@ scintr(int unit) while (len-- > 0) (*linesw[cur_tty->t_line].l_rint)(*cp++ & 0xFF, cur_tty); } - break; + break; case MKEY: /* meta is active, prepend ESC */ (*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty); (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty); @@ -1046,6 +1048,8 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) error = suser(p->p_ucred, &p->p_acflag); if (error != 0) return error; + if (securelevel > 0) + return EPERM; fp = (struct trapframe *)p->p_md.md_regs; fp->tf_eflags |= PSL_IOPL; return 0; @@ -1386,7 +1390,7 @@ sccnputc(dev_t dev, int c) scp->term = kernel_console; current_default = &kernel_default; - if (!(scp->status & UNKNOWN_MODE)) + if (scp == cur_console && !(scp->status & UNKNOWN_MODE)) remove_cursor_image(scp); buf[0] = c; ansi_put(scp, buf, 1); @@ -2297,6 +2301,13 @@ scinit(void) outb(crtc_addr, 15); hw_cursor |= inb(crtc_addr + 1); + /* + * Validate cursor location. It may be off the screen. Then we must + * not use it for the initial buffer offset. + */ + if (hw_cursor >= ROW * COL) + hw_cursor = (ROW - 1) * COL; + /* move hardware cursor out of the way */ outb(crtc_addr, 14); outb(crtc_addr + 1, 0xff); @@ -2485,7 +2496,6 @@ scgetc(u_int flags) static u_int chr = 0; next_code: - /* check if there is anything in the keyboard buffer */ if (inb(KB_STAT) & KB_BUF_FULL) { DELAY(25); scancode = inb(KB_DATA); diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c index fefed148698..ef95daa3297 100644 --- a/sys/i386/isa/syscons.c +++ b/sys/i386/isa/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.184 1996/11/10 16:44:09 nate Exp $ + * $Id: syscons.c,v 1.185 1996/11/11 22:01:56 nate Exp $ */ #include "sc.h" @@ -541,8 +541,10 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) scp->smode.mode = VT_AUTO; #endif } + spltty(); (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); + spl0(); return(0); } @@ -590,7 +592,7 @@ scintr(int unit) cur_tty = VIRTUAL_TTY(get_scr_num()); if (!(cur_tty->t_state & TS_ISOPEN)) if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN)) - return; + continue; switch (c & 0xff00) { case 0x0000: /* normal key */ @@ -601,7 +603,7 @@ scintr(int unit) while (len-- > 0) (*linesw[cur_tty->t_line].l_rint)(*cp++ & 0xFF, cur_tty); } - break; + break; case MKEY: /* meta is active, prepend ESC */ (*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty); (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty); @@ -1046,6 +1048,8 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) error = suser(p->p_ucred, &p->p_acflag); if (error != 0) return error; + if (securelevel > 0) + return EPERM; fp = (struct trapframe *)p->p_md.md_regs; fp->tf_eflags |= PSL_IOPL; return 0; @@ -1386,7 +1390,7 @@ sccnputc(dev_t dev, int c) scp->term = kernel_console; current_default = &kernel_default; - if (!(scp->status & UNKNOWN_MODE)) + if (scp == cur_console && !(scp->status & UNKNOWN_MODE)) remove_cursor_image(scp); buf[0] = c; ansi_put(scp, buf, 1); @@ -2297,6 +2301,13 @@ scinit(void) outb(crtc_addr, 15); hw_cursor |= inb(crtc_addr + 1); + /* + * Validate cursor location. It may be off the screen. Then we must + * not use it for the initial buffer offset. + */ + if (hw_cursor >= ROW * COL) + hw_cursor = (ROW - 1) * COL; + /* move hardware cursor out of the way */ outb(crtc_addr, 14); outb(crtc_addr + 1, 0xff); @@ -2485,7 +2496,6 @@ scgetc(u_int flags) static u_int chr = 0; next_code: - /* check if there is anything in the keyboard buffer */ if (inb(KB_STAT) & KB_BUF_FULL) { DELAY(25); scancode = inb(KB_DATA); diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c index fefed148698..ef95daa3297 100644 --- a/sys/isa/syscons.c +++ b/sys/isa/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.184 1996/11/10 16:44:09 nate Exp $ + * $Id: syscons.c,v 1.185 1996/11/11 22:01:56 nate Exp $ */ #include "sc.h" @@ -541,8 +541,10 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) scp->smode.mode = VT_AUTO; #endif } + spltty(); (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); + spl0(); return(0); } @@ -590,7 +592,7 @@ scintr(int unit) cur_tty = VIRTUAL_TTY(get_scr_num()); if (!(cur_tty->t_state & TS_ISOPEN)) if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN)) - return; + continue; switch (c & 0xff00) { case 0x0000: /* normal key */ @@ -601,7 +603,7 @@ scintr(int unit) while (len-- > 0) (*linesw[cur_tty->t_line].l_rint)(*cp++ & 0xFF, cur_tty); } - break; + break; case MKEY: /* meta is active, prepend ESC */ (*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty); (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty); @@ -1046,6 +1048,8 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) error = suser(p->p_ucred, &p->p_acflag); if (error != 0) return error; + if (securelevel > 0) + return EPERM; fp = (struct trapframe *)p->p_md.md_regs; fp->tf_eflags |= PSL_IOPL; return 0; @@ -1386,7 +1390,7 @@ sccnputc(dev_t dev, int c) scp->term = kernel_console; current_default = &kernel_default; - if (!(scp->status & UNKNOWN_MODE)) + if (scp == cur_console && !(scp->status & UNKNOWN_MODE)) remove_cursor_image(scp); buf[0] = c; ansi_put(scp, buf, 1); @@ -2297,6 +2301,13 @@ scinit(void) outb(crtc_addr, 15); hw_cursor |= inb(crtc_addr + 1); + /* + * Validate cursor location. It may be off the screen. Then we must + * not use it for the initial buffer offset. + */ + if (hw_cursor >= ROW * COL) + hw_cursor = (ROW - 1) * COL; + /* move hardware cursor out of the way */ outb(crtc_addr, 14); outb(crtc_addr + 1, 0xff); @@ -2485,7 +2496,6 @@ scgetc(u_int flags) static u_int chr = 0; next_code: - /* check if there is anything in the keyboard buffer */ if (inb(KB_STAT) & KB_BUF_FULL) { DELAY(25); scancode = inb(KB_DATA);