shithub: riscv

Download patch

ref: 36db1295be07b790f381e0157df7731767a25dc0
parent: a494cc74ad646540fa5b3a994e94f20d7652f62e
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Sep 28 14:28:38 EDT 2014

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.

--- a/sys/src/9/pc/devkbd.c
+++ b/sys/src/9/pc/devkbd.c
@@ -187,7 +187,7 @@
 	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 @@
 		print(err);
 	outb(Cmd, 0xA8);			/* auxiliary device enable */
 	if(outready() < 0){
+		print(err);
 		iunlock(&i8042lock);
 		return;
 	}
--- a/sys/src/9/pc/mouse.c
+++ b/sys/src/9/pc/mouse.c
@@ -113,7 +113,7 @@
 	}
 
 	msg[nb] = c;
-	if(++nb == packetsize){
+	if(++nb >= packetsize){
 		nb = 0;
 		if(msg[0] & 0x10)
 			msg[1] |= 0xFF00;
@@ -152,7 +152,6 @@
 		dy = -msg[2];
 		mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks));
 	}
-	return;
 }
 
 /*
@@ -164,12 +163,12 @@
 	if(mousetype == MousePS2)
 		return;
 
-	i8042auxenable(ps2mouseputc);
-	i8042auxcmd(0xEA);	/* set stream mode */
-
 	mousetype = MousePS2;
 	packetsize = 3;
 	mousehwaccel = 0;
+
+	i8042auxenable(ps2mouseputc);
+	i8042auxcmd(0xEA);	/* set stream mode */
 }
 
 /*