- Fix mbuf/node leakage in drivers' raw_xmit().
- For ural(4): o Fix node leakage in ural_start(), if ural_tx_mgt() fails. o Fix mbuf leakage in ural_tx_{mgt,data}(), if usbd_transfer() fails. o In ural_tx_{mgt,data}(), set ural_tx_data.{m,ni} to NULL, if usbd_transfer() fails, so they will not be freed again in ural_stop(). Approved by: sam (mentor)
This commit is contained in:
parent
f1f73e5718
commit
b03cfe2396
@ -5838,6 +5838,7 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
||||
struct ath_buf *bf;
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
|
||||
ieee80211_free_node(ni);
|
||||
m_freem(m);
|
||||
return ENETDOWN;
|
||||
}
|
||||
@ -5854,6 +5855,7 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
||||
__func__);
|
||||
sc->sc_stats.ast_tx_qstop++;
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
ieee80211_free_node(ni);
|
||||
m_freem(m);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
@ -1716,8 +1716,10 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
|
||||
|
||||
rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
|
||||
/* XXX validate */
|
||||
if (rate == 0)
|
||||
if (rate == 0) {
|
||||
m_freem(m0);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0,
|
||||
segs, &nsegs, 0);
|
||||
@ -2782,11 +2784,15 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
||||
/* prevent management frames from being sent if we're not ready */
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
RAL_UNLOCK(sc);
|
||||
m_freem(m);
|
||||
ieee80211_free_node(ni);
|
||||
return ENETDOWN;
|
||||
}
|
||||
if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
RAL_UNLOCK(sc);
|
||||
m_freem(m);
|
||||
ieee80211_free_node(ni);
|
||||
return ENOBUFS; /* XXX */
|
||||
}
|
||||
|
||||
|
@ -1222,8 +1222,12 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
ural_txeof);
|
||||
|
||||
error = usbd_transfer(data->xfer);
|
||||
if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS)
|
||||
if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
|
||||
m_freem(m0);
|
||||
data->m = NULL;
|
||||
data->ni = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
sc->tx_queued++;
|
||||
|
||||
@ -1246,8 +1250,10 @@ ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
||||
|
||||
rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
|
||||
/* XXX validate */
|
||||
if (rate == 0)
|
||||
if (rate == 0) {
|
||||
m_freem(m0);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (bpf_peers_present(sc->sc_drvbpf)) {
|
||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||
@ -1379,8 +1385,12 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
ural_txeof);
|
||||
|
||||
error = usbd_transfer(data->xfer);
|
||||
if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS)
|
||||
if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
|
||||
m_freem(m0);
|
||||
data->m = NULL;
|
||||
data->ni = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
sc->tx_queued++;
|
||||
|
||||
@ -1411,9 +1421,10 @@ ural_start(struct ifnet *ifp)
|
||||
if (bpf_peers_present(ic->ic_rawbpf))
|
||||
bpf_mtap(ic->ic_rawbpf, m0);
|
||||
|
||||
if (ural_tx_mgt(sc, m0, ni) != 0)
|
||||
if (ural_tx_mgt(sc, m0, ni) != 0) {
|
||||
ieee80211_free_node(ni);
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ic->ic_state != IEEE80211_S_RUN)
|
||||
break;
|
||||
@ -2310,10 +2321,15 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
||||
struct ural_softc *sc = ifp->if_softc;
|
||||
|
||||
/* prevent management frames from being sent if we're not ready */
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
m_freem(m);
|
||||
ieee80211_free_node(ni);
|
||||
return ENETDOWN;
|
||||
}
|
||||
if (sc->tx_queued >= RAL_TX_LIST_COUNT) {
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
m_freem(m);
|
||||
ieee80211_free_node(ni);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
|
@ -1093,9 +1093,6 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
|
||||
|
||||
k = ieee80211_crypto_encap(ic, ni, m0);
|
||||
if (k == NULL) {
|
||||
if (ni != NULL)
|
||||
ieee80211_free_node(ni);
|
||||
m_freem(m0);
|
||||
rc = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -1116,16 +1113,20 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
|
||||
frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
|
||||
if (IFF_DUMPPKTS(ifp))
|
||||
wi_dump_pkt(&frmhdr, NULL, -1);
|
||||
if (ni != NULL)
|
||||
ieee80211_free_node(ni);
|
||||
rc = wi_start_tx(ifp, &frmhdr, m0);
|
||||
if (rc)
|
||||
if (wi_start_tx(ifp, &frmhdr, m0) < 0) {
|
||||
m0 = NULL;
|
||||
rc = EIO;
|
||||
goto out;
|
||||
}
|
||||
m0 = NULL;
|
||||
|
||||
sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
|
||||
out:
|
||||
WI_UNLOCK(sc);
|
||||
|
||||
if (m0 != NULL)
|
||||
m_freem(m0);
|
||||
ieee80211_free_node(ni);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user