mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
devmem: 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 <venkatesh.pallipadi@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
ae531c26c5
commit
e2beb3eae6
1 changed files with 16 additions and 11 deletions
|
@ -109,24 +109,26 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
|
|||
#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;
|
||||
u64 from = ((u64)pfn) << PAGE_SHIFT;
|
||||
u64 to = from + size;
|
||||
u64 cursor = from;
|
||||
|
||||
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",
|
||||
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 @@ static ssize_t read_mem(struct file * file, char __user * buf,
|
|||
*/
|
||||
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 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
|
|||
*/
|
||||
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 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue