summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Villemoes <linux@rasmusvillemoes.dk>2013-07-08 15:59:48 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 10:33:20 -0700
commit9a2458a633d4b3c9e0eae506da40cf44dc075314 (patch)
tree6212adc65070486edc212587c8f3a16452d810ec
parent34e3a58c66aafd90cc16c061569fbefc3ff451e9 (diff)
downloadlwn-9a2458a633d4b3c9e0eae506da40cf44dc075314.tar.gz
lwn-9a2458a633d4b3c9e0eae506da40cf44dc075314.zip
mm: mremap: validate input before taking lock
This patch is very similar to commit 84d96d897671 ("mm: madvise: complete input validation before taking lock"): perform some basic validation of the input to mremap() before taking the &current->mm->mmap_sem lock. This also makes the MREMAP_FIXED => MREMAP_MAYMOVE dependency slightly more explicit. Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/mremap.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/mm/mremap.c b/mm/mremap.c
index 3708655378e9..457d34ef3bf2 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -456,13 +456,14 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
unsigned long charged = 0;
bool locked = false;
- down_write(&current->mm->mmap_sem);
-
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
- goto out;
+ return ret;
+
+ if (flags & MREMAP_FIXED && !(flags & MREMAP_MAYMOVE))
+ return ret;
if (addr & ~PAGE_MASK)
- goto out;
+ return ret;
old_len = PAGE_ALIGN(old_len);
new_len = PAGE_ALIGN(new_len);
@@ -473,12 +474,13 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
* a zero new-len is nonsensical.
*/
if (!new_len)
- goto out;
+ return ret;
+
+ down_write(&current->mm->mmap_sem);
if (flags & MREMAP_FIXED) {
- if (flags & MREMAP_MAYMOVE)
- ret = mremap_to(addr, old_len, new_addr, new_len,
- &locked);
+ ret = mremap_to(addr, old_len, new_addr, new_len,
+ &locked);
goto out;
}