Date: Thu, 19 Apr 2007 13:13:14 GMT From: Sepherosa Ziehau <sephe@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 118409 for review Message-ID: <200704191313.l3JDDEZ6005772@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=118409 Change 118409 by sephe@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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200704191313.l3JDDEZ6005772>