⬢ DragonFlyBSD Kernel Audit
DF-5254 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/u4b/wlan/if_urtwn.c
+++ b/sys/bus/u4b/wlan/if_urtwn.c
@@ -837,8 +837,12 @@
 	struct urtwn_softc *sc = ic->ic_softc;
 	struct urtwn_vap *uvp = URTWN_VAP(vap);
 
-	if (uvp->bcn_mbuf != NULL)
+	/* Serialize against urtwn_update_beacon()/urtwn_tx_beacon(). */
+	if (uvp->bcn_mbuf != NULL) {
+		URTWN_LOCK(sc);
 		m_freem(uvp->bcn_mbuf);
+		URTWN_UNLOCK(sc);
+	}
 	if (vap->iv_opmode == IEEE80211_M_IBSS)
 		ieee80211_draintask(ic, &uvp->tsf_task_adhoc);
 	if (URTWN_CHIP_HAS_RATECTL(sc))
@@ -2203,15 +2207,17 @@
 			return;
 		}
 	}
-	URTWN_UNLOCK(sc);
 
 	if (item == IEEE80211_BEACON_TIM)
 		mcast = 1;	/* XXX */
 
 	setbit(bo->bo_flags, item);
+	/*
+	 * Keep sc_mtx held: uvp->bcn_mbuf must not be freed/replaced by a
+	 * concurrent urtwn_setup_beacon() (newstate drops the com lock)
+	 * or urtwn_vap_delete() while we write into it.
+	 */
 	ieee80211_beacon_update(ni, uvp->bcn_mbuf, mcast);
-
-	URTWN_LOCK(sc);
 	urtwn_tx_beacon(sc, uvp);
 	URTWN_UNLOCK(sc);
 }