[PATCH] intel_th: msu-sink: Fix coherent buffer leak on partial allocation failure

Pradhan, Sanman posted 1 patch 2 months, 2 weeks ago
drivers/hwtracing/intel_th/msu-sink.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
[PATCH] intel_th: msu-sink: Fix coherent buffer leak on partial allocation failure
Posted by Pradhan, Sanman 2 months, 2 weeks ago
From: Sanman Pradhan <psanman@juniper.net>

When dma_alloc_coherent() fails part-way through
msu_sink_alloc_window(), pages allocated in earlier iterations are not
freed and the sg_table is left allocated.

The core does not recover this allocation failure.  On error,
msc_buffer_win_alloc() frees only the msc_window object and does not
call the sink's ->free_window() callback, because the window was never
successfully added to the buffer's window list.

Also, msu_sink_alloc_window() increments priv->nr_sgts before the page
allocation loop completes.  If the loop fails, nr_sgts remains elevated
for a window that was never fully allocated, which can eventually cause
false MAX_SGTS exhaustion.

Fix this by:
- deferring the sgts[]/nr_sgts update until after the allocation loop
  succeeds; and
- unwinding all previously allocated DMA-coherent pages and freeing the
  sg_table on allocation failure.

Fixes: f220df66f676 ("intel_th: msu-sink: An example msu buffer "sink"")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
---
 drivers/hwtracing/intel_th/msu-sink.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/hwtracing/intel_th/msu-sink.c b/drivers/hwtracing/intel_th/msu-sink.c
index b809a7f805a9..ea3ff8415b90 100644
--- a/drivers/hwtracing/intel_th/msu-sink.c
+++ b/drivers/hwtracing/intel_th/msu-sink.c
@@ -65,19 +65,28 @@ static int msu_sink_alloc_window(void *data, struct sg_table **sgt, size_t size)
 	if (ret)
 		return -ENOMEM;
 
-	priv->sgts[priv->nr_sgts++] = *sgt;
-
 	for_each_sg((*sgt)->sgl, sg_ptr, nents, i) {
 		block = dma_alloc_coherent(priv->dev->parent->parent,
 					   PAGE_SIZE, &sg_dma_address(sg_ptr),
 					   GFP_KERNEL);
 		if (!block)
-			return -ENOMEM;
+			goto err_free_pages;
 
 		sg_set_buf(sg_ptr, block, PAGE_SIZE);
 	}
 
+	priv->sgts[priv->nr_sgts++] = *sgt;
+
 	return nents;
+
+err_free_pages:
+	for_each_sg((*sgt)->sgl, sg_ptr, i, ret)
+		dma_free_coherent(priv->dev->parent->parent, PAGE_SIZE,
+				  sg_virt(sg_ptr), sg_dma_address(sg_ptr));
+
+	sg_free_table(*sgt);
+
+	return -ENOMEM;
 }
 
 /* See also: msc.c: __msc_buffer_win_free() */
-- 
2.34.1

Re: [PATCH] intel_th: msu-sink: Fix coherent buffer leak on partial allocation failure
Posted by Pradhan, Sanman 1 month, 4 weeks ago
From: Sanman Pradhan <psanman@juniper.net>

Ping. Kindly requesting a review when you get a chance.

https://lore.kernel.org/lkml/20260406175714.208227-1-sanman.pradhan@hpe.com/

Regards,
Sanman Pradhan