Author: hselasky
Date: Wed Mar 12 08:26:49 2014
New Revision: 263074
URL: http://svnweb.freebsd.org/changeset/base/263074

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

Modified:
  stable/9/sys/dev/usb/wlan/if_run.c   (contents, props changed)
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/usb/wlan/if_run.c
==============================================================================
--- stable/9/sys/dev/usb/wlan/if_run.c  Wed Mar 12 08:25:25 2014        
(r263073)
+++ stable/9/sys/dev/usb/wlan/if_run.c  Wed Mar 12 08:26:49 2014        
(r263074)
@@ -2507,9 +2507,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
@@ -2522,9 +2520,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);
@@ -2604,6 +2603,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 */
@@ -2732,7 +2736,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);
 }
 
 /*
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to