⬢ DragonFlyBSD Kernel Audit
DF-3429 / fix.diff
← back to finding ↓ download raw
--- a/sys/netproto/802_11/wlan/ieee80211_node.c
+++ b/sys/netproto/802_11/wlan/ieee80211_node.c
@@ -2233,6 +2233,7 @@ ieee80211_node_timeout(void *arg)
 void
 ieee80211_node_timeout(void *arg)
 {
 	struct ieee80211com *ic = arg;
+	struct mbuf *m;
 
 	/*
 	 * Defer timeout processing if a channel switch is pending.
@@ -2251,7 +2252,16 @@ ieee80211_node_timeout(void *arg)
 	 */
 	if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) {
 		ieee80211_scan_timeout(ic);
 		ieee80211_timeout_stations(ic);
-		ieee80211_ageq_age(&ic->ic_stageq, IEEE80211_INACT_WAIT);
+		/*
+		 * DF-3429: ieee80211_ageq_age() REMOVES expired frames
+		 * from the stage queue and returns them as an
+		 * m_nextpkt-joined list for the caller to reclaim.
+		 * Dropping the return value leaks every expired DWDS
+		 * discovery frame (mbuf + cluster) staged by
+		 * ieee80211_dwds_discover().
+		 */
+		m = ieee80211_ageq_age(&ic->ic_stageq, IEEE80211_INACT_WAIT);
+		if (m != NULL)
+			ieee80211_ageq_mfree(m);
 
 		IEEE80211_LOCK(ic);
 		ieee80211_erp_timeout(ic);