summaryrefslogtreecommitdiff
path: root/mm/mmap.c
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2013-02-22 16:32:46 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 17:50:11 -0800
commit1869305009857cdeaabe6283bcdc2359c5784543 (patch)
treea8a500c71e7aa3a645322635f3d591c16601af27 /mm/mmap.c
parentcea10a19b7972a1954c4a2d05a7de8db48b444fb (diff)
downloadkernel-common-1869305009857cdeaabe6283bcdc2359c5784543.tar.gz
kernel-common-1869305009857cdeaabe6283bcdc2359c5784543.tar.bz2
kernel-common-1869305009857cdeaabe6283bcdc2359c5784543.zip
mm: introduce VM_POPULATE flag to better deal with racy userspace programs
The vm_populate() code populates user mappings without constantly holding the mmap_sem. This makes it susceptible to racy userspace programs: the user mappings may change while vm_populate() is running, and in this case vm_populate() may end up populating the new mapping instead of the old one. In order to reduce the possibility of userspace getting surprised by this behavior, this change introduces the VM_POPULATE vma flag which gets set on vmas we want vm_populate() to work on. This way vm_populate() may still end up populating the new mapping after such a race, but only if the new mapping is also one that the user has requested (using MAP_SHARED, MAP_LOCKED or mlock) to be populated. Signed-off-by: Michel Lespinasse <walken@google.com> Acked-by: Rik van Riel <riel@redhat.com> Tested-by: Andy Lutomirski <luto@amacapital.net> Cc: Greg Ungerer <gregungerer@westnet.com.au> Cc: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c4
1 files changed, 1 insertions, 3 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 8826c77513a9..39a3944e1658 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1306,9 +1306,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
}
addr = mmap_region(file, addr, len, vm_flags, pgoff);
- if (!IS_ERR_VALUE(addr) &&
- ((vm_flags & VM_LOCKED) ||
- (flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE))
+ if (!IS_ERR_VALUE(addr) && (vm_flags & VM_POPULATE))
*populate = true;
return addr;
}