if_dwc: Avoid mbuf use after free

This commit is contained in:
Sebastian Huber 2015-04-07 13:54:23 +02:00
parent b99c023a08
commit 051b634730

View File

@ -806,13 +806,37 @@ dwc_rxfinish_locked(struct dwc_softc *sc)
if ((rdes0 & DDESC_RDES0_OWN) != 0) if ((rdes0 & DDESC_RDES0_OWN) != 0)
break; 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_dmamap_sync(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
BUS_DMASYNC_POSTREAD); BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->rxbuf_tag, sc->rxbuf_map[idx].map); bus_dmamap_unload(sc->rxbuf_tag, sc->rxbuf_map[idx].map);
len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK; len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK;
if (len != 0) { if (len != 0) {
m = sc->rxbuf_map[idx].mbuf;
m->m_pkthdr.rcvif = ifp; m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = len; m->m_pkthdr.len = len;
m->m_len = len; m->m_len = len;
@ -851,18 +875,6 @@ dwc_rxfinish_locked(struct dwc_softc *sc)
} else { } else {
/* XXX Zero-length packet ? */ /* 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);
} }
} }