diff options
author | sos <sos@FreeBSD.org> | 1996-11-11 22:21:03 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 1996-11-11 22:21:03 +0000 |
commit | ee50e1f023bc4e62b2b0478134bc4e3b900cfa53 (patch) | |
tree | e4ea16900c9c0a1c1f2847450587b61006877fd4 /sys | |
parent | 114b1b8eb1cac117c4869d03ba414609aaf7d401 (diff) | |
download | FreeBSD-src-ee50e1f023bc4e62b2b0478134bc4e3b900cfa53.zip FreeBSD-src-ee50e1f023bc4e62b2b0478134bc4e3b900cfa53.tar.gz |
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
~
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/syscons/syscons.c | 20 | ||||
-rw-r--r-- | sys/i386/isa/syscons.c | 20 | ||||
-rw-r--r-- | 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 fefed14..ef95daa 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 fefed14..ef95daa 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 fefed14..ef95daa 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); |