Merge git://git.kernel.org/pub/scm/linux/kernel/git/viro/mmap
* git://git.kernel.org/pub/scm/linux/kernel/git/viro/mmap: Add missing alignment check in arch/score sys_mmap() fix broken aliasing checks for MAP_FIXED on sparc32, mips, arm and sh Get rid of open-coding in ia64_brk() sparc_brk() is not needed anymore switch do_brk() to get_unmapped_area() Take arch_mmap_check() into get_unmapped_area() fix a struct file leak in do_mmap_pgoff() Unify sys_mmap* Cut hugetlb case early for 32bit on ia64 arch_mmap_check() on mn10300 Kill ancient crap in s390 compat mmap arm: add arch_mmap_check(), get rid of sys_arm_mremap() file ->get_unmapped_area() shouldn't duplicate work of get_unmapped_area() kill useless checks in sparc mremap variants fix pgoff in "have to relocate" case of mremap() fix the arch checks in MREMAP_FIXED case fix checks for expand-in-place mremap do_mremap() untangling, part 3 do_mremap() untangling, part 2 untangling do_mremap(), part 1
This commit is contained in:
@@ -564,28 +564,6 @@ asmlinkage long sparc32_open(const char __user *filename,
|
||||
return do_sys_open(AT_FDCWD, filename, flags, mode);
|
||||
}
|
||||
|
||||
extern unsigned long do_mremap(unsigned long addr,
|
||||
unsigned long old_len, unsigned long new_len,
|
||||
unsigned long flags, unsigned long new_addr);
|
||||
|
||||
asmlinkage unsigned long sys32_mremap(unsigned long addr,
|
||||
unsigned long old_len, unsigned long new_len,
|
||||
unsigned long flags, u32 __new_addr)
|
||||
{
|
||||
unsigned long ret = -EINVAL;
|
||||
unsigned long new_addr = __new_addr;
|
||||
|
||||
if (unlikely(sparc_mmap_check(addr, old_len)))
|
||||
goto out;
|
||||
if (unlikely(sparc_mmap_check(new_addr, new_len)))
|
||||
goto out;
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
long sys32_lookup_dcookie(unsigned long cookie_high,
|
||||
unsigned long cookie_low,
|
||||
char __user *buf, size_t len)
|
||||
|
||||
@@ -45,7 +45,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
|
||||
/* We do not accept a shared mapping if it would violate
|
||||
* cache aliasing constraints.
|
||||
*/
|
||||
if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
|
||||
if ((flags & MAP_SHARED) &&
|
||||
((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
|
||||
return -EINVAL;
|
||||
return addr;
|
||||
}
|
||||
@@ -79,15 +80,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage unsigned long sparc_brk(unsigned long brk)
|
||||
{
|
||||
if(ARCH_SUN4C) {
|
||||
if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000))
|
||||
return current->mm->brk;
|
||||
}
|
||||
return sys_brk(brk);
|
||||
}
|
||||
|
||||
/*
|
||||
* sys_pipe() is the normal C calling standard for creating
|
||||
* a pipe. It's not the way unix traditionally does this, though.
|
||||
@@ -234,31 +226,6 @@ int sparc_mmap_check(unsigned long addr, unsigned long len)
|
||||
}
|
||||
|
||||
/* Linux version of mmap */
|
||||
static unsigned long do_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags, unsigned long fd,
|
||||
unsigned long pgoff)
|
||||
{
|
||||
struct file * file = NULL;
|
||||
unsigned long retval = -EBADF;
|
||||
|
||||
if (!(flags & MAP_ANONYMOUS)) {
|
||||
file = fget(fd);
|
||||
if (!file)
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = PAGE_ALIGN(len);
|
||||
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
if (file)
|
||||
fput(file);
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags, unsigned long fd,
|
||||
@@ -266,14 +233,16 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
{
|
||||
/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
|
||||
we have. */
|
||||
return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
|
||||
return sys_mmap_pgoff(addr, len, prot, flags, fd,
|
||||
pgoff >> (PAGE_SHIFT - 12));
|
||||
}
|
||||
|
||||
asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags, unsigned long fd,
|
||||
unsigned long off)
|
||||
{
|
||||
return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
|
||||
/* no alignment check? */
|
||||
return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
long sparc_remap_file_pages(unsigned long start, unsigned long size,
|
||||
@@ -287,27 +256,6 @@ long sparc_remap_file_pages(unsigned long start, unsigned long size,
|
||||
(pgoff >> (PAGE_SHIFT - 12)), flags);
|
||||
}
|
||||
|
||||
extern unsigned long do_mremap(unsigned long addr,
|
||||
unsigned long old_len, unsigned long new_len,
|
||||
unsigned long flags, unsigned long new_addr);
|
||||
|
||||
asmlinkage unsigned long sparc_mremap(unsigned long addr,
|
||||
unsigned long old_len, unsigned long new_len,
|
||||
unsigned long flags, unsigned long new_addr)
|
||||
{
|
||||
unsigned long ret = -EINVAL;
|
||||
|
||||
if (unlikely(sparc_mmap_check(addr, old_len)))
|
||||
goto out;
|
||||
if (unlikely(sparc_mmap_check(new_addr, new_len)))
|
||||
goto out;
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* we come to here via sys_nis_syscall so it can setup the regs argument */
|
||||
asmlinkage unsigned long
|
||||
c_sys_nis_syscall (struct pt_regs *regs)
|
||||
|
||||
@@ -317,10 +317,14 @@ bottomup:
|
||||
unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
unsigned long align_goal, addr = -ENOMEM;
|
||||
unsigned long (*get_area)(struct file *, unsigned long,
|
||||
unsigned long, unsigned long, unsigned long);
|
||||
|
||||
get_area = current->mm->get_unmapped_area;
|
||||
|
||||
if (flags & MAP_FIXED) {
|
||||
/* Ok, don't mess with it. */
|
||||
return get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
|
||||
return get_area(NULL, orig_addr, len, pgoff, flags);
|
||||
}
|
||||
flags &= ~MAP_SHARED;
|
||||
|
||||
@@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
|
||||
align_goal = (64UL * 1024);
|
||||
|
||||
do {
|
||||
addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
|
||||
addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
|
||||
if (!(addr & ~PAGE_MASK)) {
|
||||
addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
|
||||
break;
|
||||
@@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
|
||||
* be obtained.
|
||||
*/
|
||||
if (addr & ~PAGE_MASK)
|
||||
addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
|
||||
addr = get_area(NULL, orig_addr, len, pgoff, flags);
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -399,18 +403,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
|
||||
}
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE1(sparc_brk, unsigned long, brk)
|
||||
{
|
||||
/* People could try to be nasty and use ta 0x6d in 32bit programs */
|
||||
if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32)
|
||||
return current->mm->brk;
|
||||
|
||||
if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk)))
|
||||
return current->mm->brk;
|
||||
|
||||
return sys_brk(brk);
|
||||
}
|
||||
|
||||
/*
|
||||
* sys_pipe() is the normal C calling standard for creating
|
||||
* a pipe. It's not the way unix traditionally does this, though.
|
||||
@@ -568,23 +560,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
|
||||
unsigned long, prot, unsigned long, flags, unsigned long, fd,
|
||||
unsigned long, off)
|
||||
{
|
||||
struct file * file = NULL;
|
||||
unsigned long retval = -EBADF;
|
||||
unsigned long retval = -EINVAL;
|
||||
|
||||
if (!(flags & MAP_ANONYMOUS)) {
|
||||
file = fget(fd);
|
||||
if (!file)
|
||||
goto out;
|
||||
}
|
||||
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
len = PAGE_ALIGN(len);
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
retval = do_mmap(file, addr, len, prot, flags, off);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
if (file)
|
||||
fput(file);
|
||||
if ((off + PAGE_ALIGN(len)) < off)
|
||||
goto out;
|
||||
if (off & ~PAGE_MASK)
|
||||
goto out;
|
||||
retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
@@ -614,12 +596,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len,
|
||||
|
||||
if (test_thread_flag(TIF_32BIT))
|
||||
goto out;
|
||||
if (unlikely(new_len >= VA_EXCLUDE_START))
|
||||
goto out;
|
||||
if (unlikely(sparc_mmap_check(addr, old_len)))
|
||||
goto out;
|
||||
if (unlikely(sparc_mmap_check(new_addr, new_len)))
|
||||
goto out;
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
struct new_utsname;
|
||||
|
||||
extern asmlinkage unsigned long sys_getpagesize(void);
|
||||
extern asmlinkage unsigned long sparc_brk(unsigned long brk);
|
||||
extern asmlinkage long sparc_pipe(struct pt_regs *regs);
|
||||
extern asmlinkage long sys_ipc(unsigned int call, int first,
|
||||
unsigned long second,
|
||||
|
||||
@@ -19,7 +19,7 @@ sys_call_table:
|
||||
/*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write
|
||||
/*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link
|
||||
/*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod
|
||||
/*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek
|
||||
/*15*/ .long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek
|
||||
/*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
|
||||
/*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause
|
||||
/*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
|
||||
@@ -67,7 +67,7 @@ sys_call_table:
|
||||
/*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
|
||||
/*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
|
||||
/*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
|
||||
/*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
|
||||
/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
|
||||
/*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
|
||||
/*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
|
||||
/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
|
||||
|
||||
@@ -21,7 +21,7 @@ sys_call_table32:
|
||||
/*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write
|
||||
/*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link
|
||||
/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
|
||||
/*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek
|
||||
/*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek
|
||||
/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
|
||||
/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
|
||||
/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
|
||||
@@ -68,7 +68,7 @@ sys_call_table32:
|
||||
.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall
|
||||
/*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
|
||||
.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
|
||||
/*250*/ .word sys32_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
|
||||
/*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
|
||||
.word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
|
||||
/*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
|
||||
.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
|
||||
@@ -96,7 +96,7 @@ sys_call_table:
|
||||
/*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
|
||||
/*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link
|
||||
/*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
|
||||
/*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek
|
||||
/*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek
|
||||
/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
|
||||
/*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
|
||||
/*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
|
||||
|
||||
Reference in New Issue
Block a user