summary refs log tree commit diff
path: root/drivers/uio/uio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-10-29 10:21:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-10-29 10:21:34 -0700
commit7314e613d5ff9f0934f7a0f74ed7973b903315d1 (patch)
tree71c58bf663e85fac4712ab86eaae78e889c41a49 /drivers/uio/uio.c
parentf9ec2e6f7991e748e75e324ed05ca2a7ec360ebb (diff)
downloadlinux-7314e613d5ff9f0934f7a0f74ed7973b903315d1.tar.gz
Fix a few incorrectly checked [io_]remap_pfn_range() calls
Nico Golde reports a few straggling uses of [io_]remap_pfn_range() that
really should use the vm_iomap_memory() helper.  This trivially converts
two of them to the helper, and comments about why the third one really
needs to continue to use remap_pfn_range(), and adds the missing size
check.

Reported-by: Nico Golde <nico@ngolde.de>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org.
Diffstat (limited to 'drivers/uio/uio.c')
-rw-r--r--drivers/uio/uio.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index ba475632c5fa..0e808cf91d97 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -642,16 +642,29 @@ static int uio_mmap_physical(struct vm_area_struct *vma)
 {
 	struct uio_device *idev = vma->vm_private_data;
 	int mi = uio_find_mem_index(vma);
+	struct uio_mem *mem;
 	if (mi < 0)
 		return -EINVAL;
+	mem = idev->info->mem + mi;
 
-	vma->vm_ops = &uio_physical_vm_ops;
+	if (vma->vm_end - vma->vm_start > mem->size)
+		return -EINVAL;
 
+	vma->vm_ops = &uio_physical_vm_ops;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
+	/*
+	 * We cannot use the vm_iomap_memory() helper here,
+	 * because vma->vm_pgoff is the map index we looked
+	 * up above in uio_find_mem_index(), rather than an
+	 * actual page offset into the mmap.
+	 *
+	 * So we just do the physical mmap without a page
+	 * offset.
+	 */
 	return remap_pfn_range(vma,
 			       vma->vm_start,
-			       idev->info->mem[mi].addr >> PAGE_SHIFT,
+			       mem->addr >> PAGE_SHIFT,
 			       vma->vm_end - vma->vm_start,
 			       vma->vm_page_prot);
 }