aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorRasmus Villemoes <linux@rasmusvillemoes.dk>2013-07-08 18:59:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 13:33:20 -0400
commit9a2458a633d4b3c9e0eae506da40cf44dc075314 (patch)
tree6212adc65070486edc212587c8f3a16452d810ec /mm
parent34e3a58c66aafd90cc16c061569fbefc3ff451e9 (diff)
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>
Diffstat (limited to 'mm')
-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,
456 unsigned long charged = 0; 456 unsigned long charged = 0;
457 bool locked = false; 457 bool locked = false;
458 458
459 down_write(&current->mm->mmap_sem);
460
461 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) 459 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
462 goto out; 460 return ret;
461
462 if (flags & MREMAP_FIXED && !(flags & MREMAP_MAYMOVE))
463 return ret;
463 464
464 if (addr & ~PAGE_MASK) 465 if (addr & ~PAGE_MASK)
465 goto out; 466 return ret;
466 467
467 old_len = PAGE_ALIGN(old_len); 468 old_len = PAGE_ALIGN(old_len);
468 new_len = PAGE_ALIGN(new_len); 469 new_len = PAGE_ALIGN(new_len);
@@ -473,12 +474,13 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
473 * a zero new-len is nonsensical. 474 * a zero new-len is nonsensical.
474 */ 475 */
475 if (!new_len) 476 if (!new_len)
476 goto out; 477 return ret;
478
479 down_write(&current->mm->mmap_sem);
477 480
478 if (flags & MREMAP_FIXED) { 481 if (flags & MREMAP_FIXED) {
479 if (flags & MREMAP_MAYMOVE) 482 ret = mremap_to(addr, old_len, new_addr, new_len,
480 ret = mremap_to(addr, old_len, new_addr, new_len, 483 &locked);
481 &locked);
482 goto out; 484 goto out;
483 } 485 }
484 486