DragonFlyBSD Kernel Audit
DF-1239 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/netif/iwi/if_iwi.c b/sys/dev/netif/iwi/if_iwi.c
index 0f1606cc..dcfff9da 100644
--- a/sys/dev/netif/iwi/if_iwi.c
+++ b/sys/dev/netif/iwi/if_iwi.c
@@ -1246,11 +1246,16 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
 	IWI_LOCK_DECL;
 
 	framelen = le16toh(frame->len);
-	if (framelen < IEEE80211_MIN_LEN || framelen > MCLBYTES) {
+	if (framelen < IEEE80211_MIN_LEN ||
+	    framelen > MCLBYTES - sizeof(struct iwi_hdr) - sizeof(struct iwi_frame)) {
 		/*
-		 * XXX >MCLBYTES is bogus as it means the h/w dma'd
-		 *     out of bounds; need to figure out how to limit
-		 *     frame size in the firmware
+		 * The mbuf cluster (MCLBYTES) holds the iwi_hdr(4) +
+		 * iwi_frame(24) prefix followed by the frame payload.  The
+		 * DMA map is loaded with only MCLBYTES, so a framelen above
+		 * MCLBYTES - sizeof(iwi_hdr) - sizeof(iwi_frame) (=2020)
+		 * would describe data past the DMA-mapped region, exposing
+		 * uninitialized kernel heap to ieee80211_input.  The original
+		 * >MCLBYTES bound was too loose by up to 28 bytes.
 		 */
 		/* XXX stat */
 		DPRINTFN(1,