nommu: fix race between ramfs truncation and shared mmap
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 <dhowells@redhat.com> Acked-by: Al Viro <viro@zeniv.linux.org.uk> Cc: Greg Ungerer <gerg@snapgear.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
efc1a3b169
commit
81759b5b22
|
@ -131,6 +131,8 @@ static int ramfs_nommu_check_mappings(struct inode *inode,
|
|||
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,
|
||||
|
@ -138,10 +140,13 @@ static int ramfs_nommu_check_mappings(struct inode *inode,
|
|||
) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue