From: Christoph Hellwig <h...@lst.de>

[ Upstream commit 66d7780f18eae0232827fcffeaded39a6a168236 ]

Check that the pfn returned from arch_dma_coherent_to_pfn refers to
a valid page and reject the mmap / get_sgtable requests otherwise.

Based on the arm implementation of the mmap and get_sgtable methods.

Signed-off-by: Christoph Hellwig <h...@lst.de>
Tested-by: Vignesh Raghavendra <vigne...@ti.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 kernel/dma/mapping.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index f7afdadb6770b..3401382bbca2f 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -116,11 +116,16 @@ int dma_common_get_sgtable(struct device *dev, struct 
sg_table *sgt,
        int ret;
 
        if (!dev_is_dma_coherent(dev)) {
+               unsigned long pfn;
+
                if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
                        return -ENXIO;
 
-               page = pfn_to_page(arch_dma_coherent_to_pfn(dev, cpu_addr,
-                               dma_addr));
+               /* If the PFN is not valid, we do not have a struct page */
+               pfn = arch_dma_coherent_to_pfn(dev, cpu_addr, dma_addr);
+               if (!pfn_valid(pfn))
+                       return -ENXIO;
+               page = pfn_to_page(pfn);
        } else {
                page = virt_to_page(cpu_addr);
        }
@@ -170,7 +175,11 @@ int dma_common_mmap(struct device *dev, struct 
vm_area_struct *vma,
        if (!dev_is_dma_coherent(dev)) {
                if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
                        return -ENXIO;
+
+               /* If the PFN is not valid, we do not have a struct page */
                pfn = arch_dma_coherent_to_pfn(dev, cpu_addr, dma_addr);
+               if (!pfn_valid(pfn))
+                       return -ENXIO;
        } else {
                pfn = page_to_pfn(virt_to_page(cpu_addr));
        }
-- 
2.20.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to