diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-04-07 13:54:23 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:33 +0100 |
commit | 051b63473065d4fb1c44f90df00c481ee2e294d9 (patch) | |
tree | 445b39c04ad886723662b6f34e60083bf002385a | |
parent | if_dwc: Checksum offload (diff) | |
download | rtems-libbsd-051b63473065d4fb1c44f90df00c481ee2e294d9.tar.bz2 |
if_dwc: Avoid mbuf use after free
-rw-r--r-- | freebsd/sys/dev/dwc/if_dwc.c | 38 |
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); } } |