diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2012-07-30 09:35:26 +0200 |
---|---|---|
committer | Marek Szyprowski <m.szyprowski@samsung.com> | 2012-07-30 12:25:45 +0200 |
commit | 50262a4bf38dd70486e9fce2b8235d5ae3e0f627 (patch) | |
tree | f20c140547bd6d33079143fcc77d81844796609c | |
parent | e9da6e9905e639b0f842a244bc770b48ad0523e9 (diff) |
ARM: dma-mapping: add more sanity checks in arm_dma_mmap()
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>
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f906d5f4cbd8..a2881c98fb03 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -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; |