DragonFlyBSD Kernel Audit
DF-1076 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/bus/smbus/ichsmb/ichsmb.c b/sys/bus/smbus/ichsmb/ichsmb.c
index 0000000..1111111 100644
@@ -570,10 +570,23 @@
 				}
 			} else {
 
-				/* First interrupt, get the count also */
+				/* First interrupt, get the count also.
+				 *
+				 * The count byte is supplied by the SMBus/I2C slave and is
+				 * therefore attacker-controlled (a malicious or spec-violating
+				 * peripheral can return any value 0..255; the SMBus 32-byte
+				 * limit does not apply in I2C pass-through mode per
+				 * ICH_HOSTC_I2C_EN).  Clamp it to the size of block_data so
+				 * the indexed store below cannot overflow into the adjacent
+				 * struct lock mutex / softc state.  DF-1076.
+				 */
 				if (sc->block_index == 0) {
 					sc->block_count = bus_read_1(
 					    sc->io_res, ICH_D0);
+					if (sc->block_count >
+					    (int)sizeof(sc->block_data))
+						sc->block_count =
+						    sizeof(sc->block_data);
 				}
 
 				/* Get next byte, if any */