DragonFlyBSD Kernel Audit
DF-1131 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/netif/bwn/bwn/if_bwn.c b/sys/dev/netif/bwn/bwn/if_bwn.c
--- a/sys/dev/netif/bwn/bwn/if_bwn.c
+++ b/sys/dev/netif/bwn/bwn/if_bwn.c
@@ -5483,7 +5483,14 @@
 		    BUS_DMASYNC_PREWRITE);
 		return;
 	}
-	if (len > dr->dr_rx_bufsize) {
+	/* The RX mbuf cluster is MCLBYTES (2048) but dr_rx_bufsize is
+	 * IEEE80211_MAX_LEN (2312); a device-reported frame_len in
+	 * (MCLBYTES - dr_frameoffset, dr_rx_bufsize] passes the existing
+	 * check yet makes m_len = len + dr_frameoffset exceed the cluster,
+	 * causing a heap OOB read when the frame is processed.  Drop frames
+	 * that cannot fit in the actual cluster. */
+	if (len > dr->dr_rx_bufsize ||
+	    (u_int)len + dr->dr_frameoffset > MCLBYTES) {
 		tmp = len;
 		while (1) {
 			dr->getdesc(dr, *slot, &desc, &meta);