Commit 84d96d897671cfb386e722acbefdb3a79e115a8a

Authored by Rasmus Villemoes
Committed by Linus Torvalds
1 parent 4edd7ceff0

mm: madvise: complete input validation before taking lock

In madvise(), there doesn't seem to be any reason for taking the
&current->mm->mmap_sem before start and len_in have been validated.
Incidentally, this removes the need for the out: label.

[akpm@linux-foundation.org: s/out_plug/out/, per David]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 15 additions and 16 deletions Side-by-side Diff

... ... @@ -473,28 +473,28 @@
473 473 if (!madvise_behavior_valid(behavior))
474 474 return error;
475 475  
476   - write = madvise_need_mmap_write(behavior);
477   - if (write)
478   - down_write(&current->mm->mmap_sem);
479   - else
480   - down_read(&current->mm->mmap_sem);
481   -
482 476 if (start & ~PAGE_MASK)
483   - goto out;
  477 + return error;
484 478 len = (len_in + ~PAGE_MASK) & PAGE_MASK;
485 479  
486 480 /* Check to see whether len was rounded up from small -ve to zero */
487 481 if (len_in && !len)
488   - goto out;
  482 + return error;
489 483  
490 484 end = start + len;
491 485 if (end < start)
492   - goto out;
  486 + return error;
493 487  
494 488 error = 0;
495 489 if (end == start)
496   - goto out;
  490 + return error;
497 491  
  492 + write = madvise_need_mmap_write(behavior);
  493 + if (write)
  494 + down_write(&current->mm->mmap_sem);
  495 + else
  496 + down_read(&current->mm->mmap_sem);
  497 +
498 498 /*
499 499 * If the interval [start,end) covers some unmapped address
500 500 * ranges, just ignore them, but return -ENOMEM at the end.
501 501  
... ... @@ -509,14 +509,14 @@
509 509 /* Still start < end. */
510 510 error = -ENOMEM;
511 511 if (!vma)
512   - goto out_plug;
  512 + goto out;
513 513  
514 514 /* Here start < (end|vma->vm_end). */
515 515 if (start < vma->vm_start) {
516 516 unmapped_error = -ENOMEM;
517 517 start = vma->vm_start;
518 518 if (start >= end)
519   - goto out_plug;
  519 + goto out;
520 520 }
521 521  
522 522 /* Here vma->vm_start <= start < (end|vma->vm_end) */
523 523  
524 524  
525 525  
... ... @@ -527,21 +527,20 @@
527 527 /* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */
528 528 error = madvise_vma(vma, &prev, start, tmp, behavior);
529 529 if (error)
530   - goto out_plug;
  530 + goto out;
531 531 start = tmp;
532 532 if (prev && start < prev->vm_end)
533 533 start = prev->vm_end;
534 534 error = unmapped_error;
535 535 if (start >= end)
536   - goto out_plug;
  536 + goto out;
537 537 if (prev)
538 538 vma = prev->vm_next;
539 539 else /* madvise_remove dropped mmap_sem */
540 540 vma = find_vma(current->mm, start);
541 541 }
542   -out_plug:
543   - blk_finish_plug(&plug);
544 542 out:
  543 + blk_finish_plug(&plug);
545 544 if (write)
546 545 up_write(&current->mm->mmap_sem);
547 546 else