Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] arm/dma-mapping: invalid cast in __atomic_get_pages causes kernel 
panic on mmap/sgtable
--

commit 0f1d7f693768ddb66d127fa1093856300ee17984
Author: Mikko Perttunen <[email protected]>

ARM: dma-mapping: Handle foreign buffers in arm_iommu_get_sgtable

This commit updates arm_iommu_get_sgtable() to handle foreign buffers
that were not allocated through arm_iommu_alloc_attrs(). Instead of
returning an error, it falls back to describing the buffer as a single
chunk, similar to how iommu_dma_get_sgtable() operates.

> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index d6315baeddb9c..c2ec4f1078083 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1169,12 +1169,29 @@ static int arm_iommu_get_sgtable(struct device *dev, 
> struct sg_table *sgt,
>  {
>       unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>       struct page **pages = __iommu_get_pages(cpu_addr, attrs);
> +     struct page *page;
> +     int ret;
>  
> -     if (!pages)
> -             return -ENXIO;
> +     if (pages)
> +             return sg_alloc_table_from_pages(sgt, pages, count, 0, size,
> +                                              GFP_KERNEL);

[Severity: High]
Does this code still cause memory corruption when handling atomic pool
allocations?

The underlying __iommu_get_pages() function can return the result of
__atomic_get_pages(), which incorrectly casts a single struct page pointer to
an array of pointers:

arch/arm/mm/dma-mapping.c:__atomic_get_pages() {
    ...
    return (struct page **)page;
}

When arm_iommu_get_sgtable() receives this pointer, it passes it to
sg_alloc_table_from_pages(). That function iterates over the pointer as an
array, reading pages[i]. For pages[0], this reads the internal fields of the
page object (such as flags on 32-bit ARM) and interprets them as a page
pointer. Passing this uninitialized pointer to page_to_pfn() or get_page()
causes memory corruption and kernel panics.

Can this be triggered by userspace exporting a dma-buf or mmapping an
atomic-pool DMA buffer?

The same issue appears to be present in arm_iommu_mmap_attrs() which passes
the bogus array to vm_map_pages():

arch/arm/mm/dma-mapping.c:arm_iommu_mmap_attrs() {
    ...
    return vm_map_pages(vma, pages, nr_pages);
}

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=6

Reply via email to