aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-05-12 19:33:33 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-12 19:33:33 -0400
commit94d149c34cda933ff5096aca94bb23bf68602f4e (patch)
tree2c1a33482cd6961b45296979b898881a7a4d71d3 /arch/sparc64
parentc714a534d85576af21b06be605ca55cb2fb887ee (diff)
sparc: Fix mremap address range validation.
Just like mmap, we need to validate address ranges regardless of MAP_FIXED. sparc{,64}_mmap_check()'s flag argument is unused, remove. Based upon a report and preliminary patch by Jan Lieskovsky <jlieskov@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/sys_sparc.c36
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c33
2 files changed, 6 insertions, 63 deletions
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 0dbc941f130e..ac1bff58c1ac 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -542,8 +542,7 @@ asmlinkage long sparc64_personality(unsigned long personality)
542 return ret; 542 return ret;
543} 543}
544 544
545int sparc64_mmap_check(unsigned long addr, unsigned long len, 545int sparc64_mmap_check(unsigned long addr, unsigned long len)
546 unsigned long flags)
547{ 546{
548 if (test_thread_flag(TIF_32BIT)) { 547 if (test_thread_flag(TIF_32BIT)) {
549 if (len >= STACK_TOP32) 548 if (len >= STACK_TOP32)
@@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
609 unsigned long old_len, unsigned long new_len, 608 unsigned long old_len, unsigned long new_len,
610 unsigned long flags, unsigned long new_addr) 609 unsigned long flags, unsigned long new_addr)
611{ 610{
612 struct vm_area_struct *vma;
613 unsigned long ret = -EINVAL; 611 unsigned long ret = -EINVAL;
614 612
615 if (test_thread_flag(TIF_32BIT)) 613 if (test_thread_flag(TIF_32BIT))
616 goto out; 614 goto out;
617 if (unlikely(new_len >= VA_EXCLUDE_START)) 615 if (unlikely(new_len >= VA_EXCLUDE_START))
618 goto out; 616 goto out;
619 if (unlikely(invalid_64bit_range(addr, old_len))) 617 if (unlikely(sparc64_mmap_check(addr, old_len)))
618 goto out;
619 if (unlikely(sparc64_mmap_check(new_addr, new_len)))
620 goto out; 620 goto out;
621 621
622 down_write(&current->mm->mmap_sem); 622 down_write(&current->mm->mmap_sem);
623 if (flags & MREMAP_FIXED) {
624 if (invalid_64bit_range(new_addr, new_len))
625 goto out_sem;
626 } else if (invalid_64bit_range(addr, new_len)) {
627 unsigned long map_flags = 0;
628 struct file *file = NULL;
629
630 ret = -ENOMEM;
631 if (!(flags & MREMAP_MAYMOVE))
632 goto out_sem;
633
634 vma = find_vma(current->mm, addr);
635 if (vma) {
636 if (vma->vm_flags & VM_SHARED)
637 map_flags |= MAP_SHARED;
638 file = vma->vm_file;
639 }
640
641 /* MREMAP_FIXED checked above. */
642 new_addr = get_unmapped_area(file, addr, new_len,
643 vma ? vma->vm_pgoff : 0,
644 map_flags);
645 ret = new_addr;
646 if (new_addr & ~PAGE_MASK)
647 goto out_sem;
648 flags |= MREMAP_FIXED;
649 }
650 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 623 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
651out_sem:
652 up_write(&current->mm->mmap_sem); 624 up_write(&current->mm->mmap_sem);
653out: 625out:
654 return ret; 626 return ret;
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 1aa4288125f2..ba5bd626b39e 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -867,44 +867,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
867 unsigned long old_len, unsigned long new_len, 867 unsigned long old_len, unsigned long new_len,
868 unsigned long flags, u32 __new_addr) 868 unsigned long flags, u32 __new_addr)
869{ 869{
870 struct vm_area_struct *vma;
871 unsigned long ret = -EINVAL; 870 unsigned long ret = -EINVAL;
872 unsigned long new_addr = __new_addr; 871 unsigned long new_addr = __new_addr;
873 872
874 if (old_len > STACK_TOP32 || new_len > STACK_TOP32) 873 if (unlikely(sparc64_mmap_check(addr, old_len)))
875 goto out; 874 goto out;
876 if (addr > STACK_TOP32 - old_len) 875 if (unlikely(sparc64_mmap_check(new_addr, new_len)))
877 goto out; 876 goto out;
878 down_write(&current->mm->mmap_sem); 877 down_write(&current->mm->mmap_sem);
879 if (flags & MREMAP_FIXED) {
880 if (new_addr > STACK_TOP32 - new_len)
881 goto out_sem;
882 } else if (addr > STACK_TOP32 - new_len) {
883 unsigned long map_flags = 0;
884 struct file *file = NULL;
885
886 ret = -ENOMEM;
887 if (!(flags & MREMAP_MAYMOVE))
888 goto out_sem;
889
890 vma = find_vma(current->mm, addr);
891 if (vma) {
892 if (vma->vm_flags & VM_SHARED)
893 map_flags |= MAP_SHARED;
894 file = vma->vm_file;
895 }
896
897 /* MREMAP_FIXED checked above. */
898 new_addr = get_unmapped_area(file, addr, new_len,
899 vma ? vma->vm_pgoff : 0,
900 map_flags);
901 ret = new_addr;
902 if (new_addr & ~PAGE_MASK)
903 goto out_sem;
904 flags |= MREMAP_FIXED;
905 }
906 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 878 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
907out_sem:
908 up_write(&current->mm->mmap_sem); 879 up_write(&current->mm->mmap_sem);
909out: 880out:
910 return ret; 881 return ret;