fbdev: improve fb_mmap bounds checks
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 18 Apr 2013 05:39:47 +0000 (08:39 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 26 Apr 2013 05:28:56 +0000 (08:28 +0300)
Improve fb_mmap bounds checks in gbefb, smscufx, udlfb and vfb drivers to
prevent possible uint overflows.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Steve Glendinning <steve.glendinning@smsc.com>
Cc: Bernie Thompson <bernie@plugable.com>
drivers/video/gbefb.c
drivers/video/smscufx.c
drivers/video/udlfb.c
drivers/video/vfb.c

index bda5e3941510fa1c415667a873fc684b928a91e8..ceab37020fff17935596ba435f1c30e00ce94204 100644 (file)
@@ -1016,7 +1016,9 @@ static int gbefb_mmap(struct fb_info *info,
        /* check range */
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
                return -EINVAL;
-       if (offset + size > gbe_mem_size)
+       if (size > gbe_mem_size)
+               return -EINVAL;
+       if (offset > gbe_mem_size - size)
                return -EINVAL;
 
        /* remap using the fastest write-through mode on architecture */
index 97bd6620c36494d993b0d77877a2531be80250c3..b2b33fc1ac3faa9953cab079bc094e1f04041646 100644 (file)
@@ -782,7 +782,11 @@ static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
        unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
        unsigned long page, pos;
 
-       if (offset + size > info->fix.smem_len)
+       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+               return -EINVAL;
+       if (size > info->fix.smem_len)
+               return -EINVAL;
+       if (offset > info->fix.smem_len - size)
                return -EINVAL;
 
        pos = (unsigned long)info->fix.smem_start + offset;
index 86d449ea31699db3c7e7c5f1a7bfc1a41c2b5d83..ec03e726c94008791481bfade233e5b384bb2ddb 100644 (file)
@@ -324,7 +324,11 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
        unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
        unsigned long page, pos;
 
-       if (offset + size > info->fix.smem_len)
+       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+               return -EINVAL;
+       if (size > info->fix.smem_len)
+               return -EINVAL;
+       if (offset > info->fix.smem_len - size)
                return -EINVAL;
 
        pos = (unsigned long)info->fix.smem_start + offset;
index 8bc1f9398945a2c99b9e45286064499d4dfd88fe..ee5985efa15c83c64d7e22718c22c594e0338f0e 100644 (file)
@@ -420,9 +420,12 @@ static int vfb_mmap(struct fb_info *info,
        unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
        unsigned long page, pos;
 
-       if (offset + size > info->fix.smem_len) {
+       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+               return -EINVAL;
+       if (size > info->fix.smem_len)
+               return -EINVAL;
+       if (offset > info->fix.smem_len - size)
                return -EINVAL;
-       }
 
        pos = (unsigned long)info->fix.smem_start + offset;