DragonFlyBSD Kernel Audit
DF-1287 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/netif/bwn/siba/siba_core.c b/sys/dev/netif/bwn/siba/siba_core.c
--- a/sys/dev/netif/bwn/siba/siba_core.c
+++ b/sys/dev/netif/bwn/siba/siba_core.c
@@ -1405,7 +1405,25 @@
 		siba_sprom_r123(sprom, buf);
 	} else if (siba->siba_chipid == 0x4321) {
 		sprom->rev = 4;
-		siba_sprom_r45(sprom, buf);
+		/*
+		 * rev 4/5/8 parsers index SPROM words beyond
+		 * SIBA_SPROMSIZE_R123.  Make sure the buffer we
+		 * actually hold is large enough before dispatching
+		 * to one of them, otherwise they read past the
+		 * allocation.  This can happen when a R123-sized
+		 * image passes CRC (above) but its rev byte claims
+		 * a later revision.
+		 */
+		if (siba->siba_spromsize < SIBA_SPROMSIZE_R4) {
+			device_printf(siba->siba_dev,
+			    "SPROM rev %d requires %d words but only %d "
+			    "read; falling back to rev 1\n", sprom->rev,
+			    SIBA_SPROMSIZE_R4, siba->siba_spromsize);
+			sprom->rev = 1;
+			siba_sprom_r123(sprom, buf);
+		} else {
+			siba_sprom_r45(sprom, buf);
+		}
 	} else {
 		switch (sprom->rev) {
 		case 1:
@@ -1415,10 +1433,30 @@
 			break;
 		case 4:
 		case 5:
-			siba_sprom_r45(sprom, buf);
+			if (siba->siba_spromsize < SIBA_SPROMSIZE_R4) {
+				device_printf(siba->siba_dev,
+				    "SPROM rev %d requires %d words but only "
+				    "%d read; falling back to rev 1\n",
+				    sprom->rev, SIBA_SPROMSIZE_R4,
+				    siba->siba_spromsize);
+				sprom->rev = 1;
+				siba_sprom_r123(sprom, buf);
+			} else {
+				siba_sprom_r45(sprom, buf);
+			}
 			break;
 		case 8:
-			siba_sprom_r8(sprom, buf);
+			if (siba->siba_spromsize < SIBA_SPROMSIZE_R4) {
+				device_printf(siba->siba_dev,
+				    "SPROM rev %d requires %d words but only "
+				    "%d read; falling back to rev 1\n",
+				    sprom->rev, SIBA_SPROMSIZE_R4,
+				    siba->siba_spromsize);
+				sprom->rev = 1;
+				siba_sprom_r123(sprom, buf);
+			} else {
+				siba_sprom_r8(sprom, buf);
+			}
 			break;
 		default:
 			device_printf(siba->siba_dev,