Date: Wed, 5 Mar 2014 18:39:27 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r262795 - head/sys/dev/usb/wlan Message-ID: <201403051839.s25IdRlT040941@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403051839.s25IdRlT040941>