svn commit: r342138 - stable/11/sys/dev/bwn

Mark Johnston markj at FreeBSD.org
Sat Dec 15 20:07:33 UTC 2018


Author: markj
Date: Sat Dec 15 20:07:32 2018
New Revision: 342138
URL: https://svnweb.freebsd.org/changeset/base/342138

Log:
  MFC r341990:
  Fix a possible mbuf double free in bwn_dma_tx_start().

Modified:
  stable/11/sys/dev/bwn/if_bwn.c

Modified: stable/11/sys/dev/bwn/if_bwn.c
==============================================================================
--- stable/11/sys/dev/bwn/if_bwn.c	Sat Dec 15 19:56:51 2018	(r342137)
+++ stable/11/sys/dev/bwn/if_bwn.c	Sat Dec 15 20:07:32 2018	(r342138)
@@ -196,7 +196,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);
@@ -261,7 +261,7 @@ static uint8_t	bwn_dma_check_redzone(struct bwn_dma_ri
 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);
@@ -937,7 +937,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);
@@ -946,13 +946,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;
@@ -961,6 +962,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;
@@ -980,13 +983,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");
@@ -1037,15 +1041,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 };
 
@@ -1054,6 +1060,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,
@@ -1102,9 +1109,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,


More information about the svn-src-all mailing list