Commit 84d96d897671cfb386e722acbefdb3a79e115a8a
Committed by
Linus Torvalds
1 parent
4edd7ceff0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
mm: madvise: complete input validation before taking lock
In madvise(), there doesn't seem to be any reason for taking the ¤t->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
mm/madvise.c
... | ... | @@ -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(¤t->mm->mmap_sem); | |
479 | - else | |
480 | - down_read(¤t->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(¤t->mm->mmap_sem); | |
495 | + else | |
496 | + down_read(¤t->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(¤t->mm->mmap_sem); |
547 | 546 | else |