mm: lock newly mapped VMA which can be modified after it becomes visible
authorSuren Baghdasaryan <surenb@google.com>
Sat, 8 Jul 2023 19:12:11 +0000 (12:12 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 8 Jul 2023 21:08:02 +0000 (14:08 -0700)
mmap_region adds a newly created VMA into VMA tree and might modify it
afterwards before dropping the mmap_lock.  This poses a problem for page
faults handled under per-VMA locks because they don't take the mmap_lock
and can stumble on this VMA while it's still being modified.  Currently
this does not pose a problem since post-addition modifications are done
only for file-backed VMAs, which are not handled under per-VMA lock.
However, once support for handling file-backed page faults with per-VMA
locks is added, this will become a race.

Fix this by write-locking the VMA before inserting it into the VMA tree.
Other places where a new VMA is added into VMA tree do not modify it
after the insertion, so do not need the same locking.

Cc: stable@vger.kernel.org
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/mmap.c

index c66e4622a55766d459278fd457bac65d4ad757b6..84c71431a5273830e40704dbc1a91ac79e21dda3 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2812,6 +2812,8 @@ cannot_expand:
        if (vma->vm_file)
                i_mmap_lock_write(vma->vm_file->f_mapping);
 
+       /* Lock the VMA since it is modified after insertion into VMA tree */
+       vma_start_write(vma);
        vma_iter_store(&vmi, vma);
        mm->map_count++;
        if (vma->vm_file) {