Fix the race between the truncation of a ramfs file and an attempt to make
a shared mmap of region of that file.
The problem is that do_mmap_pgoff() calls f_op->get_unmapped_area() to
verify that the file region is made of contiguous pages and to find its
base address - but there isn't any locking to guarantee this region until
vma_prio_tree_insert() is called by add_vma_to_mm().
Note that moving the functionality into f_op->mmap() doesn't help as that
is also called before vma_prio_tree_insert().
Instead make ramfs_nommu_check_mappings() grab nommu_region_sem whilst it
does its checks. This means that this function will wait whilst mmaps
take place.
Signed-off-by: David Howells <[email protected]>
Acked-by: Al Viro <[email protected]>
Cc: Greg Ungerer <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
struct vm_area_struct *vma;
struct prio_tree_iter iter;
+ down_write(&nommu_region_sem);
+
/* search for VMAs that fall within the dead zone */
vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
newsize >> PAGE_SHIFT,
) {
/* found one - only interested if it's shared out of the page
* cache */
- if (vma->vm_flags & VM_SHARED)
+ if (vma->vm_flags & VM_SHARED) {
+ up_write(&nommu_region_sem);
return -ETXTBSY; /* not quite true, but near enough */
+ }
}
+ up_write(&nommu_region_sem);
return 0;
}