diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-09-28 18:28:38 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-09-28 18:28:38 +0200 |
commit | 36db1295be07b790f381e0157df7731767a25dc0 (patch) | |
tree | 36ed8784c163b9ab5469a4ccac197d6181e08737 | |
parent | a494cc74ad646540fa5b3a994e94f20d7652f62e (diff) |
pc/pc64: fix ps2mouse memory corruption race
there was a memory corruption bug caused by us enabling the
ps2mouseputc() handler *before* initializing packetsize.
once we enabled the handler, mouse interrupts could come
in and advance the packet buffer index (nb) beyond the
buffer boundaries.
as ps2mouseputc() only checked for ++nb == packetsize, once
nb was advanced beyond the packetsize, it would continue writing
beyond the buffer and corrupt memory with each mouse packet byte.
solution is to initialize packetsize *before* enabling the
handler, and also do a >= check in ps2mouseputc() in case the
packetsize gets changed to a smaller value at runtime.
-rw-r--r-- | sys/src/9/pc/devkbd.c | 3 | ||||
-rw-r--r-- | sys/src/9/pc/mouse.c | 9 |
2 files changed, 6 insertions, 6 deletions
diff --git a/sys/src/9/pc/devkbd.c b/sys/src/9/pc/devkbd.c index db8e477e4..f951f8b52 100644 --- a/sys/src/9/pc/devkbd.c +++ b/sys/src/9/pc/devkbd.c @@ -187,7 +187,7 @@ i8042auxcmd(int cmd) iunlock(&i8042lock); if(c != 0xFA){ - print("i8042: %2.2ux returned to the %2.2ux command\n", c, cmd); + print("i8042: %2.2ux returned to the %2.2ux command (pc=%#p)\n", c, cmd, getcallerpc(&cmd)); return -1; } return 0; @@ -303,6 +303,7 @@ i8042auxenable(void (*putc)(int, int)) print(err); outb(Cmd, 0xA8); /* auxiliary device enable */ if(outready() < 0){ + print(err); iunlock(&i8042lock); return; } diff --git a/sys/src/9/pc/mouse.c b/sys/src/9/pc/mouse.c index 0519e5e76..9d69095f9 100644 --- a/sys/src/9/pc/mouse.c +++ b/sys/src/9/pc/mouse.c @@ -113,7 +113,7 @@ ps2mouseputc(int c, int shift) } msg[nb] = c; - if(++nb == packetsize){ + if(++nb >= packetsize){ nb = 0; if(msg[0] & 0x10) msg[1] |= 0xFF00; @@ -152,7 +152,6 @@ ps2mouseputc(int c, int shift) dy = -msg[2]; mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks)); } - return; } /* @@ -164,12 +163,12 @@ ps2mouse(void) if(mousetype == MousePS2) return; - i8042auxenable(ps2mouseputc); - i8042auxcmd(0xEA); /* set stream mode */ - mousetype = MousePS2; packetsize = 3; mousehwaccel = 0; + + i8042auxenable(ps2mouseputc); + i8042auxcmd(0xEA); /* set stream mode */ } /* |