Add range_is_allowed() check to mmap of /dev/mem
PATCH 1/1 Add range_is_allowed() check to mmap of /dev/mem
Earlier patch that introduced CONFIG_NONPROMISC_DEVMEM, did the range_is_allowed() check only for read and write. Add range_is_allowed() check to mmap of /dev/mem as well.
Changes the paramaters of range_is_allowed() to pfn and size to handle more than 32 bits of physical address on 32 bit arch cleanly.
Signed-off-by Venkatesh Pallipadi <[email protected]>
drivers/char/mem.c +17 -12
@@ -109,24 +109,26 @@#endif #ifdef CONFIG_NONPROMISC_DEVMEM -static inline int range_is_allowed (unsigned long from,unsigned long to) +static inline int range_is_allowed (unsigned long pfn,unsigned long size) { -unsigned long cursor; - - cursor = from >>PAGE_SHIFT ; -while ((cursor <<PAGE_SHIFT ) < to) { -if (!devmem_is_allowed (cursor)) { -printk (KERN_INFO "Program %s tried to read /dev/mem " -"between %lx->%lx.\n" , +u64 from = ((u64 )pfn) <<PAGE_SHIFT ; +u64 to = from + size; +u64 cursor = from; + +while (cursor < to) { +if (!devmem_is_allowed (pfn)) { +printk (KERN_INFO +"Program %s tried to access /dev/mem between %Lx->%Lx.\n" , current->comm, from, to);return 0 ; } - cursor++; + cursor +=PAGE_SIZE ; + pfn++; }return 1 ; }#else -static inline int range_is_allowed (unsigned long from,unsigned long to) +static inline int range_is_allowed (unsigned long pfn,unsigned long size) {return 1 ; }
@@ -181,7 +183,7 @@*/ ptr =xlate_dev_mem_ptr (p); -if (!range_is_allowed (p, p+count)) +if (!range_is_allowed (p >>PAGE_SHIFT , count))return -EPERM ;if (copy_to_user (buf, ptr, sz))return -EFAULT ;
@@ -240,7 +242,7 @@*/ ptr =xlate_dev_mem_ptr (p); -if (!range_is_allowed (p, p+sz)) +if (!range_is_allowed (p >>PAGE_SHIFT , sz))return -EPERM ; copied =copy_from_user (ptr, buf, sz);if (copied) {
@@ -309,6 +311,9 @@if (!private_mapping_ok (vma))return -ENOSYS ; +if (!range_is_allowed (vma->vm_pgoff, size)) +return -EPERM ; + vma->vm_page_prot =phys_mem_access_prot (file, vma->vm_pgoff, size, vma->vm_page_prot);
Ingo Molnar
AppliedQuoted 6 lines · Venki Pallipadi
Earlier patch that introduced
CONFIG_NONPROMISC_DEVMEM, did therange_is_allowed()check only for read and write. Addrange_is_allowed()check to mmap of/dev/memas well.Changes the paramaters of
range_is_allowed()to pfn and size to handle more than 32 bits of physical address on 32 bit arch cleanly.
thanks, applied.
Ingo