]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: usb-audio: qcom: Free sideband sg_table objects
authorXu Rao <raoxu@uniontech.com>
Tue, 16 Jun 2026 11:59:16 +0000 (19:59 +0800)
committerTakashi Iwai <tiwai@suse.de>
Wed, 17 Jun 2026 09:05:18 +0000 (11:05 +0200)
The Qualcomm USB audio offload driver obtains an endpoint transfer-ring
table by calling xhci_sideband_get_endpoint_buffer(). This getter passes
the endpoint ring to xhci_ring_to_sgtable(), which allocates the outer
struct sg_table with kzalloc_obj(*sgt). The event-ring path is
equivalent: xhci_sideband_get_event_buffer() also returns the result of
xhci_ring_to_sgtable().

Inside xhci_ring_to_sgtable(), sg_alloc_table_from_pages() separately
allocates the scatterlist storage referenced by sgt->sgl. The returned
object therefore has two allocation layers: the outer struct sg_table
and its internal scatterlist storage.

The Qualcomm caller only invokes sg_free_table(sgt). sg_free_table()
releases the scatterlist storage owned by the table, but it does not
free the separately allocated outer struct sg_table. The local sgt
pointer is then discarded, so every successful endpoint or event-ring
query leaks the outer object.

Call kfree(sgt) after sg_free_table(sgt) in both setup paths, after the
required page and DMA addresses have been copied out.

Fixes: 326bbc348298 ("ALSA: usb-audio: qcom: Introduce QC USB SND offloading support")
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/90B353283AA150C4+20260616115916.1222915-1-raoxu@uniontech.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/qcom/qc_audio_offload.c

index a3f90cc7c6cadf46b9e5194b0a1dfcb61e9d7ed9..436d6821c5c97cd029ac044669a10a402f09fc0b 100644 (file)
@@ -1160,6 +1160,7 @@ uaudio_endpoint_setup(struct snd_usb_substream *subs,
        tr_pa = page_to_phys(pg);
        mem_info->dma = sg_dma_address(sgt->sgl);
        sg_free_table(sgt);
+       kfree(sgt);
 
        /* data transfer ring */
        iova = uaudio_iommu_map_pa(MEM_XFER_RING, dma_coherent, tr_pa,
@@ -1229,6 +1230,7 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
        er_pa = page_to_phys(pg);
        mem_info->dma = sg_dma_address(sgt->sgl);
        sg_free_table(sgt);
+       kfree(sgt);
 
        iova = uaudio_iommu_map_pa(MEM_EVENT_RING, dma_coherent, er_pa,
                                   PAGE_SIZE);