DMA Engine development
 help / color / mirror / Atom feed
* [PATCH] dmaengine: xilinx: Fix wild pointer dereference on empty segment list
@ 2026-10-23  6:58 Li Ximo
  2026-10-23  7:10 ` sashiko-bot
  0 siblings, 1 reply; 3+ messages in thread
From: Li Ximo @ 2026-10-23  6:58 UTC (permalink / raw)
  To: Vinod Koul, Michal Simek
  Cc: Frank Li, dmaengine, linux-arm-kernel, linux-kernel, Wang Haoran,
	Li Ximo

From: Wang Haoran <haoranwangsec@gmail.com>

list_first_entry() does not return NULL when the list is empty; it
returns the result of container_of() on the list head, i.e. a wild
pointer that points into the enclosing xilinx_dma_tx_descriptor rather
than to a valid segment. Dereferencing it reads or writes unrelated
descriptor memory. This was found by code audit.

In xilinx_dma_prep_peripheral_dma_vec(), xilinx_dma_prep_slave_sg()
and xilinx_mcdma_prep_slave_sg(), the loop that populates
desc->segments never executes when the transfer length is zero
(nb == 0, sg_len == 0, or all vecs[i].len / sg_dma_len() entries are
zero). The dmaengine inline wrappers do not reject such zero-length
transfers, so they reach the driver unchanged. The unconditional
list_first_entry() then yields a wild pointer: the following
head->phys / segment->phys reads are out-of-bounds reads within the
descriptor slab, and on the DMA_MEM_TO_DEV path the hw.control
read-modify-write corrupts the descriptor. In
xilinx_dma_prep_peripheral_dma_vec() the empty case additionally
dereferences the never-initialized 'segment' pointer. Similarly, in
xilinx_dma_get_metadata_ptr(), a descriptor with an empty segment
list produces a wild 'seg' whose hw.app pointer is handed back to the
DMA client.

Guard each list_first_entry() call: in the three prep functions, bail
out through the existing error path (freeing the descriptor and
returning NULL, consistent with the current failure handling) when
desc->segments is still empty after the build loop; in
xilinx_dma_get_metadata_ptr(), use list_first_entry_or_null() and
return NULL when there is no segment.

Reported-by: Wang Haoran <haoranwangsec@gmail.com>
Reported-by: Li Ximo <lixicaicai@gmail.com>
Signed-off-by: Wang Haoran <haoranwangsec@gmail.com>
---
 drivers/dma/xilinx/xilinx_dma.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index cffe7c6fa..07f52f841 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -650,8 +650,11 @@ static void *xilinx_dma_get_metadata_ptr(struct dma_async_tx_descriptor *tx,
 	struct xilinx_axidma_tx_segment *seg;
 
 	*max_len = *payload_len = sizeof(u32) * XILINX_DMA_NUM_APP_WORDS;
-	seg = list_first_entry(&desc->segments,
-			       struct xilinx_axidma_tx_segment, node);
+	seg = list_first_entry_or_null(&desc->segments,
+				       struct xilinx_axidma_tx_segment, node);
+	if (!seg)
+		return NULL;
+
 	return seg->hw.app;
 }
 
@@ -2305,6 +2308,9 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_peripheral_dma_vec(
 		}
 	}
 
+	if (list_empty(&desc->segments))
+		goto error;
+
 	head = list_first_entry(&desc->segments, struct xilinx_axidma_tx_segment, node);
 	desc->async_tx.phys = head->phys;
 
@@ -2406,6 +2412,9 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
 		}
 	}
 
+	if (list_empty(&desc->segments))
+		goto error;
+
 	segment = list_first_entry(&desc->segments,
 				   struct xilinx_axidma_tx_segment, node);
 	desc->async_tx.phys = segment->phys;
@@ -2613,6 +2622,9 @@ xilinx_mcdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
 		}
 	}
 
+	if (list_empty(&desc->segments))
+		goto error;
+
 	segment = list_first_entry(&desc->segments,
 				   struct xilinx_aximcdma_tx_segment, node);
 	desc->async_tx.phys = segment->phys;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-27 19:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23  6:58 [PATCH] dmaengine: xilinx: Fix wild pointer dereference on empty segment list Li Ximo
2026-10-23  7:10 ` sashiko-bot
2026-10-27 19:34   ` Frank Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox