⬢ DragonFlyBSD Kernel Audit
DF-4611 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c
index 6206653..e97c374 100644
--- a/sys/dev/sound/pci/neomagic.c
+++ b/sys/dev/sound/pci/neomagic.c
@@ -582,6 +582,23 @@ nm_init(struct sc_info *sc)
 		}
 	}
 
+	/*
+	 * Sanity-check the (possibly card-provided) top-of-buffer value:
+	 * everything below must still cover the 0x1400 reduction, the
+	 * coefficient staging area, both ring buffers and the AC97 buffer.
+	 * A defective/hostile card returning a tiny buftop would otherwise
+	 * make cbuf/rbuf/pbuf/acbuf wrap far below the mapping and every
+	 * subsequent nm_wrbuf()/nmchan buffer access lands at a wild offset.
+	 */
+#define NM_BUFTOP_MIN							\
+	(0x1400 + NM_MAX_COEFFICIENT + (2 * NM_BUFFSIZE) +		\
+	(NM_TOTAL_COEFF_COUNT * 4))
+	if (sc->buftop < NM_BUFTOP_MIN) {
+		device_printf(sc->dev,
+		    "implausible buffer top 0x%08x\n", sc->buftop);
+		return -1;
+	}
+
 	sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT;
 	sc->rbuf = sc->cbuf - NM_BUFFSIZE;
 	sc->pbuf = sc->rbuf - NM_BUFFSIZE;