[Bug 237921] Memory leak in function wpi_free_tx_ring of sys/dev/wpi/if_wpi.c

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu May 16 11:50:19 UTC 2019


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=237921

            Bug ID: 237921
           Summary: Memory leak in function wpi_free_tx_ring of
                    sys/dev/wpi/if_wpi.c
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs at FreeBSD.org
          Reporter: yangx92 at hotmail.com

There is a memory leak and possible use-after-free vulnerability in function
wpi_free_tx_ring of sys/dev/wpi/if_wpi.c.

static void
wpi_free_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
{
        int i;

        DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__);

        wpi_dma_contig_free(&ring->desc_dma);
        wpi_dma_contig_free(&ring->cmd_dma);

        for (i = 0; i < WPI_TX_RING_COUNT; i++) {
                struct wpi_tx_data *data = &ring->data[i];

                if (data->m != NULL) {
                        bus_dmamap_sync(ring->data_dmat, data->map,
                            BUS_DMASYNC_POSTWRITE);
                        bus_dmamap_unload(ring->data_dmat, data->map);
                        m_freem(data->m);
                }
                if (data->map != NULL)
                        bus_dmamap_destroy(ring->data_dmat, data->map);
        }
        if (ring->data_dmat != NULL) {
                bus_dma_tag_destroy(ring->data_dmat);
                ring->data_dmat = NULL;
        }
}


There are two pointers in struct wpi_tx_data.
struct wpi_tx_data {
        bus_dmamap_t            map;
        bus_addr_t              cmd_paddr;
        struct mbuf             *m;
        struct ieee80211_node   *ni;
        int                     hdrlen;
};

In the for-loop, the function should both free data->m and data->ni.
Besides, there should be data->m = NULL; after m_freem(data->m). Otherwise,
there may be use-after-free vulnerability.

Below are proposed patch.

static void
wpi_free_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
{
        int i;

        DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__);

        wpi_dma_contig_free(&ring->desc_dma);
        wpi_dma_contig_free(&ring->cmd_dma);

        for (i = 0; i < WPI_TX_RING_COUNT; i++) {
                struct wpi_tx_data *data = &ring->data[i];

                if (data->m != NULL) {
                        bus_dmamap_sync(ring->data_dmat, data->map,
                            BUS_DMASYNC_POSTWRITE);
                        bus_dmamap_unload(ring->data_dmat, data->map);
                        m_freem(data->m);
+                       data->m = NULL;
                }
                if (data->map != NULL)
                        bus_dmamap_destroy(ring->data_dmat, data->map);
+               if (data->ni != NULL) {
+                       ieee80211_free_node(data->ni);
+                       data->ni = NULL;
+               }

        }
        if (ring->data_dmat != NULL) {
                bus_dma_tag_destroy(ring->data_dmat);
                ring->data_dmat = NULL;
        }
}

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list