summaryrefslogtreecommitdiffstats
path: root/sys/dev/ral
diff options
context:
space:
mode:
authordamien <damien@FreeBSD.org>2005-06-29 17:54:01 +0000
committerdamien <damien@FreeBSD.org>2005-06-29 17:54:01 +0000
commit5240ace1db4d06e71e602d7f87cfa9d4724535b8 (patch)
tree16e8899beb7f746fde6a7b131b3f7552342f9672 /sys/dev/ral
parent6886350a3073ef04cfc52d90da8dc7628663aceb (diff)
downloadFreeBSD-src-5240ace1db4d06e71e602d7f87cfa9d4724535b8.zip
FreeBSD-src-5240ace1db4d06e71e602d7f87cfa9d4724535b8.tar.gz
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)
Diffstat (limited to 'sys/dev/ral')
-rw-r--r--sys/dev/ral/if_ral.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/sys/dev/ral/if_ral.c b/sys/dev/ral/if_ral.c
index 2a25f92..9e6cf74 100644
--- a/sys/dev/ral/if_ral.c
+++ b/sys/dev/ral/if_ral.c
@@ -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;
OpenPOWER on IntegriCloud