[kernel] r15044 - in dists/lenny-security/linux-2.6/debian: . patches/bugfix/all patches/features/all/openvz patches/features/all/vserver patches/series
Dann Frazier
dannf at alioth.debian.org
Wed Jan 27 16:52:32 UTC 2010
Author: dannf
Date: Wed Jan 27 16:52:30 2010
New Revision: 15044
Log:
* Fix several issues with mmap/mremap (CVE-2010-0291)
Added:
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/untangle-the-do_mremap-mess.patch
Modified:
dists/lenny-security/linux-2.6/debian/changelog
dists/lenny-security/linux-2.6/debian/patches/features/all/openvz/openvz.patch
dists/lenny-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.35.patch
dists/lenny-security/linux-2.6/debian/patches/series/21lenny1
Modified: dists/lenny-security/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny-security/linux-2.6/debian/changelog Wed Jan 27 16:35:55 2010 (r15043)
+++ dists/lenny-security/linux-2.6/debian/changelog Wed Jan 27 16:52:30 2010 (r15044)
@@ -4,6 +4,7 @@
* mac80211: fix spurious delBA handling (CVE-2009-4027)
* e1000: enhance frame fragment detection (CVE-2009-4536)
* e1000e: enhance frame fragment detection (CVE-2009-4538)
+ * Fix several issues with mmap/mremap (CVE-2010-0291)
[ Ben Hutchings ]
* kernel/signal.c: fix kernel information leak with print-fatal-signals=1
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/untangle-the-do_mremap-mess.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/untangle-the-do_mremap-mess.patch Wed Jan 27 16:52:30 2010 (r15044)
@@ -0,0 +1,2321 @@
+diff -urpN linux-source-2.6.26.orig/arch/alpha/kernel/osf_sys.c linux-source-2.6.26/arch/alpha/kernel/osf_sys.c
+--- linux-source-2.6.26.orig/arch/alpha/kernel/osf_sys.c 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/arch/alpha/kernel/osf_sys.c 2010-01-22 17:15:05.000000000 -0700
+@@ -178,25 +178,18 @@ SYSCALL_DEFINE6(osf_mmap, unsigned long,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, off)
+ {
+- struct file *file = NULL;
+- unsigned long ret = -EBADF;
++ unsigned long ret = -EINVAL;
+
+ #if 0
+ if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
+ printk("%s: unimplemented OSF mmap flags %04lx\n",
+ current->comm, flags);
+ #endif
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- down_write(¤t->mm->mmap_sem);
+- ret = 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;
++ ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+ out:
+ return ret;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/arm/kernel/calls.S linux-source-2.6.26/arch/arm/kernel/calls.S
+--- linux-source-2.6.26.orig/arch/arm/kernel/calls.S 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/arm/kernel/calls.S 2010-01-22 17:15:05.000000000 -0700
+@@ -172,7 +172,7 @@
+ /* 160 */ CALL(sys_sched_get_priority_min)
+ CALL(sys_sched_rr_get_interval)
+ CALL(sys_nanosleep)
+- CALL(sys_arm_mremap)
++ CALL(sys_mremap)
+ CALL(sys_setresuid16)
+ /* 165 */ CALL(sys_getresuid16)
+ CALL(sys_ni_syscall) /* vm86 */
+diff -urpN linux-source-2.6.26.orig/arch/arm/kernel/entry-common.S linux-source-2.6.26/arch/arm/kernel/entry-common.S
+--- linux-source-2.6.26.orig/arch/arm/kernel/entry-common.S 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/arm/kernel/entry-common.S 2010-01-22 17:15:05.000000000 -0700
+@@ -344,12 +344,12 @@ sys_mmap2:
+ tst r5, #PGOFF_MASK
+ moveq r5, r5, lsr #PAGE_SHIFT - 12
+ streq r5, [sp, #4]
+- beq do_mmap2
++ beq sys_mmap_pgoff
+ mov r0, #-EINVAL
+ mov pc, lr
+ #else
+ str r5, [sp, #4]
+- b do_mmap2
++ b sys_mmap_pgoff
+ #endif
+
+ ENTRY(pabort_ifar)
+diff -urpN linux-source-2.6.26.orig/arch/arm/kernel/sys_arm.c linux-source-2.6.26/arch/arm/kernel/sys_arm.c
+--- linux-source-2.6.26.orig/arch/arm/kernel/sys_arm.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/arm/kernel/sys_arm.c 2010-01-22 17:15:05.000000000 -0700
+@@ -30,41 +30,6 @@
+
+ #include <asm/uaccess.h>
+
+-extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
+- unsigned long new_len, unsigned long flags,
+- unsigned long new_addr);
+-
+-/* common code for old and new mmaps */
+-inline long do_mmap2(
+- unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EINVAL;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS)
+- goto out;
+-
+- error = -EBADF;
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ struct mmap_arg_struct {
+ unsigned long addr;
+ unsigned long len;
+@@ -86,29 +51,11 @@ asmlinkage int old_mmap(struct mmap_arg_
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+
+-asmlinkage unsigned long
+-sys_arm_mremap(unsigned long addr, unsigned long old_len,
+- unsigned long new_len, unsigned long flags,
+- unsigned long new_addr)
+-{
+- unsigned long ret = -EINVAL;
+-
+- if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
+- 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;
+-}
+-
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls.
+diff -urpN linux-source-2.6.26.orig/arch/arm/mm/mmap.c linux-source-2.6.26/arch/arm/mm/mmap.c
+--- linux-source-2.6.26.orig/arch/arm/mm/mmap.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/arm/mm/mmap.c 2010-01-22 17:15:05.000000000 -0700
+@@ -52,7 +52,8 @@ arch_get_unmapped_area(struct file *filp
+ * We enforce the MAP_FIXED case.
+ */
+ if (flags & MAP_FIXED) {
+- if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1))
++ if (aliasing && flags & MAP_SHARED &&
++ (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+ return -EINVAL;
+ return addr;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/avr32/kernel/sys_avr32.c linux-source-2.6.26/arch/avr32/kernel/sys_avr32.c
+--- linux-source-2.6.26.orig/arch/avr32/kernel/sys_avr32.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/avr32/kernel/sys_avr32.c 2010-01-24 23:11:18.000000000 -0700
+@@ -5,38 +5,8 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+-#include <linux/errno.h>
+-#include <linux/fs.h>
+-#include <linux/file.h>
+-#include <linux/mm.h>
+ #include <linux/unistd.h>
+
+-#include <asm/mman.h>
+-#include <asm/uaccess.h>
+-
+-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, off_t offset)
+-{
+- int error = -EBADF;
+- struct file *file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- return error;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, offset);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+- return error;
+-}
+-
+ int kernel_execve(const char *file, char **argv, char **envp)
+ {
+ register long scno asm("r8") = __NR_execve;
+diff -urpN linux-source-2.6.26.orig/arch/avr32/kernel/syscall-stubs.S linux-source-2.6.26/arch/avr32/kernel/syscall-stubs.S
+--- linux-source-2.6.26.orig/arch/avr32/kernel/syscall-stubs.S 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/avr32/kernel/syscall-stubs.S 2010-01-24 23:11:51.000000000 -0700
+@@ -61,7 +61,7 @@ __sys_execve:
+ __sys_mmap2:
+ pushm lr
+ st.w --sp, ARG6
+- rcall sys_mmap2
++ call sys_mmap_pgoff
+ sub sp, -4
+ popm pc
+
+diff -urpN linux-source-2.6.26.orig/arch/blackfin/kernel/sys_bfin.c linux-source-2.6.26/arch/blackfin/kernel/sys_bfin.c
+--- linux-source-2.6.26.orig/arch/blackfin/kernel/sys_bfin.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/blackfin/kernel/sys_bfin.c 2010-01-24 23:12:46.000000000 -0700
+@@ -45,39 +45,6 @@
+ #include <asm/cacheflush.h>
+ #include <asm/dma.h>
+
+-/* common code for old and new mmaps */
+-static inline long
+-do_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file *file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+- out:
+- return error;
+-}
+-
+-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- return do_mmap2(addr, len, prot, flags, fd, pgoff);
+-}
+-
+ asmlinkage int sys_getpagesize(void)
+ {
+ return PAGE_SIZE;
+diff -urpN linux-source-2.6.26.orig/arch/blackfin/mach-common/entry.S linux-source-2.6.26/arch/blackfin/mach-common/entry.S
+--- linux-source-2.6.26.orig/arch/blackfin/mach-common/entry.S 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/blackfin/mach-common/entry.S 2010-01-22 17:15:08.000000000 -0700
+@@ -1220,7 +1220,7 @@ ENTRY(_sys_call_table)
+ .long _sys_ni_syscall /* streams2 */
+ .long _sys_vfork /* 190 */
+ .long _sys_getrlimit
+- .long _sys_mmap2
++ .long _sys_mmap_pgoff
+ .long _sys_truncate64
+ .long _sys_ftruncate64
+ .long _sys_stat64 /* 195 */
+diff -urpN linux-source-2.6.26.orig/arch/cris/kernel/sys_cris.c linux-source-2.6.26/arch/cris/kernel/sys_cris.c
+--- linux-source-2.6.26.orig/arch/cris/kernel/sys_cris.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/cris/kernel/sys_cris.c 2010-01-22 17:15:08.000000000 -0700
+@@ -27,31 +27,6 @@
+ #include <asm/uaccess.h>
+ #include <asm/segment.h>
+
+-/* common code for old and new mmaps */
+-static inline long
+-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+- unsigned long flags, unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ asmlinkage unsigned long old_mmap(unsigned long __user *args)
+ {
+ unsigned long buffer[6];
+@@ -64,7 +39,7 @@ asmlinkage unsigned long old_mmap(unsign
+ if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
+ goto out;
+
+- err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3],
++ err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3],
+ buffer[4], buffer[5] >> PAGE_SHIFT);
+ out:
+ return err;
+@@ -74,7 +49,8 @@ asmlinkage long
+ sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long pgoff)
+ {
+- return do_mmap2(addr, len, prot, flags, fd, pgoff);
++ /* bug(?): 8Kb pages here */
++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
+ }
+
+ /*
+diff -urpN linux-source-2.6.26.orig/arch/frv/kernel/sys_frv.c linux-source-2.6.26/arch/frv/kernel/sys_frv.c
+--- linux-source-2.6.26.orig/arch/frv/kernel/sys_frv.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/frv/kernel/sys_frv.c 2010-01-24 23:15:23.000000000 -0700
+@@ -32,16 +32,6 @@ asmlinkage long sys_mmap2(unsigned long
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+ {
+- int error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+ /* As with sparc32, make sure the shift for mmap2 is constant
+ (12), no matter what PAGE_SIZE we have.... */
+
+@@ -50,62 +40,9 @@ asmlinkage long sys_mmap2(unsigned long
+ if (pgoff & ((1<<(PAGE_SHIFT-12))-1))
+ return -EINVAL;
+
+- pgoff >>= (PAGE_SHIFT - 12);
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+-#if 0 /* DAVIDM - do we want this */
+-struct mmap_arg_struct64 {
+- __u32 addr;
+- __u32 len;
+- __u32 prot;
+- __u32 flags;
+- __u64 offset; /* 64 bits */
+- __u32 fd;
+-};
+-
+-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+-{
+- int error = -EFAULT;
+- struct file * file = NULL;
+- struct mmap_arg_struct64 a;
+- unsigned long pgoff;
+-
+- if (copy_from_user(&a, arg, sizeof(a)))
+- return -EFAULT;
+-
+- if ((long)a.offset & ~PAGE_MASK)
+- return -EINVAL;
+-
+- pgoff = a.offset >> PAGE_SHIFT;
+- if ((a.offset >> PAGE_SHIFT) != pgoff)
+- return -EINVAL;
+-
+- if (!(a.flags & MAP_ANONYMOUS)) {
+- error = -EBADF;
+- file = fget(a.fd);
+- if (!file)
+- goto out;
+- }
+- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+- if (file)
+- fput(file);
+-out:
+- return error;
++ return sys_mmap_pgoff(addr, len, prot, flags, fd,
++ pgoff >> (PAGE_SHIFT - 12));
+ }
+-#endif
+
+ /*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+diff -urpN linux-source-2.6.26.orig/arch/h8300/kernel/syscalls.S linux-source-2.6.26/arch/h8300/kernel/syscalls.S
+--- linux-source-2.6.26.orig/arch/h8300/kernel/syscalls.S 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/h8300/kernel/syscalls.S 2010-01-22 17:15:08.000000000 -0700
+@@ -206,7 +206,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
+ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
+ .long SYMBOL_NAME(sys_vfork) /* 190 */
+ .long SYMBOL_NAME(sys_getrlimit)
+- .long SYMBOL_NAME(sys_mmap2)
++ .long SYMBOL_NAME(sys_mmap_pgoff)
+ .long SYMBOL_NAME(sys_truncate64)
+ .long SYMBOL_NAME(sys_ftruncate64)
+ .long SYMBOL_NAME(sys_stat64) /* 195 */
+diff -urpN linux-source-2.6.26.orig/arch/h8300/kernel/sys_h8300.c linux-source-2.6.26/arch/h8300/kernel/sys_h8300.c
+--- linux-source-2.6.26.orig/arch/h8300/kernel/sys_h8300.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/h8300/kernel/sys_h8300.c 2010-01-22 17:15:08.000000000 -0700
+@@ -27,39 +27,6 @@
+ #include <asm/traps.h>
+ #include <asm/unistd.h>
+
+-/* common code for old and new mmaps */
+-static inline long do_mmap2(
+- unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- return do_mmap2(addr, len, prot, flags, fd, pgoff);
+-}
+-
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+@@ -88,58 +55,12 @@ asmlinkage int old_mmap(struct mmap_arg_
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
++ a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+
+-#if 0 /* DAVIDM - do we want this */
+-struct mmap_arg_struct64 {
+- __u32 addr;
+- __u32 len;
+- __u32 prot;
+- __u32 flags;
+- __u64 offset; /* 64 bits */
+- __u32 fd;
+-};
+-
+-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+-{
+- int error = -EFAULT;
+- struct file * file = NULL;
+- struct mmap_arg_struct64 a;
+- unsigned long pgoff;
+-
+- if (copy_from_user(&a, arg, sizeof(a)))
+- return -EFAULT;
+-
+- if ((long)a.offset & ~PAGE_MASK)
+- return -EINVAL;
+-
+- pgoff = a.offset >> PAGE_SHIFT;
+- if ((a.offset >> PAGE_SHIFT) != pgoff)
+- return -EINVAL;
+-
+- if (!(a.flags & MAP_ANONYMOUS)) {
+- error = -EBADF;
+- file = fget(a.fd);
+- if (!file)
+- goto out;
+- }
+- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-#endif
+-
+ struct sel_arg_struct {
+ unsigned long n;
+ fd_set *inp, *outp, *exp;
+diff -urpN linux-source-2.6.26.orig/arch/ia64/ia32/sys_ia32.c linux-source-2.6.26/arch/ia64/ia32/sys_ia32.c
+--- linux-source-2.6.26.orig/arch/ia64/ia32/sys_ia32.c 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/ia64/ia32/sys_ia32.c 2010-01-22 17:15:08.000000000 -0700
+@@ -893,6 +893,9 @@ ia32_do_mmap (struct file *file, unsigne
+
+ prot = get_prot32(prot);
+
++ /*if (flags & MAP_HUGETLB)
++ return -ENOMEM;*/
++
+ #if PAGE_SHIFT > IA32_PAGE_SHIFT
+ mutex_lock(&ia32_mmap_mutex);
+ {
+diff -urpN linux-source-2.6.26.orig/arch/ia64/kernel/sys_ia64.c linux-source-2.6.26/arch/ia64/kernel/sys_ia64.c
+--- linux-source-2.6.26.orig/arch/ia64/kernel/sys_ia64.c 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/ia64/kernel/sys_ia64.c 2010-01-22 17:15:08.000000000 -0700
+@@ -100,51 +100,7 @@ sys_getpagesize (void)
+ asmlinkage unsigned long
+ ia64_brk (unsigned long brk)
+ {
+- unsigned long rlim, retval, newbrk, oldbrk;
+- struct mm_struct *mm = current->mm;
+-
+- /*
+- * Most of this replicates the code in sys_brk() except for an additional safety
+- * check and the clearing of r8. However, we can't call sys_brk() because we need
+- * to acquire the mmap_sem before we can do the test...
+- */
+- down_write(&mm->mmap_sem);
+-
+- if (brk < mm->end_code)
+- goto out;
+- newbrk = PAGE_ALIGN(brk);
+- oldbrk = PAGE_ALIGN(mm->brk);
+- if (oldbrk == newbrk)
+- goto set_brk;
+-
+- /* Always allow shrinking brk. */
+- if (brk <= mm->brk) {
+- if (!do_munmap(mm, newbrk, oldbrk-newbrk))
+- goto set_brk;
+- goto out;
+- }
+-
+- /* Check against unimplemented/unmapped addresses: */
+- if ((newbrk - oldbrk) > RGN_MAP_LIMIT || REGION_OFFSET(newbrk) > RGN_MAP_LIMIT)
+- goto out;
+-
+- /* Check against rlimit.. */
+- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+- if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
+- goto out;
+-
+- /* Check against existing mmap mappings. */
+- if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
+- goto out;
+-
+- /* Ok, looks good - let it rip. */
+- if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
+- goto out;
+-set_brk:
+- mm->brk = brk;
+-out:
+- retval = mm->brk;
+- up_write(&mm->mmap_sem);
++ unsigned long retval = sys_brk(brk);
+ force_successful_syscall_return();
+ return retval;
+ }
+@@ -185,39 +141,6 @@ int ia64_mmap_check(unsigned long addr,
+ return 0;
+ }
+
+-static inline unsigned long
+-do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
+-{
+- struct file *file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- return -EBADF;
+-
+- if (!file->f_op || !file->f_op->mmap) {
+- addr = -ENODEV;
+- goto out;
+- }
+- }
+-
+- /* Careful about overflows.. */
+- len = PAGE_ALIGN(len);
+- if (!len || len > TASK_SIZE) {
+- addr = -EINVAL;
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+-out: if (file)
+- fput(file);
+- return addr;
+-}
+-
+ /*
+ * mmap2() is like mmap() except that the offset is expressed in units
+ * of PAGE_SIZE (instead of bytes). This allows to mmap2() (pieces
+@@ -226,7 +149,7 @@ out: if (file)
+ asmlinkage unsigned long
+ sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
+ {
+- addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
++ addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
+ if (!IS_ERR((void *) addr))
+ force_successful_syscall_return();
+ return addr;
+@@ -238,7 +161,7 @@ sys_mmap (unsigned long addr, unsigned l
+ if (offset_in_page(off) != 0)
+ return -EINVAL;
+
+- addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
++ addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+ if (!IS_ERR((void *) addr))
+ force_successful_syscall_return();
+ return addr;
+diff -urpN linux-source-2.6.26.orig/arch/m32r/kernel/syscall_table.S linux-source-2.6.26/arch/m32r/kernel/syscall_table.S
+--- linux-source-2.6.26.orig/arch/m32r/kernel/syscall_table.S 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/m32r/kernel/syscall_table.S 2010-01-22 17:15:08.000000000 -0700
+@@ -191,7 +191,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap2
++ .long sys_mmap_pgoff
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff -urpN linux-source-2.6.26.orig/arch/m32r/kernel/sys_m32r.c linux-source-2.6.26/arch/m32r/kernel/sys_m32r.c
+--- linux-source-2.6.26.orig/arch/m32r/kernel/sys_m32r.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/m32r/kernel/sys_m32r.c 2010-01-22 17:15:08.000000000 -0700
+@@ -76,30 +76,6 @@ asmlinkage int sys_tas(int __user *addr)
+ return oldval;
+ }
+
+-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file *file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ /*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+diff -urpN linux-source-2.6.26.orig/arch/m68k/kernel/sys_m68k.c linux-source-2.6.26/arch/m68k/kernel/sys_m68k.c
+--- linux-source-2.6.26.orig/arch/m68k/kernel/sys_m68k.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/m68k/kernel/sys_m68k.c 2010-01-22 17:15:08.000000000 -0700
+@@ -30,37 +30,16 @@
+ #include <asm/page.h>
+ #include <asm/unistd.h>
+
+-/* common code for old and new mmaps */
+-static inline long do_mmap2(
+- unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+ {
+- return do_mmap2(addr, len, prot, flags, fd, pgoff);
++ /*
++ * This is wrong for sun3 - there PAGE_SIZE is 8Kb,
++ * so we need to shift the argument down by 1; m68k mmap64(3)
++ * (in libc) expects the last argument of mmap2 in 4Kb units.
++ */
++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
+ }
+
+ /*
+@@ -91,57 +70,11 @@ asmlinkage int old_mmap(struct mmap_arg_
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+-out:
+- return error;
+-}
+-
+-#if 0
+-struct mmap_arg_struct64 {
+- __u32 addr;
+- __u32 len;
+- __u32 prot;
+- __u32 flags;
+- __u64 offset; /* 64 bits */
+- __u32 fd;
+-};
+-
+-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+-{
+- int error = -EFAULT;
+- struct file * file = NULL;
+- struct mmap_arg_struct64 a;
+- unsigned long pgoff;
+-
+- if (copy_from_user(&a, arg, sizeof(a)))
+- return -EFAULT;
+-
+- if ((long)a.offset & ~PAGE_MASK)
+- return -EINVAL;
+-
+- pgoff = a.offset >> PAGE_SHIFT;
+- if ((a.offset >> PAGE_SHIFT) != pgoff)
+- return -EINVAL;
+-
+- if (!(a.flags & MAP_ANONYMOUS)) {
+- error = -EBADF;
+- file = fget(a.fd);
+- if (!file)
+- goto out;
+- }
+- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+- if (file)
+- fput(file);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
++ a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+-#endif
+
+ struct sel_arg_struct {
+ unsigned long n;
+diff -urpN linux-source-2.6.26.orig/arch/m68knommu/kernel/syscalltable.S linux-source-2.6.26/arch/m68knommu/kernel/syscalltable.S
+--- linux-source-2.6.26.orig/arch/m68knommu/kernel/syscalltable.S 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/m68knommu/kernel/syscalltable.S 2010-01-22 17:15:08.000000000 -0700
+@@ -210,7 +210,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap2
++ .long sys_mmap_pgoff
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff -urpN linux-source-2.6.26.orig/arch/m68knommu/kernel/sys_m68k.c linux-source-2.6.26/arch/m68knommu/kernel/sys_m68k.c
+--- linux-source-2.6.26.orig/arch/m68knommu/kernel/sys_m68k.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/m68knommu/kernel/sys_m68k.c 2010-01-22 17:15:08.000000000 -0700
+@@ -28,39 +28,6 @@
+ #include <asm/cacheflush.h>
+ #include <asm/unistd.h>
+
+-/* common code for old and new mmaps */
+-static inline long do_mmap2(
+- unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- return do_mmap2(addr, len, prot, flags, fd, pgoff);
+-}
+-
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+@@ -89,9 +56,8 @@ asmlinkage int old_mmap(struct mmap_arg_
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
++ a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/mips/kernel/linux32.c linux-source-2.6.26/arch/mips/kernel/linux32.c
+--- linux-source-2.6.26.orig/arch/mips/kernel/linux32.c 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/arch/mips/kernel/linux32.c 2010-01-22 17:15:08.000000000 -0700
+@@ -104,28 +104,13 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, pgoff)
+ {
+- struct file * file = NULL;
+ unsigned long error;
+
+ error = -EINVAL;
+ if (pgoff & (~PAGE_MASK >> 12))
+ goto out;
+- pgoff >>= PAGE_SHIFT-12;
+-
+- if (!(flags & MAP_ANONYMOUS)) {
+- error = -EBADF;
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+- if (file)
+- fput(file);
+-
++ error = sys_mmap_pgoff(addr, len, prot, flags, fd,
++ pgoff >> (PAGE_SHIFT-12));
+ out:
+ return error;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/mips/kernel/syscall.c linux-source-2.6.26/arch/mips/kernel/syscall.c
+--- linux-source-2.6.26.orig/arch/mips/kernel/syscall.c 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/arch/mips/kernel/syscall.c 2010-01-22 17:15:08.000000000 -0700
+@@ -92,7 +92,8 @@ unsigned long arch_get_unmapped_area(str
+ * We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+- if ((flags & MAP_SHARED) && (addr & shm_align_mask))
++ if ((flags & MAP_SHARED) &&
++ ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
+ return -EINVAL;
+ return addr;
+ }
+@@ -128,31 +129,6 @@ unsigned long arch_get_unmapped_area(str
+ }
+ }
+
+-/* common code for old and new mmaps */
+-static inline unsigned long
+-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+- unsigned long flags, unsigned long fd, unsigned long pgoff)
+-{
+- unsigned long error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long,
+ fd, off_t, offset)
+@@ -163,7 +139,7 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long
+ if (offset & ~PAGE_MASK)
+ goto out;
+
+- result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+
+ out:
+ return result;
+@@ -176,7 +152,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned lon
+ if (pgoff & (~PAGE_MASK >> 12))
+ return -EINVAL;
+
+- 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));
+ }
+
+ save_static_function(sys_fork);
+diff -urpN linux-source-2.6.26.orig/arch/mn10300/kernel/entry.S linux-source-2.6.26/arch/mn10300/kernel/entry.S
+--- linux-source-2.6.26.orig/arch/mn10300/kernel/entry.S 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/mn10300/kernel/entry.S 2010-01-22 17:15:08.000000000 -0700
+@@ -580,7 +580,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap2
++ .long sys_mmap_pgoff
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff -urpN linux-source-2.6.26.orig/arch/mn10300/kernel/sys_mn10300.c linux-source-2.6.26/arch/mn10300/kernel/sys_mn10300.c
+--- linux-source-2.6.26.orig/arch/mn10300/kernel/sys_mn10300.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/mn10300/kernel/sys_mn10300.c 2010-01-22 17:15:08.000000000 -0700
+@@ -26,47 +26,13 @@
+
+ #include <asm/uaccess.h>
+
+-#define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */
+-
+-/*
+- * memory mapping syscall
+- */
+-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- struct file *file = NULL;
+- long error = -EINVAL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- if (flags & MAP_FIXED && addr < MIN_MAP_ADDR)
+- goto out;
+-
+- error = -EBADF;
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ asmlinkage long old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long offset)
+ {
+ if (offset & ~PAGE_MASK)
+ return -EINVAL;
+- return sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ }
+
+ struct sel_arg_struct {
+diff -urpN linux-source-2.6.26.orig/arch/parisc/kernel/sys_parisc.c linux-source-2.6.26/arch/parisc/kernel/sys_parisc.c
+--- linux-source-2.6.26.orig/arch/parisc/kernel/sys_parisc.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/parisc/kernel/sys_parisc.c 2010-01-22 17:15:08.000000000 -0700
+@@ -110,37 +110,14 @@ unsigned long arch_get_unmapped_area(str
+ return addr;
+ }
+
+-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 error = -EBADF;
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file != NULL)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags, unsigned long fd,
+ unsigned long pgoff)
+ {
+ /* 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,
+@@ -148,7 +125,8 @@ asmlinkage unsigned long sys_mmap(unsign
+ unsigned long offset)
+ {
+ if (!(offset & ~PAGE_MASK)) {
+- return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ return sys_mmap_pgoff(addr, len, prot, flags, fd,
++ offset >> PAGE_SHIFT);
+ } else {
+ return -EINVAL;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/powerpc/kernel/syscalls.c linux-source-2.6.26/arch/powerpc/kernel/syscalls.c
+--- linux-source-2.6.26.orig/arch/powerpc/kernel/syscalls.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/powerpc/kernel/syscalls.c 2010-01-22 17:15:08.000000000 -0700
+@@ -140,7 +140,6 @@ static inline unsigned long do_mmap2(uns
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long off, int shift)
+ {
+- struct file * file = NULL;
+ unsigned long ret = -EINVAL;
+
+ if (shift) {
+@@ -148,20 +147,8 @@ static inline unsigned long do_mmap2(uns
+ goto out;
+ off >>= shift;
+ }
+-
+- ret = -EBADF;
+- if (!(flags & MAP_ANONYMOUS)) {
+- if (!(file = fget(fd)))
+- goto out;
+- }
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+- down_write(¤t->mm->mmap_sem);
+- ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
+- up_write(¤t->mm->mmap_sem);
+- if (file)
+- fput(file);
++ ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off);
+ out:
+ return ret;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/s390/kernel/compat_linux.c linux-source-2.6.26/arch/s390/kernel/compat_linux.c
+--- linux-source-2.6.26.orig/arch/s390/kernel/compat_linux.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/s390/kernel/compat_linux.c 2010-01-22 17:15:08.000000000 -0700
+@@ -843,38 +843,6 @@ struct mmap_arg_struct_emu31 {
+ u32 offset;
+ };
+
+-/* common code for old and new mmaps */
+-static inline 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 error = -EBADF;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
+- /* Result is out of bounds. */
+- do_munmap(current->mm, addr, len);
+- error = -ENOMEM;
+- }
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+-
+ asmlinkage unsigned long
+ old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
+ {
+@@ -888,7 +856,8 @@ old32_mmap(struct mmap_arg_struct_emu31
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
++ a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+@@ -901,7 +870,7 @@ sys32_mmap2(struct mmap_arg_struct_emu31
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ goto out;
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+ out:
+ return error;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/s390/kernel/sys_s390.c linux-source-2.6.26/arch/s390/kernel/sys_s390.c
+--- linux-source-2.6.26.orig/arch/s390/kernel/sys_s390.c 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/arch/s390/kernel/sys_s390.c 2010-01-22 17:15:08.000000000 -0700
+@@ -33,32 +33,6 @@
+ #include <asm/uaccess.h>
+ #include "entry.h"
+
+-/* common code for old and new mmaps */
+-static inline long do_mmap2(
+- unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- long error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux for S/390 isn't able to handle more than 5
+@@ -82,7 +56,7 @@ SYSCALL_DEFINE1(mmap2, struct mmap_arg_s
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ goto out;
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+ out:
+ return error;
+ }
+@@ -99,7 +73,7 @@ SYSCALL_DEFINE1(s390_old_mmap, struct mm
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/sh/kernel/sys_sh.c linux-source-2.6.26/arch/sh/kernel/sys_sh.c
+--- linux-source-2.6.26.orig/arch/sh/kernel/sys_sh.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/sh/kernel/sys_sh.c 2010-01-24 23:18:02.000000000 -0700
+@@ -49,7 +49,8 @@ unsigned long arch_get_unmapped_area(str
+ /* We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+- if ((flags & MAP_SHARED) && (addr & shm_align_mask))
++ if ((flags & MAP_SHARED) &&
++ ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
+ return -EINVAL;
+ return addr;
+ }
+@@ -117,44 +118,20 @@ full_search:
+ }
+ #endif /* CONFIG_MMU */
+
+-static inline long
+-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+- unsigned long flags, int fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file *file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ asmlinkage int old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ int fd, unsigned long off)
+ {
+ if (off & ~PAGE_MASK)
+ return -EINVAL;
+- return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
++ return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
+ }
+
+ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+ {
+- return do_mmap2(addr, len, prot, flags, fd, pgoff);
++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
+ }
+
+ /*
+diff -urpN linux-source-2.6.26.orig/arch/sparc/kernel/sys_sparc.c linux-source-2.6.26/arch/sparc/kernel/sys_sparc.c
+--- linux-source-2.6.26.orig/arch/sparc/kernel/sys_sparc.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/sparc/kernel/sys_sparc.c 2010-01-24 22:45:57.000000000 -0700
+@@ -45,7 +45,8 @@ unsigned long arch_get_unmapped_area(str
+ /* 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(str
+ }
+ }
+
+-asmlinkage unsigned long sparc_brk(unsigned long brk)
+-{
+- if(ARCH_SUN4C_SUN4) {
+- 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,
+ }
+
+ /* 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(unsig
+ {
+ /* 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 lon
+ (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)
+diff -urpN linux-source-2.6.26.orig/arch/sparc/kernel/systbls.S linux-source-2.6.26/arch/sparc/kernel/systbls.S
+--- linux-source-2.6.26.orig/arch/sparc/kernel/systbls.S 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/sparc/kernel/systbls.S 2010-01-24 22:58:13.000000000 -0700
+@@ -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
+diff -urpN linux-source-2.6.26.orig/arch/sparc64/kernel/sys_sparc.c linux-source-2.6.26/arch/sparc64/kernel/sys_sparc.c
+--- linux-source-2.6.26.orig/arch/sparc64/kernel/sys_sparc.c 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/arch/sparc64/kernel/sys_sparc.c 2010-01-24 22:50:20.000000000 -0700
+@@ -316,10 +316,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;
+
+@@ -332,7 +336,7 @@ unsigned long get_fb_unmapped_area(struc
+ 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;
+@@ -350,7 +354,7 @@ unsigned long get_fb_unmapped_area(struc
+ * 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;
+ }
+@@ -397,18 +401,6 @@ void arch_pick_mmap_layout(struct mm_str
+ }
+ }
+
+-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.
+@@ -566,23 +558,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, add
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, off)
+ {
+- struct file * file = NULL;
+- unsigned long retval = -EBADF;
+-
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- len = PAGE_ALIGN(len);
++ unsigned long retval = -EINVAL;
+
+- 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;
+ }
+@@ -612,12 +594,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long
+
+ if (test_thread_flag(TIF_32BIT))
+ goto out;
+- if (unlikely(new_len >= VA_EXCLUDE_START))
+- goto out;
+- if (unlikely(sparc64_mmap_check(addr, old_len)))
+- goto out;
+- if (unlikely(sparc64_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);
+diff -urpN linux-source-2.6.26.orig/arch/sparc64/kernel/systbls.h linux-source-2.6.26/arch/sparc64/kernel/systbls.h
+--- linux-source-2.6.26.orig/arch/sparc64/kernel/systbls.h 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/arch/sparc64/kernel/systbls.h 2010-01-24 23:00:08.000000000 -0700
+@@ -8,7 +8,6 @@
+ #include <asm/signal.h>
+
+ 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,
+diff -urpN linux-source-2.6.26.orig/arch/sparc64/kernel/systbls.S linux-source-2.6.26/arch/sparc64/kernel/systbls.S
+--- linux-source-2.6.26.orig/arch/sparc64/kernel/systbls.S 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/arch/sparc64/kernel/systbls.S 2010-01-24 22:59:03.000000000 -0700
+@@ -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, sys32_chown16, sys32_mknod
+-/*15*/ .word sys_chmod, sys32_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, sys32_setuid16, sys32_getuid16
+ /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
+ /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
+@@ -94,7 +94,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
+diff -urpN linux-source-2.6.26.orig/arch/um/include/sysdep-i386/syscalls.h linux-source-2.6.26/arch/um/include/sysdep-i386/syscalls.h
+--- linux-source-2.6.26.orig/arch/um/include/sysdep-i386/syscalls.h 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/um/include/sysdep-i386/syscalls.h 2010-01-22 17:30:51.000000000 -0700
+@@ -20,7 +20,3 @@ extern syscall_handler_t *sys_call_table
+ #define EXECUTE_SYSCALL(syscall, regs) \
+ ((long (*)(struct syscall_args)) \
+ (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
+-
+-extern long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff);
+diff -urpN linux-source-2.6.26.orig/arch/um/kernel/syscall.c linux-source-2.6.26/arch/um/kernel/syscall.c
+--- linux-source-2.6.26.orig/arch/um/kernel/syscall.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/um/kernel/syscall.c 2010-01-22 17:15:08.000000000 -0700
+@@ -8,6 +8,7 @@
+ #include "linux/mm.h"
+ #include "linux/sched.h"
+ #include "linux/utsname.h"
++#include "linux/syscalls.h"
+ #include "asm/current.h"
+ #include "asm/mman.h"
+ #include "asm/uaccess.h"
+@@ -36,31 +37,6 @@ long sys_vfork(void)
+ return ret;
+ }
+
+-/* common code for old and new mmaps */
+-long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- long error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+- out:
+- return error;
+-}
+-
+ long old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long offset)
+@@ -69,7 +45,7 @@ long old_mmap(unsigned long addr, unsign
+ if (offset & ~PAGE_MASK)
+ goto out;
+
+- err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ out:
+ return err;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/x86/ia32/ia32entry.S linux-source-2.6.26/arch/x86/ia32/ia32entry.S
+--- linux-source-2.6.26.orig/arch/x86/ia32/ia32entry.S 2009-12-26 01:14:58.000000000 -0700
++++ linux-source-2.6.26/arch/x86/ia32/ia32entry.S 2010-01-22 17:15:08.000000000 -0700
+@@ -600,7 +600,7 @@ ia32_sys_call_table:
+ .quad quiet_ni_syscall /* streams2 */
+ .quad stub32_vfork /* 190 */
+ .quad compat_sys_getrlimit
+- .quad sys32_mmap2
++ .quad sys_mmap_pgoff
+ .quad sys32_truncate64
+ .quad sys32_ftruncate64
+ .quad sys32_stat64 /* 195 */
+diff -urpN linux-source-2.6.26.orig/arch/x86/ia32/sys_ia32.c linux-source-2.6.26/arch/x86/ia32/sys_ia32.c
+--- linux-source-2.6.26.orig/arch/x86/ia32/sys_ia32.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/x86/ia32/sys_ia32.c 2010-01-22 17:15:08.000000000 -0700
+@@ -199,9 +199,6 @@ struct mmap_arg_struct {
+ asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
+ {
+ struct mmap_arg_struct a;
+- struct file *file = NULL;
+- unsigned long retval;
+- struct mm_struct *mm ;
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ return -EFAULT;
+@@ -209,22 +206,8 @@ asmlinkage long sys32_mmap(struct mmap_a
+ if (a.offset & ~PAGE_MASK)
+ return -EINVAL;
+
+- if (!(a.flags & MAP_ANONYMOUS)) {
+- file = fget(a.fd);
+- if (!file)
+- return -EBADF;
+- }
+-
+- mm = current->mm;
+- down_write(&mm->mmap_sem);
+- retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags,
++ return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+ a.offset>>PAGE_SHIFT);
+- if (file)
+- fput(file);
+-
+- up_write(&mm->mmap_sem);
+-
+- return retval;
+ }
+
+ asmlinkage long sys32_mprotect(unsigned long start, size_t len,
+@@ -670,30 +653,6 @@ asmlinkage long sys32_sendfile(int out_f
+ return ret;
+ }
+
+-asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- struct mm_struct *mm = current->mm;
+- unsigned long error;
+- struct file *file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- return -EBADF;
+- }
+-
+- down_write(&mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(&mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+- return error;
+-}
+-
+ asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
+ {
+ char *arch = "x86_64";
+diff -urpN linux-source-2.6.26.orig/arch/x86/kernel/syscall_table_32.S linux-source-2.6.26/arch/x86/kernel/syscall_table_32.S
+--- linux-source-2.6.26.orig/arch/x86/kernel/syscall_table_32.S 2009-12-26 01:14:55.000000000 -0700
++++ linux-source-2.6.26/arch/x86/kernel/syscall_table_32.S 2010-01-22 17:15:08.000000000 -0700
+@@ -191,7 +191,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap2
++ .long sys_mmap_pgoff
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff -urpN linux-source-2.6.26.orig/arch/x86/kernel/sys_i386_32.c linux-source-2.6.26/arch/x86/kernel/sys_i386_32.c
+--- linux-source-2.6.26.orig/arch/x86/kernel/sys_i386_32.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/x86/kernel/sys_i386_32.c 2010-01-22 17:15:08.000000000 -0700
+@@ -22,31 +22,6 @@
+ #include <asm/uaccess.h>
+ #include <asm/unistd.h>
+
+-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file *file = NULL;
+- struct mm_struct *mm = current->mm;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(&mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(&mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/i386 didn't use to be able to handle more than
+@@ -75,7 +50,7 @@ asmlinkage int old_mmap(struct mmap_arg_
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- err = sys_mmap2(a.addr, a.len, a.prot, a.flags,
++ err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags,
+ a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return err;
+diff -urpN linux-source-2.6.26.orig/arch/x86/kernel/sys_x86_64.c linux-source-2.6.26/arch/x86/kernel/sys_x86_64.c
+--- linux-source-2.6.26.orig/arch/x86/kernel/sys_x86_64.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/x86/kernel/sys_x86_64.c 2010-01-22 17:27:43.000000000 -0700
+@@ -21,26 +21,11 @@ asmlinkage long sys_mmap(unsigned long a
+ unsigned long fd, unsigned long off)
+ {
+ long error;
+- struct file * file;
+-
+ error = -EINVAL;
+ if (off & ~PAGE_MASK)
+ goto out;
+
+- error = -EBADF;
+- file = NULL;
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
++ error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+diff -urpN linux-source-2.6.26.orig/arch/xtensa/kernel/syscall.c linux-source-2.6.26/arch/xtensa/kernel/syscall.c
+--- linux-source-2.6.26.orig/arch/xtensa/kernel/syscall.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/arch/xtensa/kernel/syscall.c 2010-01-22 17:15:08.000000000 -0700
+@@ -57,31 +57,6 @@ asmlinkage long xtensa_pipe(int __user *
+ return error;
+ }
+
+-
+-asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff)
+-{
+- int error = -EBADF;
+- struct file * file = NULL;
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+- if (!(flags & MAP_ANONYMOUS)) {
+- file = fget(fd);
+- if (!file)
+- goto out;
+- }
+-
+- down_write(¤t->mm->mmap_sem);
+- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return error;
+-}
+-
+ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
+ {
+ unsigned long ret;
+diff -urpN linux-source-2.6.26.orig/include/asm-arm/mman.h linux-source-2.6.26/include/asm-arm/mman.h
+--- linux-source-2.6.26.orig/include/asm-arm/mman.h 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-arm/mman.h 2010-01-22 17:15:05.000000000 -0700
+@@ -1,4 +1,7 @@
+ #ifndef __ARM_MMAN_H__
++
++#define arch_mmap_check(addr, len, flags) \
++ (((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0)
+ #define __ARM_MMAN_H__
+
+ #include <asm-generic/mman.h>
+diff -urpN linux-source-2.6.26.orig/include/asm-mn10300/mman.h linux-source-2.6.26/include/asm-mn10300/mman.h
+--- linux-source-2.6.26.orig/include/asm-mn10300/mman.h 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-mn10300/mman.h 2010-01-22 17:15:08.000000000 -0700
+@@ -1,4 +1,9 @@
+ /* MN10300 Constants for mmap and co.
++
++#define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */
++
++#define arch_mmap_check(addr, len, flags) \
++ (((flags) & MAP_FIXED && (addr) < MIN_MAP_ADDR) ? -EINVAL : 0)
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+diff -urpN linux-source-2.6.26.orig/include/asm-xtensa/syscall.h linux-source-2.6.26/include/asm-xtensa/syscall.h
+--- linux-source-2.6.26.orig/include/asm-xtensa/syscall.h 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-xtensa/syscall.h 2010-01-22 17:15:08.000000000 -0700
+@@ -13,8 +13,6 @@ struct sigaction;
+ asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*);
+ asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*);
+ asmlinkage long xtensa_pipe(int __user *);
+-asmlinkage long xtensa_mmap2(unsigned long, unsigned long, unsigned long,
+- unsigned long, unsigned long, unsigned long);
+ asmlinkage long xtensa_ptrace(long, long, long, long);
+ asmlinkage long xtensa_sigreturn(struct pt_regs*);
+ asmlinkage long xtensa_rt_sigreturn(struct pt_regs*);
+diff -urpN linux-source-2.6.26.orig/include/asm-xtensa/unistd.h linux-source-2.6.26/include/asm-xtensa/unistd.h
+--- linux-source-2.6.26.orig/include/asm-xtensa/unistd.h 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-xtensa/unistd.h 2010-01-22 17:15:08.000000000 -0700
+@@ -189,7 +189,7 @@ __SYSCALL( 79, sys_fremovexattr, 2)
+ /* File Map / Shared Memory Operations */
+
+ #define __NR_mmap2 80
+-__SYSCALL( 80, xtensa_mmap2, 6)
++__SYSCALL( 80, sys_mmap_pgoff, 6)
+ #define __NR_munmap 81
+ __SYSCALL( 81, sys_munmap, 2)
+ #define __NR_mprotect 82
+diff -urpN linux-source-2.6.26.orig/include/linux/syscalls.h linux-source-2.6.26/include/linux/syscalls.h
+--- linux-source-2.6.26.orig/include/linux/syscalls.h 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/include/linux/syscalls.h 2010-01-22 17:33:52.000000000 -0700
+@@ -686,6 +686,10 @@ asmlinkage long sys_ppoll(struct pollfd
+ asmlinkage long sys_pipe2(int __user *, int);
+ asmlinkage long sys_pipe(int __user *);
+
++asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff);
++
+ int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+
+ #endif
+diff -urpN linux-source-2.6.26.orig/ipc/shm.c linux-source-2.6.26/ipc/shm.c
+--- linux-source-2.6.26.orig/ipc/shm.c 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/ipc/shm.c 2010-01-22 17:18:51.000000000 -0700
+@@ -304,28 +304,28 @@ static unsigned long shm_get_unmapped_ar
+ unsigned long flags)
+ {
+ struct shm_file_data *sfd = shm_file_data(file);
+- return get_unmapped_area(sfd->file, addr, len, pgoff, flags);
+-}
+-
+-int is_file_shm_hugepages(struct file *file)
+-{
+- int ret = 0;
+-
+- if (file->f_op == &shm_file_operations) {
+- struct shm_file_data *sfd;
+- sfd = shm_file_data(file);
+- ret = is_file_hugepages(sfd->file);
+- }
+- return ret;
++ return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
++ pgoff, flags);
+ }
+
+ static const struct file_operations shm_file_operations = {
+ .mmap = shm_mmap,
+ .fsync = shm_fsync,
+ .release = shm_release,
++};
++
++static const struct file_operations shm_file_operations_huge = {
++ .mmap = shm_mmap,
++ .fsync = shm_fsync,
++ .release = shm_release,
+ .get_unmapped_area = shm_get_unmapped_area,
+ };
+
++int is_file_shm_hugepages(struct file *file)
++{
++ return file->f_op == &shm_file_operations_huge;
++}
++
+ static struct vm_operations_struct shm_vm_ops = {
+ .open = shm_open, /* callback for a new vm-area open */
+ .close = shm_close, /* callback for when the vm-area is released */
+@@ -898,7 +898,10 @@ long do_shmat(int shmid, char __user *sh
+ if (!sfd)
+ goto out_put_dentry;
+
+- file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
++ file = alloc_file(path.mnt, path.dentry, f_mode,
++ is_file_hugepages(shp->shm_file) ?
++ &shm_file_operations_huge :
++ &shm_file_operations);
+ if (!file)
+ goto out_free;
+
+diff -urpN linux-source-2.6.26.orig/mm/mmap.c linux-source-2.6.26/mm/mmap.c
+--- linux-source-2.6.26.orig/mm/mmap.c 2009-12-26 01:14:57.000000000 -0700
++++ linux-source-2.6.26/mm/mmap.c 2010-01-22 17:15:08.000000000 -0700
+@@ -932,13 +932,9 @@ unsigned long do_mmap_pgoff(struct file
+ if (!(flags & MAP_FIXED))
+ addr = round_hint_to_min(addr);
+
+- error = arch_mmap_check(addr, len, flags);
+- if (error)
+- return error;
+-
+ /* Careful about overflows.. */
+ len = PAGE_ALIGN(len);
+- if (!len || len > TASK_SIZE)
++ if (!len)
+ return -ENOMEM;
+
+ /* offset overflow? */
+@@ -1429,6 +1425,14 @@ get_unmapped_area(struct file *file, uns
+ unsigned long (*get_area)(struct file *, unsigned long,
+ unsigned long, unsigned long, unsigned long);
+
++ unsigned long error = arch_mmap_check(addr, len, flags);
++ if (error)
++ return error;
++
++ /* Careful about overflows.. */
++ if (len > TASK_SIZE)
++ return -ENOMEM;
++
+ get_area = current->mm->get_unmapped_area;
+ if (file && file->f_op && file->f_op->get_unmapped_area)
+ get_area = file->f_op->get_unmapped_area;
+@@ -1956,20 +1960,14 @@ unsigned long do_brk(unsigned long addr,
+ if (!len)
+ return addr;
+
+- if ((addr + len) > TASK_SIZE || (addr + len) < addr)
+- return -EINVAL;
+-
+- if (is_hugepage_only_range(mm, addr, len))
+- return -EINVAL;
+-
+ error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
+ if (error)
+ return error;
+
+ flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+
+- error = arch_mmap_check(addr, len, flags);
+- if (error)
++ error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
++ if (error & ~PAGE_MASK)
+ return error;
+
+ /*
+diff -urpN linux-source-2.6.26.orig/mm/mremap.c linux-source-2.6.26/mm/mremap.c
+--- linux-source-2.6.26.orig/mm/mremap.c 2009-12-26 01:14:56.000000000 -0700
++++ linux-source-2.6.26/mm/mremap.c 2010-01-22 17:15:08.000000000 -0700
+@@ -239,6 +239,137 @@ static unsigned long move_vma(struct vm_
+ return new_addr;
+ }
+
++static struct vm_area_struct *vma_to_resize(unsigned long addr,
++ unsigned long old_len, unsigned long new_len, unsigned long *p)
++{
++ struct mm_struct *mm = current->mm;
++ struct vm_area_struct *vma = find_vma(mm, addr);
++
++ if (!vma || vma->vm_start > addr)
++ goto Efault;
++
++ if (is_vm_hugetlb_page(vma))
++ goto Einval;
++
++ /* We can't remap across vm area boundaries */
++ if (old_len > vma->vm_end - addr)
++ goto Efault;
++
++ if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
++ if (new_len > old_len)
++ goto Efault;
++ }
++
++ if (vma->vm_flags & VM_LOCKED) {
++ unsigned long locked, lock_limit;
++ locked = mm->locked_vm << PAGE_SHIFT;
++ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ locked += new_len - old_len;
++ if (locked > lock_limit && !capable(CAP_IPC_LOCK))
++ goto Eagain;
++ }
++
++ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT))
++ goto Enomem;
++
++ if (vma->vm_flags & VM_ACCOUNT) {
++ unsigned long charged = (new_len - old_len) >> PAGE_SHIFT;
++ if (security_vm_enough_memory(charged))
++ goto Efault;
++ *p = charged;
++ }
++
++ return vma;
++
++Efault: /* very odd choice for most of the cases, but... */
++ return ERR_PTR(-EFAULT);
++Einval:
++ return ERR_PTR(-EINVAL);
++Enomem:
++ return ERR_PTR(-ENOMEM);
++Eagain:
++ return ERR_PTR(-EAGAIN);
++}
++
++static unsigned long mremap_to(unsigned long addr,
++ unsigned long old_len, unsigned long new_addr,
++ unsigned long new_len)
++{
++ struct mm_struct *mm = current->mm;
++ struct vm_area_struct *vma;
++ unsigned long ret = -EINVAL;
++ unsigned long charged = 0;
++ unsigned long map_flags;
++
++ if (new_addr & ~PAGE_MASK)
++ goto out;
++
++ if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
++ goto out;
++
++ /* Check if the location we're moving into overlaps the
++ * old location at all, and fail if it does.
++ */
++ if ((new_addr <= addr) && (new_addr+new_len) > addr)
++ goto out;
++
++ if ((addr <= new_addr) && (addr+old_len) > new_addr)
++ goto out;
++
++ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
++ if (ret)
++ goto out;
++
++ ret = do_munmap(mm, new_addr, new_len);
++ if (ret)
++ goto out;
++
++ if (old_len >= new_len) {
++ ret = do_munmap(mm, addr+new_len, old_len - new_len);
++ if (ret && old_len != new_len)
++ goto out;
++ old_len = new_len;
++ }
++
++ vma = vma_to_resize(addr, old_len, new_len, &charged);
++ if (IS_ERR(vma)) {
++ ret = PTR_ERR(vma);
++ goto out;
++ }
++
++ map_flags = MAP_FIXED;
++ if (vma->vm_flags & VM_MAYSHARE)
++ map_flags |= MAP_SHARED;
++
++ ret = get_unmapped_area(vma->vm_file, new_addr, new_len, vma->vm_pgoff +
++ ((addr - vma->vm_start) >> PAGE_SHIFT),
++ map_flags);
++ if (ret & ~PAGE_MASK)
++ goto out1;
++
++ ret = move_vma(vma, addr, old_len, new_len, new_addr);
++ if (!(ret & ~PAGE_MASK))
++ goto out;
++out1:
++ vm_unacct_memory(charged);
++
++out:
++ return ret;
++}
++
++static int vma_expandable(struct vm_area_struct *vma, unsigned long delta)
++{
++ unsigned long end = vma->vm_end + delta;
++ if (end < vma->vm_end) /* overflow */
++ return 0;
++ if (vma->vm_next && vma->vm_next->vm_start < end) /* intersection */
++ return 0;
++ if (get_unmapped_area(NULL, vma->vm_start, end - vma->vm_start,
++ 0, MAP_FIXED) & ~PAGE_MASK)
++ return 0;
++ return 1;
++}
++
+ /*
+ * Expand (or shrink) an existing mapping, potentially moving it at the
+ * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
+@@ -272,32 +403,10 @@ unsigned long do_mremap(unsigned long ad
+ if (!new_len)
+ goto out;
+
+- /* new_addr is only valid if MREMAP_FIXED is specified */
+ if (flags & MREMAP_FIXED) {
+- if (new_addr & ~PAGE_MASK)
+- goto out;
+- if (!(flags & MREMAP_MAYMOVE))
+- goto out;
+-
+- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
+- goto out;
+-
+- /* Check if the location we're moving into overlaps the
+- * old location at all, and fail if it does.
+- */
+- if ((new_addr <= addr) && (new_addr+new_len) > addr)
+- goto out;
+-
+- if ((addr <= new_addr) && (addr+old_len) > new_addr)
+- goto out;
+-
+- ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
+- if (ret)
+- goto out;
+-
+- ret = do_munmap(mm, new_addr, new_len);
+- if (ret)
+- goto out;
++ if (flags & MREMAP_MAYMOVE)
++ ret = mremap_to(addr, old_len, new_addr, new_len);
++ goto out;
+ }
+
+ /*
+@@ -310,60 +419,23 @@ unsigned long do_mremap(unsigned long ad
+ if (ret && old_len != new_len)
+ goto out;
+ ret = addr;
+- if (!(flags & MREMAP_FIXED) || (new_addr == addr))
+- goto out;
+- old_len = new_len;
++ goto out;
+ }
+
+ /*
+- * Ok, we need to grow.. or relocate.
++ * Ok, we need to grow..
+ */
+- ret = -EFAULT;
+- vma = find_vma(mm, addr);
+- if (!vma || vma->vm_start > addr)
++ vma = vma_to_resize(addr, old_len, new_len, &charged);
++ if (IS_ERR(vma)) {
++ ret = PTR_ERR(vma);
+ goto out;
+- if (is_vm_hugetlb_page(vma)) {
+- ret = -EINVAL;
+- goto out;
+- }
+- /* We can't remap across vm area boundaries */
+- if (old_len > vma->vm_end - addr)
+- goto out;
+- if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
+- if (new_len > old_len)
+- goto out;
+- }
+- if (vma->vm_flags & VM_LOCKED) {
+- unsigned long locked, lock_limit;
+- locked = mm->locked_vm << PAGE_SHIFT;
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+- locked += new_len - old_len;
+- ret = -EAGAIN;
+- if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+- goto out;
+- }
+- if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
+- ret = -ENOMEM;
+- goto out;
+- }
+-
+- if (vma->vm_flags & VM_ACCOUNT) {
+- charged = (new_len - old_len) >> PAGE_SHIFT;
+- if (security_vm_enough_memory(charged))
+- goto out_nc;
+ }
+
+ /* old_len exactly to the end of the area..
+- * And we're not relocating the area.
+ */
+- if (old_len == vma->vm_end - addr &&
+- !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
+- (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
+- unsigned long max_addr = TASK_SIZE;
+- if (vma->vm_next)
+- max_addr = vma->vm_next->vm_start;
++ if (old_len == vma->vm_end - addr) {
+ /* can we just expand the current mapping? */
+- if (max_addr - addr >= new_len) {
++ if (vma_expandable(vma, new_len - old_len)) {
+ int pages = (new_len - old_len) >> PAGE_SHIFT;
+
+ vma_adjust(vma, vma->vm_start,
+@@ -387,28 +459,27 @@ unsigned long do_mremap(unsigned long ad
+ */
+ ret = -ENOMEM;
+ if (flags & MREMAP_MAYMOVE) {
+- if (!(flags & MREMAP_FIXED)) {
+- unsigned long map_flags = 0;
+- if (vma->vm_flags & VM_MAYSHARE)
+- map_flags |= MAP_SHARED;
+-
+- new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
+- vma->vm_pgoff, map_flags);
+- if (new_addr & ~PAGE_MASK) {
+- ret = new_addr;
+- goto out;
+- }
+-
+- ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
+- if (ret)
+- goto out;
++ unsigned long map_flags = 0;
++ if (vma->vm_flags & VM_MAYSHARE)
++ map_flags |= MAP_SHARED;
++
++ new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
++ vma->vm_pgoff +
++ ((addr - vma->vm_start) >> PAGE_SHIFT),
++ map_flags);
++ if (new_addr & ~PAGE_MASK) {
++ ret = new_addr;
++ goto out;
+ }
++
++ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
++ if (ret)
++ goto out;
+ ret = move_vma(vma, addr, old_len, new_len, new_addr);
+ }
+ out:
+ if (ret & ~PAGE_MASK)
+ vm_unacct_memory(charged);
+-out_nc:
+ return ret;
+ }
+
+diff -urpN linux-source-2.6.26.orig/mm/util.c linux-source-2.6.26/mm/util.c
+--- linux-source-2.6.26.orig/mm/util.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/mm/util.c 2010-01-22 17:29:51.000000000 -0700
+@@ -2,6 +2,10 @@
+ #include <linux/string.h>
+ #include <linux/module.h>
+ #include <linux/err.h>
++#include <linux/hugetlb.h>
++#include <linux/syscalls.h>
++#include <linux/mman.h>
++#include <linux/file.h>
+ #include <asm/uaccess.h>
+
+ /**
+@@ -136,3 +140,30 @@ char *strndup_user(const char __user *s,
+ return p;
+ }
+ EXPORT_SYMBOL(strndup_user);
++
++SYSCALL_DEFINE6(mmap_pgoff, 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)) {
++ /*if (unlikely(flags & MAP_HUGETLB))
++ return -EINVAL;*/
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ 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;
++}
Modified: dists/lenny-security/linux-2.6/debian/patches/features/all/openvz/openvz.patch
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/features/all/openvz/openvz.patch Wed Jan 27 16:35:55 2010 (r15043)
+++ dists/lenny-security/linux-2.6/debian/patches/features/all/openvz/openvz.patch Wed Jan 27 16:52:30 2010 (r15044)
@@ -996,19 +996,6 @@
}
}
}
-diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
-index 1eda194..e93e7d3 100644
---- a/arch/ia64/kernel/sys_ia64.c
-+++ b/arch/ia64/kernel/sys_ia64.c
-@@ -204,7 +204,7 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
-
- /* Careful about overflows.. */
- len = PAGE_ALIGN(len);
-- if (!len || len > TASK_SIZE) {
-+ if (len > TASK_SIZE) {
- addr = -EINVAL;
- goto out;
- }
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index aad1b7b..9194bf5 100644
--- a/arch/ia64/kernel/time.c
@@ -30496,8 +30483,8 @@
else
user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size,
shp->mlock_user);
-@@ -319,12 +337,13 @@ int is_file_shm_hugepages(struct file *file)
- return ret;
+@@ -308,11 +326,12 @@ static unsigned long shm_get_unmapped_ar
+ pgoff, flags);
}
-static const struct file_operations shm_file_operations = {
@@ -30505,12 +30492,11 @@
.mmap = shm_mmap,
.fsync = shm_fsync,
.release = shm_release,
- .get_unmapped_area = shm_get_unmapped_area,
};
+EXPORT_SYMBOL_GPL(shm_file_operations);
- static struct vm_operations_struct shm_vm_ops = {
- .open = shm_open, /* callback for a new vm-area open */
+ static const struct file_operations shm_file_operations_huge = {
+ .mmap = shm_mmap,
@@ -349,11 +368,12 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
key_t key = params->key;
int shmflg = params->flg;
@@ -67782,10 +67768,10 @@
}
/*
-@@ -364,7 +376,15 @@ unsigned long do_mremap(unsigned long addr,
- max_addr = vma->vm_next->vm_start;
+@@ -436,7 +448,15 @@ unsigned long do_mremap(unsigned long ad
+ if (old_len == vma->vm_end - addr) {
/* can we just expand the current mapping? */
- if (max_addr - addr >= new_len) {
+ if (vma_expandable(vma, new_len - old_len)) {
- int pages = (new_len - old_len) >> PAGE_SHIFT;
+ unsigned long len;
+ int pages;
Modified: dists/lenny-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.35.patch
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.35.patch Wed Jan 27 16:35:55 2010 (r15043)
+++ dists/lenny-security/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.35.patch Wed Jan 27 16:52:30 2010 (r15044)
@@ -26003,16 +26003,16 @@
if (new_len > old_len)
make_pages_present(new_addr + old_len,
new_addr + new_len);
-@@ -341,6 +342,9 @@ unsigned long do_mremap(unsigned long ad
- ret = -EAGAIN;
+@@ -267,6 +268,9 @@ static struct vm_area_struct *vma_to_res
+ locked += new_len - old_len;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
- goto out;
+ goto Eagain;
+ if (!vx_vmlocked_avail(current->mm,
+ (new_len - old_len) >> PAGE_SHIFT))
-+ goto out;
++ goto Einval;
}
- if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
- ret = -ENOMEM;
+
+ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT))
@@ -369,10 +373,10 @@ unsigned long do_mremap(unsigned long ad
vma_adjust(vma, vma->vm_start,
addr + new_len, vma->vm_pgoff, NULL);
Modified: dists/lenny-security/linux-2.6/debian/patches/series/21lenny1
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/series/21lenny1 Wed Jan 27 16:35:55 2010 (r15043)
+++ dists/lenny-security/linux-2.6/debian/patches/series/21lenny1 Wed Jan 27 16:52:30 2010 (r15044)
@@ -3,3 +3,4 @@
+ bugfix/all/netfilter-ebtables-enforce-CAP_NET_ADMIN.patch
+ bugfix/all/e1000-enhance-frame-fragment-detection.patch
+ bugfix/all/e1000e-enhance-frame-fragment-detection.patch
++ bugfix/all/untangle-the-do_mremap-mess.patch
More information about the Kernel-svn-changes
mailing list