]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Take mmap lock in cacheflush syscall
authorJann Horn <jannh@google.com>
Fri, 19 Feb 2021 06:59:35 +0000 (14:59 +0800)
committerLey Foon Tan <ley.foon.tan@intel.com>
Fri, 19 Feb 2021 07:01:59 +0000 (15:01 +0800)
We need to take the mmap lock around find_vma() and subsequent use of the
VMA. Otherwise, we can race with concurrent operations like munmap(), which
can lead to use-after-free accesses to freed VMAs.

Fixes: 1000197d8013 ("nios2: System calls handling")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
arch/nios2/kernel/sys_nios2.c

index cd390ec4f88bf5689557148cac034d63c9e68313..b1ca85699952135678c814053b94acc4ff388138 100644 (file)
@@ -22,6 +22,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len,
                                unsigned int op)
 {
        struct vm_area_struct *vma;
+       struct mm_struct *mm = current->mm;
 
        if (len == 0)
                return 0;
@@ -34,16 +35,22 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len,
        if (addr + len < addr)
                return -EFAULT;
 
+       if (mmap_read_lock_killable(mm))
+               return -EINTR;
+
        /*
         * Verify that the specified address region actually belongs
         * to this process.
         */
-       vma = find_vma(current->mm, addr);
-       if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
+       vma = find_vma(mm, addr);
+       if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) {
+               mmap_read_unlock(mm);
                return -EFAULT;
+       }
 
        flush_cache_range(vma, addr, addr + len);
 
+       mmap_read_unlock(mm);
        return 0;
 }