From 051b63473065d4fb1c44f90df00c481ee2e294d9 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 7 Apr 2015 13:54:23 +0200 Subject: if_dwc: Avoid mbuf use after free --- freebsd/sys/dev/dwc/if_dwc.c | 38 +++++++++++++++++++++++++------------- 1 file 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); } } -- cgit v1.2.3