Skip to content

Commit

Permalink
nommu: fix race between ramfs truncation and shared mmap
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dhowells authored and torvalds committed Jan 16, 2010
1 parent efc1a3b commit 81759b5
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion fs/ramfs/file-nommu.c
Expand Up @@ -131,17 +131,22 @@ 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,
(size + PAGE_SIZE - 1) >> 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;
}

Expand Down

0 comments on commit 81759b5

Please sign in to comment.