Date: Mon, 20 Jun 2016 22:39:32 +0000 (UTC) From: Andriy Voskoboinyk <avos@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r302034 - head/sys/dev/urtwn Message-ID: <201606202239.u5KMdWaa042731@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avos Date: Mon Jun 20 22:39:32 2016 New Revision: 302034 URL: https://svnweb.freebsd.org/changeset/base/302034 Log: urtwn: fix panic on device detach. Remove frames from active/pending Tx queues and free related node references when vap is destroyed to prevent various use-after-free scenarios. Reported and tested by: Aleksander Alekseev <afiskon@devzen.ru> PR: 208632 Approved by: re (gjb) Modified: head/sys/dev/urtwn/if_urtwn.c Modified: head/sys/dev/urtwn/if_urtwn.c ============================================================================== --- head/sys/dev/urtwn/if_urtwn.c Mon Jun 20 22:05:59 2016 (r302033) +++ head/sys/dev/urtwn/if_urtwn.c Mon Jun 20 22:39:32 2016 (r302034) @@ -208,6 +208,10 @@ static struct ieee80211vap *urtwn_vap_cr const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void urtwn_vap_delete(struct ieee80211vap *); +static void urtwn_vap_clear_tx(struct urtwn_softc *, + struct ieee80211vap *); +static void urtwn_vap_clear_tx_queue(struct urtwn_softc *, + urtwn_datahead *, struct ieee80211vap *); static struct mbuf * urtwn_rx_copy_to_mbuf(struct urtwn_softc *, struct r92c_rx_stat *, int); static struct mbuf * urtwn_report_intr(struct usb_xfer *, @@ -824,8 +828,16 @@ urtwn_vap_delete(struct ieee80211vap *va struct urtwn_softc *sc = ic->ic_softc; struct urtwn_vap *uvp = URTWN_VAP(vap); + /* Guarantee that nothing will go through this vap. */ + ieee80211_new_state(vap, IEEE80211_S_INIT, -1); + ieee80211_draintask(ic, &vap->iv_nstate_task); + + URTWN_LOCK(sc); if (uvp->bcn_mbuf != NULL) m_freem(uvp->bcn_mbuf); + /* Cancel any unfinished Tx. */ + urtwn_vap_clear_tx(sc, vap); + URTWN_UNLOCK(sc); if (vap->iv_opmode == IEEE80211_M_IBSS) ieee80211_draintask(ic, &uvp->tsf_task_adhoc); if (URTWN_CHIP_HAS_RATECTL(sc)) @@ -834,6 +846,41 @@ urtwn_vap_delete(struct ieee80211vap *va free(uvp, M_80211_VAP); } +static void +urtwn_vap_clear_tx(struct urtwn_softc *sc, struct ieee80211vap *vap) +{ + + URTWN_ASSERT_LOCKED(sc); + + urtwn_vap_clear_tx_queue(sc, &sc->sc_tx_active, vap); + urtwn_vap_clear_tx_queue(sc, &sc->sc_tx_pending, vap); +} + +static void +urtwn_vap_clear_tx_queue(struct urtwn_softc *sc, urtwn_datahead *head, + struct ieee80211vap *vap) +{ + struct urtwn_data *dp, *tmp; + + STAILQ_FOREACH_SAFE(dp, head, next, tmp) { + if (dp->ni != NULL) { + if (dp->ni->ni_vap == vap) { + ieee80211_free_node(dp->ni); + dp->ni = NULL; + + if (dp->m != NULL) { + m_freem(dp->m); + dp->m = NULL; + } + + STAILQ_REMOVE(head, dp, urtwn_data, next); + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, dp, + next); + } + } + } +} + static struct mbuf * urtwn_rx_copy_to_mbuf(struct urtwn_softc *sc, struct r92c_rx_stat *stat, int totlen)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606202239.u5KMdWaa042731>