o Fix a write mbuf-after-free bug. The duration field of the 802.11 header

was written in the old fragmented mbuf chain instead of the defragmented
  one.  Thus, the duration field of outgoing frames was incorrect.

o Only call m_defrag() if the mbuf fragmentation threshold is greater
  than what is currently supported by the driver.

Reviewed by:    silby (mentor)
Approved by:    re (scottl)
This commit is contained in:
damien 2005-06-29 17:54:01 +00:00
parent 6886350a30
commit 5240ace1db

View File

@ -1971,22 +1971,36 @@ ral_tx_data(struct ral_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
data = &sc->txq.data[sc->txq.cur_encrypt];
desc = &sc->txq.desc[sc->txq.cur_encrypt];
mnew = m_defrag(m0, M_DONTWAIT);
if (mnew == NULL) {
device_printf(sc->sc_dev, "could not defragment mbuf\n");
m_freem(m0);
return ENOMEM;
}
m0 = mnew;
error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, m0,
segs, &nsegs, 0);
if (error != 0) {
if (error != 0 && error != EFBIG) {
device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
error);
m_freem(m0);
return error;
}
if (error != 0) {
mnew = m_defrag(m0, M_DONTWAIT);
if (mnew == NULL) {
device_printf(sc->sc_dev,
"could not defragment mbuf\n");
m_freem(m0);
return ENOBUFS;
}
m0 = mnew;
error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map,
m0, segs, &nsegs, 0);
if (error != 0) {
device_printf(sc->sc_dev,
"could not map mbuf (error %d)\n", error);
m_freem(m0);
return error;
}
/* packet header may have moved, reset our local pointer */
wh = mtod(m0, struct ieee80211_frame *);
}
if (sc->sc_drvbpf != NULL) {
struct ral_tx_radiotap_header *tap = &sc->sc_txtap;