⬢ DragonFlyBSD Kernel Audit
DF-3971 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ral/rt2560.c
+++ b/sys/dev/netif/ral/rt2560.c
@@ -819,8 +819,10 @@
 			}
 			ieee80211_ref_node(ni);
 			error = rt2560_tx_bcn(sc, m, ni);
-			if (error != 0)
+			if (error != 0) {
+				ieee80211_free_node(ni);
 				return error;
+			}
 		}
 
 		/* turn association led on */
@@ -1516,6 +1518,21 @@
 	desc = &sc->bcnq.desc[sc->bcnq.cur];
 	data = &sc->bcnq.data[sc->bcnq.cur];
 
+	/*
+	 * Free any beacon left over in this slot from a previous RUN
+	 * state (re-association without an intervening stop); otherwise
+	 * the old mbuf and node reference are silently leaked.
+	 */
+	if (data->m != NULL && data->m != m0) {
+		bus_dmamap_unload(sc->bcnq.data_dmat, data->map);
+		m_freem(data->m);
+		data->m = NULL;
+	}
+	if (data->ni != NULL && data->ni != ni) {
+		ieee80211_free_node(data->ni);
+		data->ni = NULL;
+	}
+
 	/* XXX maybe a separate beacon rate? */
 	rate = vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)].mgmtrate;