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,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to