From owner-svn-src-all@freebsd.org Wed Dec 12 15:49:15 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 133FE1313236; Wed, 12 Dec 2018 15:49:15 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id A9C866B130; Wed, 12 Dec 2018 15:49:14 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9F362A0CC; Wed, 12 Dec 2018 15:49:14 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wBCFnESG005878; Wed, 12 Dec 2018 15:49:14 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wBCFnEmM005877; Wed, 12 Dec 2018 15:49:14 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201812121549.wBCFnEmM005877@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Wed, 12 Dec 2018 15:49:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341990 - head/sys/dev/bwn X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: head/sys/dev/bwn X-SVN-Commit-Revision: 341990 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: A9C866B130 X-Spamd-Bar: / Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-0.64 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_SHORT(-0.64)[-0.643,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Dec 2018 15:49:15 -0000 Author: markj Date: Wed Dec 12 15:49:14 2018 New Revision: 341990 URL: https://svnweb.freebsd.org/changeset/base/341990 Log: Fix a possible mbuf double free in bwn_dma_tx_start(). If bus_dmamap_load_mbuf() fails following a defrag, the caller of bwn_dma_tx_start() would free the original mbuf after m_defrag() had already done so. Fix this by returning the defragged mbuf to the caller instead. Update bwn_pio_tx_start() similarly for consistency. Reported by: Ilja Van Sprundel Reviewed by: landonf Tested by: landonf MFC after: 3 days admbug: 820 Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D18342 Modified: head/sys/dev/bwn/if_bwn.c Modified: head/sys/dev/bwn/if_bwn.c ============================================================================== --- head/sys/dev/bwn/if_bwn.c Wed Dec 12 15:23:40 2018 (r341989) +++ head/sys/dev/bwn/if_bwn.c Wed Dec 12 15:49:14 2018 (r341990) @@ -209,7 +209,7 @@ static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, uint32_t); static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, - struct mbuf *); + struct mbuf **); static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, struct bwn_pio_txqueue *, uint32_t, const void *, int); @@ -273,7 +273,7 @@ static void bwn_ratectl_tx_complete(const struct ieee8 static void bwn_dma_handle_txeof(struct bwn_mac *, const struct bwn_txstatus *); static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, - struct mbuf *); + struct mbuf **); static int bwn_dma_getslot(struct bwn_dma_ring *); static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, uint8_t); @@ -1068,7 +1068,7 @@ bwn_tx_start(struct bwn_softc *sc, struct ieee80211_no } error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? - bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); + bwn_dma_tx_start(mac, ni, &m) : bwn_pio_tx_start(mac, ni, &m); if (error) { m_freem(m); return (error); @@ -1077,13 +1077,14 @@ bwn_tx_start(struct bwn_softc *sc, struct ieee80211_no } static int -bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) +bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, + struct mbuf **mp) { struct bwn_pio_txpkt *tp; - struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); + struct bwn_pio_txqueue *tq; struct bwn_softc *sc = mac->mac_sc; struct bwn_txhdr txhdr; - struct mbuf *m_new; + struct mbuf *m, *m_new; uint32_t ctl32; int error; uint16_t ctl16; @@ -1092,6 +1093,8 @@ bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211 /* XXX TODO send packets after DTIM */ + m = *mp; + tq = bwn_pio_select(mac, M_WME_GETAC(m)); KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); tp = TAILQ_FIRST(&tq->tq_pktlist); tp->tp_ni = ni; @@ -1111,13 +1114,14 @@ bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211 /* * XXX please removes m_defrag(9) */ - m_new = m_defrag(m, M_NOWAIT); + m_new = m_defrag(*mp, M_NOWAIT); if (m_new == NULL) { device_printf(sc->sc_dev, "%s: can't defrag TX buffer\n", __func__); return (ENOBUFS); } + *mp = m_new; if (m_new->m_next != NULL) device_printf(sc->sc_dev, "TODO: fragmented packets for PIO\n"); @@ -1168,15 +1172,17 @@ bwn_pio_select(struct bwn_mac *mac, uint8_t prio) } static int -bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) +bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, + struct mbuf **mp) { #define BWN_GET_TXHDRCACHE(slot) \ &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) struct bwn_dma *dma = &mac->mac_method.dma; - struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); + struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(*mp)); struct bwn_dmadesc_generic *desc; struct bwn_dmadesc_meta *mt; struct bwn_softc *sc = mac->mac_sc; + struct mbuf *m; uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; @@ -1185,6 +1191,7 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211 /* XXX send after DTIM */ + m = *mp; slot = bwn_dma_getslot(dr); dr->getdesc(dr, slot, &desc, &mt); KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, @@ -1233,9 +1240,8 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211 __func__); error = ENOBUFS; goto fail; - } else { - m = m_new; } + *mp = m = m_new; mt->mt_m = m; error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,