Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66d7780f authored by Christoph Hellwig's avatar Christoph Hellwig
Browse files

dma-mapping: check pfn validity in dma_common_{mmap,get_sgtable}



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: default avatarChristoph Hellwig <hch@lst.de>
Tested-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
parent 06532750
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -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));
	}