ARM: dma-mapping: add more sanity checks in arm_dma_mmap()
authorMarek Szyprowski <m.szyprowski@samsung.com>
Mon, 30 Jul 2012 07:35:26 +0000 (09:35 +0200)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Mon, 30 Jul 2012 10:25:45 +0000 (12:25 +0200)
Add some sanity checks and forbid mmaping of buffers into vma areas larger
than allocated dma buffer.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
arch/arm/mm/dma-mapping.c

index f906d5f4cbd8e203f4b567dcee32cdff0f6874d6..a2881c98fb03bb6de82a48484ecd4c44db44d91d 100644 (file)
@@ -611,16 +611,22 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 {
        int ret = -ENXIO;
 #ifdef CONFIG_MMU
+       unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+       unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
        unsigned long pfn = dma_to_pfn(dev, dma_addr);
+       unsigned long off = vma->vm_pgoff;
+
        vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
 
        if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
                return ret;
 
-       ret = remap_pfn_range(vma, vma->vm_start,
-                             pfn + vma->vm_pgoff,
-                             vma->vm_end - vma->vm_start,
-                             vma->vm_page_prot);
+       if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
+               ret = remap_pfn_range(vma, vma->vm_start,
+                                     pfn + off,
+                                     vma->vm_end - vma->vm_start,
+                                     vma->vm_page_prot);
+       }
 #endif /* CONFIG_MMU */
 
        return ret;