svn commit: r262795 - head/sys/dev/usb/wlan

Hans Petter Selasky hselasky at FreeBSD.org
Wed Mar 5 18:39:28 UTC 2014


Author: hselasky
Date: Wed Mar  5 18:39:27 2014
New Revision: 262795
URL: http://svnweb.freebsd.org/changeset/base/262795

Log:
  - Temporary fix for race in RUN driver which can
  cause freed memory to be accessed.
  - Properly lock callout_reset()'s.
  
  MFC after:	1 week

Modified:
  head/sys/dev/usb/wlan/if_run.c

Modified: head/sys/dev/usb/wlan/if_run.c
==============================================================================
--- head/sys/dev/usb/wlan/if_run.c	Wed Mar  5 17:23:38 2014	(r262794)
+++ head/sys/dev/usb/wlan/if_run.c	Wed Mar  5 18:39:27 2014	(r262795)
@@ -2508,9 +2508,7 @@ run_ratectl_cb(void *arg, int pending)
 	if (vap == NULL)
 		return;
 
-	if (sc->rvp_cnt <= 1 && vap->iv_opmode == IEEE80211_M_STA)
-		run_iter_func(sc, vap->iv_bss);
-	else {
+	if (sc->rvp_cnt > 1 || vap->iv_opmode != IEEE80211_M_STA) {
 		/*
 		 * run_reset_livelock() doesn't do anything with AMRR,
 		 * but Ralink wants us to call it every 1 sec. So, we
@@ -2523,9 +2521,10 @@ run_ratectl_cb(void *arg, int pending)
 		/* just in case, there are some stats to drain */
 		run_drain_fifo(sc);
 		RUN_UNLOCK(sc);
-		ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, sc);
 	}
 
+	ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, sc);
+
 	RUN_LOCK(sc);
 	if(sc->ratectl_run != RUN_RATECTL_OFF)
 		usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc);
@@ -2605,6 +2604,11 @@ run_iter_func(void *arg, struct ieee8021
 
 	RUN_LOCK(sc);
 
+	/* Check for special case */
+	if (sc->rvp_cnt <= 1 && vap->iv_opmode == IEEE80211_M_STA &&
+	    ni != vap->iv_bss)
+		goto fail;
+
 	if (sc->rvp_cnt <= 1 && (vap->iv_opmode == IEEE80211_M_IBSS ||
 	    vap->iv_opmode == IEEE80211_M_STA)) {
 		/* read statistic counters (clear on read) and update AMRR state */
@@ -2733,7 +2737,10 @@ run_newassoc(struct ieee80211_node *ni, 
 	rn->mgt_ridx = ridx;
 	DPRINTF("rate=%d, mgmt_ridx=%d\n", rate, rn->mgt_ridx);
 
-	usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc);
+	RUN_LOCK(sc);
+	if(sc->ratectl_run != RUN_RATECTL_OFF)
+		usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc);
+	RUN_UNLOCK(sc);
 }
 
 /*


More information about the svn-src-head mailing list