Thread (7 messages) flat view 7 messages, 4 authors, 3d ago

Re: [PATCH v2] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg()

From: sashiko-bot@kernel.org
Date: 2026-09-10 02:27:02

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Use-after-free of list head in error path when freeing descriptor chain because the list head is embedded in the first element being freed.
--

commit 5f1b06ea0ed695c8b6d14358fdfb48649d799152
Author: Baineng Shou [off-list ref]

dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg()

This commit fixes a bug in mmp_pdma_prep_slave_sg() where for_each_sg()
read the entry length from the list head instead of the current entry.
This led to out-of-bounds reads or silent data loss when handling
multi-sg lists of varying entry lengths.
quoted hunk ↗ jump to hunk
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 386e85cd4882a..e90fd2023af71 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -713,7 +713,7 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
 
 	for_each_sg(sgl, sg, sg_len, i) {
 		addr = sg_dma_address(sg);
-		avail = sg_dma_len(sgl);
+		avail = sg_dma_len(sg);
 
 		do {
 			len = min_t(size_t, avail, PDMA_MAX_DESC_BYTES);
[Severity: High]
This is a pre-existing issue, but I noticed a potential use-after-free
if a subsequent descriptor allocation fails further down in this function.

If a subsequent allocation fails, the error path is taken:

drivers/dma/mmp_pdma.c:mmp_pdma_prep_slave_sg() {
    ...
fail:
	if (first)
		mmp_pdma_free_desc_list(chan, &first->tx_list);
	return NULL;
}

Inside mmp_pdma_free_desc_list(), list_for_each_entry_safe() iterates
over the list and frees each descriptor:

drivers/dma/mmp_pdma.c:mmp_pdma_free_desc_list() {
    ...
	list_for_each_entry_safe(desc, _desc, list, node) {
		list_del(&desc->node);
		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
	}
}

Because the list head (&first->tx_list) is embedded within the first
descriptor, it is freed during the first iteration.

If there are multiple elements in the list, the second iteration calls
list_del(&desc->node), which modifies pointers that point back to the
now-freed list head. 

Does this result in a use-after-free write into the freed descriptor?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260910021652.1296640-1-shoubaineng@gmail.com?part=1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help