- 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;
|
struct ath_buf *bf;
|
||||||
|
|
||||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
|
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
|
||||||
|
ieee80211_free_node(ni);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return ENETDOWN;
|
return ENETDOWN;
|
||||||
}
|
}
|
||||||
@ -5854,6 +5855,7 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
__func__);
|
__func__);
|
||||||
sc->sc_stats.ast_tx_qstop++;
|
sc->sc_stats.ast_tx_qstop++;
|
||||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||||
|
ieee80211_free_node(ni);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
|
@ -1716,8 +1716,10 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
|
|
||||||
rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
|
rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
|
||||||
/* XXX validate */
|
/* XXX validate */
|
||||||
if (rate == 0)
|
if (rate == 0) {
|
||||||
|
m_freem(m0);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0,
|
error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0,
|
||||||
segs, &nsegs, 0);
|
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 */
|
/* 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)) {
|
||||||
RAL_UNLOCK(sc);
|
RAL_UNLOCK(sc);
|
||||||
|
m_freem(m);
|
||||||
|
ieee80211_free_node(ni);
|
||||||
return ENETDOWN;
|
return ENETDOWN;
|
||||||
}
|
}
|
||||||
if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
|
if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
|
||||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||||
RAL_UNLOCK(sc);
|
RAL_UNLOCK(sc);
|
||||||
|
m_freem(m);
|
||||||
|
ieee80211_free_node(ni);
|
||||||
return ENOBUFS; /* XXX */
|
return ENOBUFS; /* XXX */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,8 +1222,12 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
|||||||
ural_txeof);
|
ural_txeof);
|
||||||
|
|
||||||
error = usbd_transfer(data->xfer);
|
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;
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
sc->tx_queued++;
|
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;
|
rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
|
||||||
/* XXX validate */
|
/* XXX validate */
|
||||||
if (rate == 0)
|
if (rate == 0) {
|
||||||
|
m_freem(m0);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(sc->sc_drvbpf)) {
|
if (bpf_peers_present(sc->sc_drvbpf)) {
|
||||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
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);
|
ural_txeof);
|
||||||
|
|
||||||
error = usbd_transfer(data->xfer);
|
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;
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
sc->tx_queued++;
|
sc->tx_queued++;
|
||||||
|
|
||||||
@ -1411,9 +1421,10 @@ ural_start(struct ifnet *ifp)
|
|||||||
if (bpf_peers_present(ic->ic_rawbpf))
|
if (bpf_peers_present(ic->ic_rawbpf))
|
||||||
bpf_mtap(ic->ic_rawbpf, m0);
|
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;
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ic->ic_state != IEEE80211_S_RUN)
|
if (ic->ic_state != IEEE80211_S_RUN)
|
||||||
break;
|
break;
|
||||||
@ -2310,10 +2321,15 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
struct ural_softc *sc = ifp->if_softc;
|
struct ural_softc *sc = ifp->if_softc;
|
||||||
|
|
||||||
/* prevent management frames from being sent if we're not ready */
|
/* 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;
|
return ENETDOWN;
|
||||||
|
}
|
||||||
if (sc->tx_queued >= RAL_TX_LIST_COUNT) {
|
if (sc->tx_queued >= RAL_TX_LIST_COUNT) {
|
||||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||||
|
m_freem(m);
|
||||||
|
ieee80211_free_node(ni);
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1093,9 +1093,6 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
|
|
||||||
k = ieee80211_crypto_encap(ic, ni, m0);
|
k = ieee80211_crypto_encap(ic, ni, m0);
|
||||||
if (k == NULL) {
|
if (k == NULL) {
|
||||||
if (ni != NULL)
|
|
||||||
ieee80211_free_node(ni);
|
|
||||||
m_freem(m0);
|
|
||||||
rc = ENOMEM;
|
rc = ENOMEM;
|
||||||
goto out;
|
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);
|
frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
|
||||||
if (IFF_DUMPPKTS(ifp))
|
if (IFF_DUMPPKTS(ifp))
|
||||||
wi_dump_pkt(&frmhdr, NULL, -1);
|
wi_dump_pkt(&frmhdr, NULL, -1);
|
||||||
if (ni != NULL)
|
if (wi_start_tx(ifp, &frmhdr, m0) < 0) {
|
||||||
ieee80211_free_node(ni);
|
m0 = NULL;
|
||||||
rc = wi_start_tx(ifp, &frmhdr, m0);
|
rc = EIO;
|
||||||
if (rc)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
m0 = NULL;
|
||||||
|
|
||||||
sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
|
sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
|
||||||
out:
|
out:
|
||||||
WI_UNLOCK(sc);
|
WI_UNLOCK(sc);
|
||||||
|
|
||||||
|
if (m0 != NULL)
|
||||||
|
m_freem(m0);
|
||||||
|
ieee80211_free_node(ni);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user