summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-04-07 13:54:23 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:33 +0100
commit051b63473065d4fb1c44f90df00c481ee2e294d9 (patch)
tree445b39c04ad886723662b6f34e60083bf002385a
parentif_dwc: Checksum offload (diff)
downloadrtems-libbsd-051b63473065d4fb1c44f90df00c481ee2e294d9.tar.bz2
if_dwc: Avoid mbuf use after free
-rw-r--r--freebsd/sys/dev/dwc/if_dwc.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/freebsd/sys/dev/dwc/if_dwc.c b/freebsd/sys/dev/dwc/if_dwc.c
index 3f8824ac..98885edc 100644
--- a/freebsd/sys/dev/dwc/if_dwc.c
+++ b/freebsd/sys/dev/dwc/if_dwc.c
@@ -806,13 +806,37 @@ dwc_rxfinish_locked(struct dwc_softc *sc)
if ((rdes0 & DDESC_RDES0_OWN) != 0)
break;
+ sc->rx_idx = next_rxidx(sc, idx);
+
+ m = sc->rxbuf_map[idx].mbuf;
+
+ m0 = dwc_alloc_mbufcl(sc);
+ if (m0 == NULL) {
+ m0 = m;
+
+ /* Account for m_adj() in dwc_setup_rxbuf() */
+ m0->m_data = m0->m_ext.ext_buf;
+ }
+
+ if ((error = dwc_setup_rxbuf(sc, idx, m0)) != 0) {
+ /*
+ * XXX Now what?
+ * We've got a hole in the rx ring.
+ */
+ }
+
+ if (m0 == m) {
+ /* Discard frame and continue */
+ if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1);
+ continue;
+ }
+
bus_dmamap_sync(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->rxbuf_tag, sc->rxbuf_map[idx].map);
len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK;
if (len != 0) {
- m = sc->rxbuf_map[idx].mbuf;
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = len;
m->m_len = len;
@@ -851,18 +875,6 @@ dwc_rxfinish_locked(struct dwc_softc *sc)
} else {
/* XXX Zero-length packet ? */
}
-
- if ((m0 = dwc_alloc_mbufcl(sc)) != NULL) {
- if ((error = dwc_setup_rxbuf(sc, idx, m0)) != 0) {
- /*
- * XXX Now what?
- * We've got a hole in the rx ring.
- */
- }
- } else
- if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1);
-
- sc->rx_idx = next_rxidx(sc, sc->rx_idx);
}
}