--- fe05c24365f5371b9caf114579657fae390e0746 +++ 7ded615890c8d94a06ac4b30f0b772c9eacb2c19 @@ -925,7 +925,6 @@ static int check_vaddr_bounds(unsigned l if (end < start) goto out; - down_read(&mm->mmap_sem); vma = find_vma(mm, start); if (vma && vma->vm_start < end) { if (start < vma->vm_start) @@ -936,7 +935,6 @@ static int check_vaddr_bounds(unsigned l } out_up: - up_read(&mm->mmap_sem); out: return ret; } @@ -1543,7 +1541,7 @@ static long ion_ioctl(struct file *filp, unsigned long start, end; struct ion_handle *handle = NULL; int ret; - + struct mm_struct *mm = current->active_mm; if (copy_from_user(&data, (void __user *)arg, sizeof(struct ion_flush_data))) return -EFAULT; @@ -1551,12 +1549,6 @@ static long ion_ioctl(struct file *filp, start = (unsigned long) data.vaddr; end = (unsigned long) data.vaddr + data.length; - if (check_vaddr_bounds(start, end)) { - pr_err("%s: virtual address %p is out of bounds\n", - __func__, data.vaddr); - return -EINVAL; - } - if (!data.handle) { handle = ion_import_fd(client, data.fd); if (IS_ERR_OR_NULL(handle)) { @@ -1565,12 +1557,21 @@ static long ion_ioctl(struct file *filp, return -EINVAL; } } + down_read(&mm->mmap_sem); + if (check_vaddr_bounds(start, end)) { + up_read(&mm->mmap_sem); + pr_err("%s: virtual address %p is out of bounds\n", + __func__, data.vaddr); + if (!data.handle) + ion_free(client, handle); + return -EINVAL; + } ret = ion_do_cache_op(client, data.handle ? data.handle : handle, data.vaddr, data.offset, data.length, cmd); - + up_read(&mm->mmap_sem); if (!data.handle) ion_free(client, handle);