Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 May 2019 11:50:17 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 237921] Memory leak in function wpi_free_tx_ring of sys/dev/wpi/if_wpi.c
Message-ID:  <bug-237921-227@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D237921

            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@FreeBSD.org
          Reporter: yangx92@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 =3D 0; i < WPI_TX_RING_COUNT; i++) {
                struct wpi_tx_data *data =3D &ring->data[i];

                if (data->m !=3D 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 !=3D NULL)
                        bus_dmamap_destroy(ring->data_dmat, data->map);
        }
        if (ring->data_dmat !=3D NULL) {
                bus_dma_tag_destroy(ring->data_dmat);
                ring->data_dmat =3D 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 =3D NULL; after m_freem(data->m). Otherwis=
e,
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 =3D 0; i < WPI_TX_RING_COUNT; i++) {
                struct wpi_tx_data *data =3D &ring->data[i];

                if (data->m !=3D 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 =3D NULL;
                }
                if (data->map !=3D NULL)
                        bus_dmamap_destroy(ring->data_dmat, data->map);
+               if (data->ni !=3D NULL) {
+                       ieee80211_free_node(data->ni);
+                       data->ni =3D NULL;
+               }

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

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-237921-227>