DragonFlyBSD Kernel Audit
DF-0612 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netproto/802_11/wlan/ieee80211_tdma.c b/sys/netproto/802_11/wlan/ieee80211_tdma.c
--- a/sys/netproto/802_11/wlan/ieee80211_tdma.c
+++ b/sys/netproto/802_11/wlan/ieee80211_tdma.c
@@ -651,6 +651,28 @@
 		    (const struct ieee80211_tdma_param *)ie;
 		struct ieee80211_tdma_state *ts = vap->iv_tdma;
 		/*
+		 * Validate the vendor IE before touching any field.
+		 * Unlike the beacon-during-RUN handler
+		 * (tdma_process_params), this join path historically
+		 * performed no length or slot validation, so a crafted
+		 * beacon with an out-of-range tdma_slot drove setbit()
+		 * past the 1-byte ts->tdma_inuse[] array and corrupted
+		 * adjacent TDMA state on the heap.  The guards mirror
+		 * ieee80211_tdma.c:536 and :555.
+		 */
+		if (ie[1] < sizeof(*tdma) - 2) {
+			IEEE80211_DISCARD_IE(vap,
+			    IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA,
+			    NULL, "tdma", "too short, len %u", ie[1]);
+			return;
+		}
+		if (tdma->tdma_slot >= TDMA_MAXSLOTS) {
+			IEEE80211_DISCARD_IE(vap,
+			    IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA,
+			    NULL, "tdma", "invalid slot %u", tdma->tdma_slot);
+			return;
+		}
+		/*
 		 * Adopt TDMA configuration when joining an
 		 * existing network.
 		 */