PERFORCE change 118409 for review
Sepherosa Ziehau
sephe at FreeBSD.org
Thu Apr 19 13:13:15 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=118409
Change 118409 by sephe at sephe_zealot:sam_wifi on 2007/04/19 13:12:13
- 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)
Affected files ...
.. //depot/projects/wifi/sys/dev/ath/if_ath.c#137 edit
.. //depot/projects/wifi/sys/dev/ral/rt2560.c#18 edit
.. //depot/projects/wifi/sys/dev/usb/if_ural.c#18 edit
.. //depot/projects/wifi/sys/dev/wi/if_wi.c#32 edit
Differences ...
==== //depot/projects/wifi/sys/dev/ath/if_ath.c#137 (text+ko) ====
@@ -6498,6 +6498,7 @@
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;
}
@@ -6514,6 +6515,7 @@
__func__);
sc->sc_stats.ast_tx_qstop++;
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ ieee80211_free_node(ni);
m_freem(m);
return ENOBUFS;
}
==== //depot/projects/wifi/sys/dev/ral/rt2560.c#18 (text) ====
@@ -1681,8 +1681,10 @@
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);
@@ -2823,11 +2825,15 @@
/* 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 */
}
==== //depot/projects/wifi/sys/dev/usb/if_ural.c#18 (text+ko) ====
@@ -1246,8 +1246,12 @@
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++;
@@ -1270,8 +1274,10 @@
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;
@@ -1314,8 +1320,12 @@
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++;
@@ -1435,9 +1445,10 @@
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;
@@ -2381,10 +2392,16 @@
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;
}
==== //depot/projects/wifi/sys/dev/wi/if_wi.c#32 (text+ko) ====
@@ -1116,9 +1116,6 @@
k = ieee80211_crypto_encap(ic, ni, m0);
if (k == NULL) {
- if (ni != NULL)
- ieee80211_free_node(ni);
- m_freem(m0);
rc = ENOMEM;
goto out;
}
@@ -1139,16 +1136,20 @@
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;
}
More information about the p4-projects
mailing list