summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2.6.32/0000_README2
-rw-r--r--2.6.32/4420_grsecurity-2.9-2.6.32.57-201202251202.patch (renamed from 2.6.32/4420_grsecurity-2.2.2-2.6.32.57-201202131842.patch)993
-rw-r--r--3.2.7/0000_README (renamed from 3.2.6/0000_README)6
-rw-r--r--3.2.7/1006_linux-3.2.7.patch994
-rw-r--r--3.2.7/4420_grsecurity-2.9-3.2.7-201202251203.patch (renamed from 3.2.6/4420_grsecurity-2.2.2-3.2.6-201202131824.patch)872
-rw-r--r--3.2.7/4425_grsec_enable_xtpax.patch (renamed from 3.2.6/4425_grsec_enable_xtpax.patch)0
-rw-r--r--3.2.7/4430_grsec-remove-localversion-grsec.patch (renamed from 3.2.6/4430_grsec-remove-localversion-grsec.patch)0
-rw-r--r--3.2.7/4435_grsec-mute-warnings.patch (renamed from 3.2.6/4435_grsec-mute-warnings.patch)0
-rw-r--r--3.2.7/4440_grsec-remove-protected-paths.patch (renamed from 3.2.6/4440_grsec-remove-protected-paths.patch)0
-rw-r--r--3.2.7/4445_grsec-pax-without-grsec.patch (renamed from 3.2.6/4445_grsec-pax-without-grsec.patch)0
-rw-r--r--3.2.7/4450_grsec-kconfig-default-gids.patch (renamed from 3.2.6/4450_grsec-kconfig-default-gids.patch)0
-rw-r--r--3.2.7/4455_grsec-kconfig-gentoo.patch (renamed from 3.2.6/4455_grsec-kconfig-gentoo.patch)0
-rw-r--r--3.2.7/4460-grsec-kconfig-proc-user.patch (renamed from 3.2.6/4460-grsec-kconfig-proc-user.patch)0
-rw-r--r--3.2.7/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.2.6/4465_selinux-avc_audit-log-curr_ip.patch)0
-rw-r--r--3.2.7/4470_disable-compat_vdso.patch (renamed from 3.2.6/4470_disable-compat_vdso.patch)0
15 files changed, 2355 insertions, 512 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index d1d1d12..d4a9997 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -22,7 +22,7 @@ Patch: 1056_linux-2.6.32.57.patch
From: http://www.kernel.org
Desc: Linux 2.6.32.57
-Patch: 4420_grsecurity-2.2.2-2.6.32.57-201202131842.patch
+Patch: 4420_grsecurity-2.9-2.6.32.57-201202251202.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/2.6.32/4420_grsecurity-2.2.2-2.6.32.57-201202131842.patch b/2.6.32/4420_grsecurity-2.9-2.6.32.57-201202251202.patch
index 89f6faf..59a7ef3 100644
--- a/2.6.32/4420_grsecurity-2.2.2-2.6.32.57-201202131842.patch
+++ b/2.6.32/4420_grsecurity-2.9-2.6.32.57-201202251202.patch
@@ -401,6 +401,27 @@ index 3377650..76aacb3 100644
$(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(@:.ko=.o)
+diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
+index 610dff4..f396854 100644
+--- a/arch/alpha/include/asm/atomic.h
++++ b/arch/alpha/include/asm/atomic.h
+@@ -251,6 +251,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ #define atomic_dec(v) atomic_sub(1,(v))
+ #define atomic64_dec(v) atomic64_sub(1,(v))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #define smp_mb__before_atomic_dec() smp_mb()
+ #define smp_mb__after_atomic_dec() smp_mb()
+ #define smp_mb__before_atomic_inc() smp_mb()
diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
index 5c75c1b..c82f878 100644
--- a/arch/alpha/include/asm/elf.h
@@ -649,6 +670,33 @@ index 00a31de..2ded0f2 100644
} else if (!cause) {
/* Allow reads even for write-only mappings */
if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index b68faef..6dd1496 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -14,6 +14,7 @@ config ARM
+ select SYS_SUPPORTS_APM_EMULATION
+ select HAVE_OPROFILE
+ select HAVE_ARCH_KGDB
++ select GENERIC_ATOMIC64
+ select HAVE_KPROBES if (!XIP_KERNEL)
+ select HAVE_KRETPROBES if (HAVE_KPROBES)
+ select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
+diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
+index d0daeab..ff286a8 100644
+--- a/arch/arm/include/asm/atomic.h
++++ b/arch/arm/include/asm/atomic.h
+@@ -15,6 +15,10 @@
+ #include <linux/types.h>
+ #include <asm/system.h>
+
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i) { (i) }
+
+ #ifdef __KERNEL__
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 6aac3f5..265536b 100644
--- a/arch/arm/include/asm/elf.h
@@ -1254,6 +1302,27 @@ index 8837be4..b2fb413 100644
.enter = bfin_pm_enter,
.valid = bfin_pm_valid,
};
+diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
+index 00a57af..c3ef0cd 100644
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -241,6 +241,16 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v);
+ #define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter))
+ #define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+ {
+ int c, old;
diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h
index f8e16b2..c73ff79 100644
--- a/arch/frv/include/asm/kmap_types.h
@@ -1380,6 +1449,27 @@ index 0f15349..26b3429 100644
#define IA32_GATE_OFFSET IA32_PAGE_OFFSET
#define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
+diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
+index 88405cb..de5ca5d 100644
+--- a/arch/ia64/include/asm/atomic.h
++++ b/arch/ia64/include/asm/atomic.h
+@@ -210,6 +210,16 @@ atomic64_add_negative (__s64 i, atomic64_t *v)
+ #define atomic64_inc(v) atomic64_add(1, (v))
+ #define atomic64_dec(v) atomic64_sub(1, (v))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ /* Atomic operations are already serializing */
+ #define smp_mb__before_atomic_dec() barrier()
+ #define smp_mb__after_atomic_dec() barrier()
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 8d3c79c..71b3af6 100644
--- a/arch/ia64/include/asm/dma-mapping.h
@@ -1904,6 +1994,18 @@ index 82abd15..d95ae5d 100644
prefetchw(to);
if (access_ok(VERIFY_READ, from, n))
__copy_user_zeroing(to,from,n);
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index fd7620f..63d73a6 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -5,6 +5,7 @@ config MIPS
+ select HAVE_IDE
+ select HAVE_OPROFILE
+ select HAVE_ARCH_KGDB
++ select GENERIC_ATOMIC64 if !64BIT
+ # Horrible source of confusion. Die, die, die ...
+ select EMBEDDED
+ select RTC_LIB if !LEMOTE_FULOONG2E
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 77f5021..2b1db8a 100644
--- a/arch/mips/Makefile
@@ -1930,6 +2032,38 @@ index 632f986..fd0378d 100644
.valid = suspend_valid_only_mem,
.begin = db1x_pm_begin,
.enter = db1x_pm_enter,
+diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
+index 09e7128..111035b 100644
+--- a/arch/mips/include/asm/atomic.h
++++ b/arch/mips/include/asm/atomic.h
+@@ -21,6 +21,10 @@
+ #include <asm/war.h>
+ #include <asm/system.h>
+
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i) { (i) }
+
+ /*
+@@ -782,6 +786,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ */
+ #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* CONFIG_64BIT */
+
+ /*
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index 7990694..4e93acf 100644
--- a/arch/mips/include/asm/elf.h
@@ -2154,6 +2288,27 @@ index e97a7a2..f18f5b0 100644
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
+diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
+index 8bc9e96..26554f8 100644
+--- a/arch/parisc/include/asm/atomic.h
++++ b/arch/parisc/include/asm/atomic.h
+@@ -336,6 +336,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #else /* CONFIG_64BIT */
+
+ #include <asm-generic/atomic64.h>
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 9c802eb..0592e41 100644
--- a/arch/parisc/include/asm/elf.h
@@ -3839,6 +3994,27 @@ index 43c0aca..42c045b 100644
comment "Code generation options"
+diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
+index ae7c8f9..3f01a0c 100644
+--- a/arch/s390/include/asm/atomic.h
++++ b/arch/s390/include/asm/atomic.h
+@@ -362,6 +362,16 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+ #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0)
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #define smp_mb__before_atomic_dec() smp_mb()
+ #define smp_mb__after_atomic_dec() smp_mb()
+ #define smp_mb__before_atomic_inc() smp_mb()
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index e885442..e3a2817 100644
--- a/arch/s390/include/asm/elf.h
@@ -4251,6 +4427,18 @@ index afeb710..d1d1289 100644
bottomup:
/*
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
+index 05ef538..dc9c857 100644
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -32,6 +32,7 @@ config SPARC
+
+ config SPARC32
+ def_bool !64BIT
++ select GENERIC_ATOMIC64
+
+ config SPARC64
+ def_bool 64BIT
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 113225b..7fd04e7 100644
--- a/arch/sparc/Makefile
@@ -4264,6 +4452,17 @@ index 113225b..7fd04e7 100644
VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
VMLINUX_MAIN += $(drivers-y) $(net-y)
+diff --git a/arch/sparc/include/asm/atomic.h b/arch/sparc/include/asm/atomic.h
+index 8ff83d8..4a459c2 100644
+--- a/arch/sparc/include/asm/atomic.h
++++ b/arch/sparc/include/asm/atomic.h
+@@ -4,5 +4,6 @@
+ #include <asm/atomic_64.h>
+ #else
+ #include <asm/atomic_32.h>
++#include <asm-generic/atomic64.h>
+ #endif
+ #endif
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index f5cc06f..f858d47 100644
--- a/arch/sparc/include/asm/atomic_64.h
@@ -4543,6 +4742,19 @@ index 9968085..c2106ef 100644
/* This yields a mask that user programs can use to figure out what
instruction set this cpu supports. */
+diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
+index 156707b..aefa786 100644
+--- a/arch/sparc/include/asm/page_32.h
++++ b/arch/sparc/include/asm/page_32.h
+@@ -8,6 +8,8 @@
+ #ifndef _SPARC_PAGE_H
+ #define _SPARC_PAGE_H
+
++#include <linux/const.h>
++
+ #define PAGE_SHIFT 12
+
+ #ifndef __ASSEMBLY__
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index e0cabe7..efd60f1 100644
--- a/arch/sparc/include/asm/pgtable_32.h
@@ -31418,6 +31630,19 @@ index 1270f64..8495f49 100644
};
static int memory_open(struct inode *inode, struct file *filp)
+diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
+index 918711a..4ffaf5e 100644
+--- a/drivers/char/mmtimer.c
++++ b/drivers/char/mmtimer.c
+@@ -756,7 +756,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
+ return err;
+ }
+
+-static struct k_clock sgi_clock = {
++static k_clock_no_const sgi_clock = {
+ .res = 0,
+ .clock_set = sgi_clock_set,
+ .clock_get = sgi_clock_get,
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c
index 674b3ab..a8d1970 100644
--- a/drivers/char/pcmcia/ipwireless/tty.c
@@ -47928,7 +48153,7 @@ index a5bf577..6d19845 100644
return hit;
}
diff --git a/fs/compat.c b/fs/compat.c
-index d1e2411..b1eda5d 100644
+index d1e2411..c2ef8ed 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -133,8 +133,8 @@ asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval _
@@ -48049,7 +48274,18 @@ index d1e2411..b1eda5d 100644
goto out;
if (!file->f_op)
goto out;
-@@ -1463,11 +1481,35 @@ int compat_do_execve(char * filename,
+@@ -1454,6 +1472,10 @@ out:
+ return ret;
+ }
+
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++extern atomic64_unchecked_t global_exec_counter;
++#endif
++
+ /*
+ * compat_do_execve() is mostly a copy of do_execve(), with the exception
+ * that it processes 32 bit argv and envp pointers.
+@@ -1463,11 +1485,35 @@ int compat_do_execve(char * filename,
compat_uptr_t __user *envp,
struct pt_regs * regs)
{
@@ -48085,7 +48321,7 @@ index d1e2411..b1eda5d 100644
retval = unshare_files(&displaced);
if (retval)
-@@ -1493,12 +1535,26 @@ int compat_do_execve(char * filename,
+@@ -1493,12 +1539,26 @@ int compat_do_execve(char * filename,
if (IS_ERR(file))
goto out_unmark;
@@ -48112,7 +48348,7 @@ index d1e2411..b1eda5d 100644
retval = bprm_mm_init(bprm);
if (retval)
goto out_file;
-@@ -1528,9 +1584,40 @@ int compat_do_execve(char * filename,
+@@ -1528,11 +1588,45 @@ int compat_do_execve(char * filename,
if (retval < 0)
goto out;
@@ -48153,8 +48389,13 @@ index d1e2411..b1eda5d 100644
+#endif
/* execve succeeded */
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++ current->exec_id = atomic64_inc_return_unchecked(&global_exec_counter);
++#endif
current->fs->in_exec = 0;
-@@ -1541,6 +1628,14 @@ int compat_do_execve(char * filename,
+ current->in_execve = 0;
+ acct_update_integrals(current);
+@@ -1541,6 +1635,14 @@ int compat_do_execve(char * filename,
put_files_struct(displaced);
return retval;
@@ -48169,7 +48410,7 @@ index d1e2411..b1eda5d 100644
out:
if (bprm->mm) {
acct_arg_size(bprm, 0);
-@@ -1711,6 +1806,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
+@@ -1711,6 +1813,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
struct fdtable *fdt;
long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
@@ -48178,7 +48419,7 @@ index d1e2411..b1eda5d 100644
if (n < 0)
goto out_nofds;
-@@ -2151,7 +2248,7 @@ asmlinkage long compat_sys_nfsservctl(int cmd,
+@@ -2151,7 +2255,7 @@ asmlinkage long compat_sys_nfsservctl(int cmd,
oldfs = get_fs();
set_fs(KERNEL_DS);
/* The __user pointer casts are valid because of the set_fs() */
@@ -48409,7 +48650,7 @@ index 88ba4d4..073f003 100644
if (rc < 0)
goto out_free;
diff --git a/fs/exec.c b/fs/exec.c
-index 86fafc6..47ffa63 100644
+index 86fafc6..6272c0e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,12 +56,28 @@
@@ -48463,7 +48704,25 @@ index 86fafc6..47ffa63 100644
return NULL;
if (write) {
-@@ -263,6 +271,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+@@ -205,6 +213,17 @@ struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+ if (size <= ARG_MAX)
+ return page;
+
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++ // only allow 1MB for argv+env on suid/sgid binaries
++ // to prevent easy ASLR exhaustion
++ if (((bprm->cred->euid != current_euid()) ||
++ (bprm->cred->egid != current_egid())) &&
++ (size > (1024 * 1024))) {
++ put_page(page);
++ return NULL;
++ }
++#endif
++
+ /*
+ * Limit to 1/4-th the stack size for the argv+env strings.
+ * This ensures that:
+@@ -263,6 +282,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
vma->vm_end = STACK_TOP_MAX;
vma->vm_start = vma->vm_end - PAGE_SIZE;
vma->vm_flags = VM_STACK_FLAGS;
@@ -48475,7 +48734,7 @@ index 86fafc6..47ffa63 100644
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
-@@ -276,6 +289,12 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+@@ -276,6 +300,12 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
mm->stack_vm = mm->total_vm = 1;
up_write(&mm->mmap_sem);
bprm->p = vma->vm_end - sizeof(void *);
@@ -48488,7 +48747,7 @@ index 86fafc6..47ffa63 100644
return 0;
err:
up_write(&mm->mmap_sem);
-@@ -510,7 +529,7 @@ int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm)
+@@ -510,7 +540,7 @@ int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm)
int r;
mm_segment_t oldfs = get_fs();
set_fs(KERNEL_DS);
@@ -48497,7 +48756,7 @@ index 86fafc6..47ffa63 100644
set_fs(oldfs);
return r;
}
-@@ -540,7 +559,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+@@ -540,7 +570,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
unsigned long new_end = old_end - shift;
struct mmu_gather *tlb;
@@ -48507,7 +48766,7 @@ index 86fafc6..47ffa63 100644
/*
* ensure there are no vmas between where we want to go
-@@ -549,6 +569,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+@@ -549,6 +580,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
if (vma != find_vma(mm, new_start))
return -EFAULT;
@@ -48518,7 +48777,7 @@ index 86fafc6..47ffa63 100644
/*
* cover the whole range: [new_start, old_end)
*/
-@@ -630,10 +654,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -630,10 +665,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
stack_top = arch_align_stack(stack_top);
stack_top = PAGE_ALIGN(stack_top);
@@ -48529,7 +48788,7 @@ index 86fafc6..47ffa63 100644
stack_shift = vma->vm_end - stack_top;
bprm->p -= stack_shift;
-@@ -645,6 +665,14 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -645,6 +676,14 @@ int setup_arg_pages(struct linux_binprm *bprm,
bprm->exec -= stack_shift;
down_write(&mm->mmap_sem);
@@ -48544,7 +48803,7 @@ index 86fafc6..47ffa63 100644
vm_flags = VM_STACK_FLAGS;
/*
-@@ -658,19 +686,24 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -658,19 +697,24 @@ int setup_arg_pages(struct linux_binprm *bprm,
vm_flags &= ~VM_EXEC;
vm_flags |= mm->def_flags;
@@ -48576,7 +48835,7 @@ index 86fafc6..47ffa63 100644
stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
stack_size = vma->vm_end - vma->vm_start;
/*
-@@ -744,7 +777,7 @@ int kernel_read(struct file *file, loff_t offset,
+@@ -744,7 +788,7 @@ int kernel_read(struct file *file, loff_t offset,
old_fs = get_fs();
set_fs(get_ds());
/* The cast to a user pointer is valid due to the set_fs() */
@@ -48585,7 +48844,7 @@ index 86fafc6..47ffa63 100644
set_fs(old_fs);
return result;
}
-@@ -985,6 +1018,21 @@ void set_task_comm(struct task_struct *tsk, char *buf)
+@@ -985,6 +1029,21 @@ void set_task_comm(struct task_struct *tsk, char *buf)
perf_event_comm(tsk);
}
@@ -48607,7 +48866,7 @@ index 86fafc6..47ffa63 100644
int flush_old_exec(struct linux_binprm * bprm)
{
int retval;
-@@ -999,6 +1047,7 @@ int flush_old_exec(struct linux_binprm * bprm)
+@@ -999,6 +1058,7 @@ int flush_old_exec(struct linux_binprm * bprm)
set_mm_exe_file(bprm->mm, bprm->file);
@@ -48615,7 +48874,7 @@ index 86fafc6..47ffa63 100644
/*
* Release all of the old mmap stuff
*/
-@@ -1023,10 +1072,6 @@ EXPORT_SYMBOL(flush_old_exec);
+@@ -1023,10 +1083,6 @@ EXPORT_SYMBOL(flush_old_exec);
void setup_new_exec(struct linux_binprm * bprm)
{
@@ -48626,7 +48885,7 @@ index 86fafc6..47ffa63 100644
arch_pick_mmap_layout(current->mm);
/* This is the point of no return */
-@@ -1037,18 +1082,7 @@ void setup_new_exec(struct linux_binprm * bprm)
+@@ -1037,18 +1093,7 @@ void setup_new_exec(struct linux_binprm * bprm)
else
set_dumpable(current->mm, suid_dumpable);
@@ -48646,7 +48905,7 @@ index 86fafc6..47ffa63 100644
/* Set the new mm task size. We have to do that late because it may
* depend on TIF_32BIT which is only updated in flush_thread() on
-@@ -1152,7 +1186,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
+@@ -1152,7 +1197,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
}
rcu_read_unlock();
@@ -48655,7 +48914,7 @@ index 86fafc6..47ffa63 100644
bprm->unsafe |= LSM_UNSAFE_SHARE;
} else {
res = -EAGAIN;
-@@ -1339,6 +1373,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
+@@ -1339,6 +1384,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
EXPORT_SYMBOL(search_binary_handler);
@@ -48666,7 +48925,7 @@ index 86fafc6..47ffa63 100644
/*
* sys_execve() executes a new program.
*/
-@@ -1347,11 +1385,35 @@ int do_execve(char * filename,
+@@ -1347,11 +1396,35 @@ int do_execve(char * filename,
char __user *__user *envp,
struct pt_regs * regs)
{
@@ -48702,7 +48961,7 @@ index 86fafc6..47ffa63 100644
retval = unshare_files(&displaced);
if (retval)
-@@ -1377,12 +1439,27 @@ int do_execve(char * filename,
+@@ -1377,12 +1450,27 @@ int do_execve(char * filename,
if (IS_ERR(file))
goto out_unmark;
@@ -48730,7 +48989,7 @@ index 86fafc6..47ffa63 100644
retval = bprm_mm_init(bprm);
if (retval)
goto out_file;
-@@ -1412,12 +1489,47 @@ int do_execve(char * filename,
+@@ -1412,12 +1500,47 @@ int do_execve(char * filename,
if (retval < 0)
goto out;
@@ -48779,7 +49038,7 @@ index 86fafc6..47ffa63 100644
current->fs->in_exec = 0;
current->in_execve = 0;
acct_update_integrals(current);
-@@ -1426,6 +1538,14 @@ int do_execve(char * filename,
+@@ -1426,6 +1549,14 @@ int do_execve(char * filename,
put_files_struct(displaced);
return retval;
@@ -48794,7 +49053,7 @@ index 86fafc6..47ffa63 100644
out:
if (bprm->mm) {
acct_arg_size(bprm, 0);
-@@ -1591,6 +1711,220 @@ out:
+@@ -1591,6 +1722,220 @@ out:
return ispipe;
}
@@ -49015,7 +49274,7 @@ index 86fafc6..47ffa63 100644
static int zap_process(struct task_struct *start)
{
struct task_struct *t;
-@@ -1793,17 +2127,17 @@ static void wait_for_dump_helpers(struct file *file)
+@@ -1793,17 +2138,17 @@ static void wait_for_dump_helpers(struct file *file)
pipe = file->f_path.dentry->d_inode->i_pipe;
pipe_lock(pipe);
@@ -49038,7 +49297,7 @@ index 86fafc6..47ffa63 100644
pipe_unlock(pipe);
}
-@@ -1826,10 +2160,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -1826,10 +2171,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
char **helper_argv = NULL;
int helper_argc = 0;
int dump_count = 0;
@@ -49053,7 +49312,7 @@ index 86fafc6..47ffa63 100644
binfmt = mm->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
-@@ -1874,6 +2211,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -1874,6 +2222,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
*/
clear_thread_flag(TIF_SIGPENDING);
@@ -49062,7 +49321,7 @@ index 86fafc6..47ffa63 100644
/*
* lock_kernel() because format_corename() is controlled by sysctl, which
* uses lock_kernel()
-@@ -1908,7 +2247,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -1908,7 +2258,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
goto fail_unlock;
}
@@ -49071,7 +49330,7 @@ index 86fafc6..47ffa63 100644
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
task_tgid_vnr(current), current->comm);
-@@ -1972,7 +2311,7 @@ close_fail:
+@@ -1972,7 +2322,7 @@ close_fail:
filp_close(file, NULL);
fail_dropcount:
if (dump_count)
@@ -49462,7 +49721,7 @@ index a24c58e..53f91ee 100644
if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
-index eee0590..ef5bc0e 100644
+index eee0590..1181166 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -4,6 +4,7 @@
@@ -49519,7 +49778,14 @@ index eee0590..ef5bc0e 100644
write_unlock(&fs->lock);
task_unlock(current);
-@@ -147,7 +152,7 @@ EXPORT_SYMBOL(current_umask);
+@@ -141,13 +146,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
+
+ int current_umask(void)
+ {
+- return current->fs->umask;
++ return current->fs->umask | gr_acl_umask();
+ }
+ EXPORT_SYMBOL(current_umask);
/* to be mentioned only in INIT_TASK */
struct fs_struct init_fs = {
@@ -52304,7 +52570,7 @@ index 9f55be4..a3f8048 100644
/* Copy the blockcheck stats from the superblock probe */
osb->osb_ecc_stats = *stats;
diff --git a/fs/open.c b/fs/open.c
-index 4f01e06..091f6c3 100644
+index 4f01e06..2a8057a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -275,6 +275,10 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
@@ -52365,63 +52631,110 @@ index 4f01e06..091f6c3 100644
error = 0;
dput_and_out:
path_put(&path);
-@@ -616,12 +638,27 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
- err = mnt_want_write_file(file);
- if (err)
- goto out_putf;
-+
- mutex_lock(&inode->i_mutex);
+@@ -596,66 +618,57 @@ out:
+ return error;
+ }
+
++static int chmod_common(struct path *path, umode_t mode)
++{
++ struct inode *inode = path->dentry->d_inode;
++ struct iattr newattrs;
++ int error;
+
-+ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
-+ err = -EACCES;
++ error = mnt_want_write(path->mnt);
++ if (error)
++ return error;
++ mutex_lock(&inode->i_mutex);
++ if (!gr_acl_handle_chmod(path->dentry, path->mnt, &mode)) {
++ error = -EACCES;
+ goto out_unlock;
+ }
-+
- if (mode == (mode_t) -1)
- mode = inode->i_mode;
-+
-+ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
-+ err = -EPERM;
++ if (gr_handle_chroot_chmod(path->dentry, path->mnt, mode)) {
++ error = -EPERM;
+ goto out_unlock;
+ }
-+
- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
- err = notify_change(dentry, &newattrs);
-+
++ newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
++ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
++ error = notify_change(path->dentry, &newattrs);
+out_unlock:
- mutex_unlock(&inode->i_mutex);
- mnt_drop_write(file->f_path.mnt);
- out_putf:
-@@ -645,12 +682,27 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
- error = mnt_want_write(path.mnt);
- if (error)
- goto dput_and_out;
-+
- mutex_lock(&inode->i_mutex);
++ mutex_unlock(&inode->i_mutex);
++ mnt_drop_write(path->mnt);
++ return error;
++}
+
-+ if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
-+ error = -EACCES;
-+ goto out_unlock;
+ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
+ {
+- struct inode * inode;
+- struct dentry * dentry;
+ struct file * file;
+ int err = -EBADF;
+- struct iattr newattrs;
+
+ file = fget(fd);
+- if (!file)
+- goto out;
+-
+- dentry = file->f_path.dentry;
+- inode = dentry->d_inode;
+-
+- audit_inode(NULL, dentry);
+-
+- err = mnt_want_write_file(file);
+- if (err)
+- goto out_putf;
+- mutex_lock(&inode->i_mutex);
+- if (mode == (mode_t) -1)
+- mode = inode->i_mode;
+- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+- err = notify_change(dentry, &newattrs);
+- mutex_unlock(&inode->i_mutex);
+- mnt_drop_write(file->f_path.mnt);
+-out_putf:
+- fput(file);
+-out:
++ if (file) {
++ audit_inode(NULL, file->f_path.dentry);
++ err = chmod_common(&file->f_path, mode);
++ fput(file);
+ }
-+
- if (mode == (mode_t) -1)
- mode = inode->i_mode;
-+
-+ if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
-+ error = -EACCES;
-+ goto out_unlock;
+ return err;
+ }
+
+ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
+ {
+ struct path path;
+- struct inode *inode;
+ int error;
+- struct iattr newattrs;
+
+ error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
+- if (error)
+- goto out;
+- inode = path.dentry->d_inode;
+-
+- error = mnt_want_write(path.mnt);
+- if (error)
+- goto dput_and_out;
+- mutex_lock(&inode->i_mutex);
+- if (mode == (mode_t) -1)
+- mode = inode->i_mode;
+- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+- error = notify_change(path.dentry, &newattrs);
+- mutex_unlock(&inode->i_mutex);
+- mnt_drop_write(path.mnt);
+-dput_and_out:
+- path_put(&path);
+-out:
++ if (!error) {
++ error = chmod_common(&path, mode);
++ path_put(&path);
+ }
-+
- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
- error = notify_change(path.dentry, &newattrs);
-+
-+out_unlock:
- mutex_unlock(&inode->i_mutex);
- mnt_drop_write(path.mnt);
- dput_and_out:
-@@ -664,12 +716,15 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
+ return error;
+ }
+
+@@ -664,12 +677,15 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
return sys_fchmodat(AT_FDCWD, filename, mode);
}
@@ -52438,7 +52751,7 @@ index 4f01e06..091f6c3 100644
newattrs.ia_valid = ATTR_CTIME;
if (user != (uid_t) -1) {
newattrs.ia_valid |= ATTR_UID;
-@@ -700,7 +755,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
+@@ -700,7 +716,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
error = mnt_want_write(path.mnt);
if (error)
goto out_release;
@@ -52447,7 +52760,7 @@ index 4f01e06..091f6c3 100644
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
-@@ -725,7 +780,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
+@@ -725,7 +741,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
error = mnt_want_write(path.mnt);
if (error)
goto out_release;
@@ -52456,7 +52769,7 @@ index 4f01e06..091f6c3 100644
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
-@@ -744,7 +799,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
+@@ -744,7 +760,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
error = mnt_want_write(path.mnt);
if (error)
goto out_release;
@@ -52465,7 +52778,7 @@ index 4f01e06..091f6c3 100644
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
-@@ -767,7 +822,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
+@@ -767,7 +783,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
goto out_fput;
dentry = file->f_path.dentry;
audit_inode(NULL, dentry);
@@ -52474,7 +52787,7 @@ index 4f01e06..091f6c3 100644
mnt_drop_write(file->f_path.mnt);
out_fput:
fput(file);
-@@ -1036,7 +1091,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
+@@ -1036,7 +1052,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
if (!IS_ERR(tmp)) {
fd = get_unused_fd_flags(flags);
if (fd >= 0) {
@@ -52856,7 +53169,7 @@ index c5ef152..24a1b87 100644
+}
+#endif
diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 67f7dc0..67ab883 100644
+index 67f7dc0..a86ad9a 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -102,6 +102,22 @@ struct pid_entry {
@@ -52979,7 +53292,15 @@ index 67f7dc0..67ab883 100644
put_task_struct(task);
}
return allowed;
-@@ -809,6 +850,8 @@ static int mem_open(struct inode* inode, struct file* file)
+@@ -806,9 +847,16 @@ static const struct file_operations proc_single_file_operations = {
+ static int mem_open(struct inode* inode, struct file* file)
+ {
+ file->private_data = (void*)((long)current->self_exec_id);
++
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++ file->f_version = current->exec_id;
++#endif
++
return 0;
}
@@ -52988,20 +53309,21 @@ index 67f7dc0..67ab883 100644
static ssize_t mem_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
-@@ -824,6 +867,12 @@ static ssize_t mem_read(struct file * file, char __user * buf,
- if (check_mem_permission(task))
- goto out;
+@@ -818,6 +866,13 @@ static ssize_t mem_read(struct file * file, char __user * buf,
+ int ret = -ESRCH;
+ struct mm_struct *mm;
-+ // XXX: temporary workaround
-+ if (!task_dumpable(task) && task == current) {
-+ ret = -EACCES;
-+ goto out;
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++ if (file->f_version != current->exec_id) {
++ gr_log_badprocpid("mem");
++ return 0;
+ }
++#endif
+
- ret = -ENOMEM;
- page = (char *)__get_free_page(GFP_TEMPORARY);
- if (!page)
-@@ -963,6 +1012,9 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+ if (!task)
+ goto out_no_task;
+
+@@ -963,6 +1018,9 @@ static ssize_t environ_read(struct file *file, char __user *buf,
if (!task)
goto out_no_task;
@@ -53011,7 +53333,7 @@ index 67f7dc0..67ab883 100644
if (!ptrace_may_access(task, PTRACE_MODE_READ))
goto out;
-@@ -1377,7 +1429,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+@@ -1377,7 +1435,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
path_put(&nd->path);
/* Are we allowed to snoop on the tasks file descriptors? */
@@ -53020,7 +53342,7 @@ index 67f7dc0..67ab883 100644
goto out;
error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
-@@ -1417,8 +1469,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
+@@ -1417,8 +1475,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
struct path path;
/* Are we allowed to snoop on the tasks file descriptors? */
@@ -53041,7 +53363,7 @@ index 67f7dc0..67ab883 100644
error = PROC_I(inode)->op.proc_get_link(inode, &path);
if (error)
-@@ -1483,7 +1545,11 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
+@@ -1483,7 +1551,11 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
rcu_read_lock();
cred = __task_cred(task);
inode->i_uid = cred->euid;
@@ -53053,7 +53375,7 @@ index 67f7dc0..67ab883 100644
rcu_read_unlock();
}
security_task_to_inode(task, inode);
-@@ -1501,6 +1567,9 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
+@@ -1501,6 +1573,9 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
struct inode *inode = dentry->d_inode;
struct task_struct *task;
const struct cred *cred;
@@ -53063,7 +53385,7 @@ index 67f7dc0..67ab883 100644
generic_fillattr(inode, stat);
-@@ -1508,13 +1577,41 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
+@@ -1508,13 +1583,41 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
stat->uid = 0;
stat->gid = 0;
task = pid_task(proc_pid(inode), PIDTYPE_PID);
@@ -53106,7 +53428,7 @@ index 67f7dc0..67ab883 100644
}
rcu_read_unlock();
return 0;
-@@ -1545,11 +1642,20 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
+@@ -1545,11 +1648,20 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
if (task) {
if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
@@ -53127,7 +53449,7 @@ index 67f7dc0..67ab883 100644
rcu_read_unlock();
} else {
inode->i_uid = 0;
-@@ -1670,7 +1776,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
+@@ -1670,7 +1782,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
int fd = proc_fd(inode);
if (task) {
@@ -53137,7 +53459,7 @@ index 67f7dc0..67ab883 100644
put_task_struct(task);
}
if (files) {
-@@ -1922,12 +2029,22 @@ static const struct file_operations proc_fd_operations = {
+@@ -1922,12 +2035,22 @@ static const struct file_operations proc_fd_operations = {
static int proc_fd_permission(struct inode *inode, int mask)
{
int rv;
@@ -53162,7 +53484,7 @@ index 67f7dc0..67ab883 100644
return rv;
}
-@@ -2036,6 +2153,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
+@@ -2036,6 +2159,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
if (!task)
goto out_no_task;
@@ -53172,7 +53494,7 @@ index 67f7dc0..67ab883 100644
/*
* Yes, it does not scale. And it should not. Don't add
* new entries into /proc/<tgid>/ without very good reasons.
-@@ -2080,6 +2200,9 @@ static int proc_pident_readdir(struct file *filp,
+@@ -2080,6 +2206,9 @@ static int proc_pident_readdir(struct file *filp,
if (!task)
goto out_no_task;
@@ -53182,7 +53504,7 @@ index 67f7dc0..67ab883 100644
ret = 0;
i = filp->f_pos;
switch (i) {
-@@ -2347,7 +2470,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+@@ -2347,7 +2476,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
void *cookie)
{
@@ -53191,7 +53513,7 @@ index 67f7dc0..67ab883 100644
if (!IS_ERR(s))
__putname(s);
}
-@@ -2553,7 +2676,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2553,7 +2682,7 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
@@ -53200,7 +53522,7 @@ index 67f7dc0..67ab883 100644
INF("syscall", S_IRUGO, proc_pid_syscall),
#endif
INF("cmdline", S_IRUGO, proc_pid_cmdline),
-@@ -2578,10 +2701,10 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2578,10 +2707,10 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -53213,7 +53535,7 @@ index 67f7dc0..67ab883 100644
ONE("stack", S_IRUGO, proc_pid_stack),
#endif
#ifdef CONFIG_SCHEDSTATS
-@@ -2611,6 +2734,9 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2611,6 +2740,9 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_TASK_IO_ACCOUNTING
INF("io", S_IRUSR, proc_tgid_io_accounting),
#endif
@@ -53223,7 +53545,7 @@ index 67f7dc0..67ab883 100644
};
static int proc_tgid_base_readdir(struct file * filp,
-@@ -2735,7 +2861,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
+@@ -2735,7 +2867,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
if (!inode)
goto out;
@@ -53238,7 +53560,7 @@ index 67f7dc0..67ab883 100644
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
-@@ -2777,7 +2910,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
+@@ -2777,7 +2916,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
if (!task)
goto out;
@@ -53250,7 +53572,7 @@ index 67f7dc0..67ab883 100644
put_task_struct(task);
out:
return result;
-@@ -2842,6 +2979,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+@@ -2842,6 +2985,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
unsigned int nr;
struct task_struct *reaper;
@@ -53262,7 +53584,7 @@ index 67f7dc0..67ab883 100644
struct tgid_iter iter;
struct pid_namespace *ns;
-@@ -2865,8 +3007,27 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+@@ -2865,8 +3013,27 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
for (iter = next_tgid(ns, iter);
iter.task;
iter.tgid += 1, iter = next_tgid(ns, iter)) {
@@ -53291,7 +53613,7 @@ index 67f7dc0..67ab883 100644
put_task_struct(iter.task);
goto out;
}
-@@ -2892,7 +3053,7 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -2892,7 +3059,7 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
@@ -53300,7 +53622,7 @@ index 67f7dc0..67ab883 100644
INF("syscall", S_IRUGO, proc_pid_syscall),
#endif
INF("cmdline", S_IRUGO, proc_pid_cmdline),
-@@ -2916,10 +3077,10 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -2916,10 +3083,10 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -54234,10 +54556,18 @@ index fd38ce2..f5381b8 100644
return -EINVAL;
diff --git a/fs/seq_file.c b/fs/seq_file.c
-index eae7d9d..12c71e3 100644
+index eae7d9d..4ddabe2 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
-@@ -40,6 +40,9 @@ int seq_open(struct file *file, const struct seq_operations *op)
+@@ -9,6 +9,7 @@
+ #include <linux/module.h>
+ #include <linux/seq_file.h>
+ #include <linux/slab.h>
++#include <linux/sched.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/page.h>
+@@ -40,6 +41,9 @@ int seq_open(struct file *file, const struct seq_operations *op)
memset(p, 0, sizeof(*p));
mutex_init(&p->lock);
p->op = op;
@@ -54247,7 +54577,7 @@ index eae7d9d..12c71e3 100644
/*
* Wrappers around seq_open(e.g. swaps_open) need to be
-@@ -76,7 +79,8 @@ static int traverse(struct seq_file *m, loff_t offset)
+@@ -76,7 +80,8 @@ static int traverse(struct seq_file *m, loff_t offset)
return 0;
}
if (!m->buf) {
@@ -54257,7 +54587,7 @@ index eae7d9d..12c71e3 100644
if (!m->buf)
return -ENOMEM;
}
-@@ -116,7 +120,8 @@ static int traverse(struct seq_file *m, loff_t offset)
+@@ -116,7 +121,8 @@ static int traverse(struct seq_file *m, loff_t offset)
Eoverflow:
m->op->stop(m, p);
kfree(m->buf);
@@ -54267,7 +54597,7 @@ index eae7d9d..12c71e3 100644
return !m->buf ? -ENOMEM : -EAGAIN;
}
-@@ -169,7 +174,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+@@ -169,7 +175,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
m->version = file->f_version;
/* grab buffer if we didn't have one */
if (!m->buf) {
@@ -54277,7 +54607,7 @@ index eae7d9d..12c71e3 100644
if (!m->buf)
goto Enomem;
}
-@@ -210,7 +216,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+@@ -210,7 +217,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
goto Fill;
m->op->stop(m, p);
kfree(m->buf);
@@ -54287,7 +54617,7 @@ index eae7d9d..12c71e3 100644
if (!m->buf)
goto Enomem;
m->count = 0;
-@@ -551,7 +558,7 @@ static void single_stop(struct seq_file *p, void *v)
+@@ -551,7 +559,7 @@ static void single_stop(struct seq_file *p, void *v)
int single_open(struct file *file, int (*show)(struct seq_file *, void *),
void *data)
{
@@ -54912,10 +55242,10 @@ index 8f32f50..b6a41e8 100644
link[pathlen] = '\0';
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..9ac9020
+index 0000000..7026cbd
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,1072 @@
+@@ -0,0 +1,1074 @@
+#
+# grecurity configuration
+#
@@ -55122,7 +55452,7 @@ index 0000000..9ac9020
+
+endchoice
+
-+menu "Address Space Protection"
++menu "Memory Protections"
+depends on GRKERNSEC
+
+config GRKERNSEC_KMEM
@@ -55179,7 +55509,7 @@ index 0000000..9ac9020
+ protect your kernel against modification, use the RBAC system.
+
+config GRKERNSEC_PROC_MEMMAP
-+ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
++ bool "Harden ASLR against information leaks and entropy reduction"
+ default y if (PAX_NOEXEC || PAX_ASLR)
+ depends on PAX_NOEXEC || PAX_ASLR
+ help
@@ -55190,9 +55520,11 @@ index 0000000..9ac9020
+ dangerous sources of information, this option causes reads of sensitive
+ /proc/<pid> entries where the file descriptor was opened in a different
+ task than the one performing the read. Such attempts are logged.
-+ If you use PaX it is greatly recommended that you say Y here as it
-+ closes up a hole that makes the full ASLR useless for suid
-+ binaries.
++ Finally, this option limits argv/env strings for suid/sgid binaries
++ to 1MB to prevent a complete exhaustion of the stack entropy provided
++ by ASLR.
++ If you use PaX it is essential that you say Y here as it closes up
++ several holes that make full ASLR useless for suid/sgid binaries.
+
+config GRKERNSEC_BRUTE
+ bool "Deter exploit bruteforcing"
@@ -56034,10 +56366,10 @@ index 0000000..1b9afa9
+endif
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
new file mode 100644
-index 0000000..78e83d8
+index 0000000..b1c4f4d
--- /dev/null
+++ b/grsecurity/gracl.c
-@@ -0,0 +1,4148 @@
+@@ -0,0 +1,4149 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -58294,17 +58626,18 @@ index 0000000..78e83d8
+void
+gr_copy_label(struct task_struct *tsk)
+{
++ /* plain copying of fields is already done by dup_task_struct */
+ tsk->signal->used_accept = 0;
+ tsk->acl_sp_role = 0;
-+ tsk->acl_role_id = current->acl_role_id;
-+ tsk->acl = current->acl;
-+ tsk->role = current->role;
++ //tsk->acl_role_id = current->acl_role_id;
++ //tsk->acl = current->acl;
++ //tsk->role = current->role;
+ tsk->signal->curr_ip = current->signal->curr_ip;
+ tsk->signal->saved_ip = current->signal->saved_ip;
+ if (current->exec_file)
+ get_file(current->exec_file);
-+ tsk->exec_file = current->exec_file;
-+ tsk->is_writable = current->is_writable;
++ //tsk->exec_file = current->exec_file;
++ //tsk->is_writable = current->is_writable;
+ if (unlikely(current->signal->used_accept)) {
+ current->signal->curr_ip = 0;
+ current->signal->saved_ip = 0;
@@ -58516,8 +58849,8 @@ index 0000000..78e83d8
+
+ /* don't change the role if we're not a privileged process */
+ if (role && task->role != role &&
-+ (((role->roletype & GR_ROLE_USER) && gr_acl_is_capable(CAP_SETUID)) ||
-+ ((role->roletype & GR_ROLE_GROUP) && gr_acl_is_capable(CAP_SETGID))))
++ (((role->roletype & GR_ROLE_USER) && !gr_acl_is_capable(CAP_SETUID)) ||
++ ((role->roletype & GR_ROLE_GROUP) && !gr_acl_is_capable(CAP_SETGID))))
+ return;
+
+ /* perform subject lookup in possibly new role
@@ -60406,10 +60739,10 @@ index 0000000..955ddfb
+
diff --git a/grsecurity/gracl_fs.c b/grsecurity/gracl_fs.c
new file mode 100644
-index 0000000..d5f210c
+index 0000000..523e7e8
--- /dev/null
+++ b/grsecurity/gracl_fs.c
-@@ -0,0 +1,433 @@
+@@ -0,0 +1,435 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
@@ -60420,6 +60753,15 @@ index 0000000..d5f210c
+#include <linux/grinternal.h>
+#include <linux/gracl.h>
+
++umode_t
++gr_acl_umask(void)
++{
++ if (unlikely(!gr_acl_is_enabled()))
++ return 0;
++
++ return current->role->umask;
++}
++
+__u32
+gr_acl_handle_hidden_file(const struct dentry * dentry,
+ const struct vfsmount * mnt)
@@ -60608,25 +60950,18 @@ index 0000000..d5f210c
+}
+
+__u32
-+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
-+ mode_t mode)
++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
++ umode_t *modeptr)
+{
++ mode_t mode;
++
++ *modeptr &= ~(mode_t)gr_acl_umask();
++ mode = *modeptr;
++
+ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
+ return 1;
+
-+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
-+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
-+ GR_FCHMOD_ACL_MSG);
-+ } else {
-+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
-+ }
-+}
-+
-+__u32
-+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
-+ mode_t mode)
-+{
-+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
++ if (unlikely(mode & (S_ISUID | S_ISGID))) {
+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
+ GR_CHMOD_ACL_MSG);
+ } else {
@@ -62273,10 +62608,10 @@ index 0000000..197bdd5
+}
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
new file mode 100644
-index 0000000..b81db5b
+index 0000000..40545bf
--- /dev/null
+++ b/grsecurity/grsec_disabled.c
-@@ -0,0 +1,439 @@
+@@ -0,0 +1,437 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -62516,15 +62851,8 @@ index 0000000..b81db5b
+}
+
+__u32
-+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
-+ mode_t mode)
-+{
-+ return 1;
-+}
-+
-+__u32
+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
-+ mode_t mode)
++ umode_t *mode)
+{
+ return 1;
+}
@@ -62547,6 +62875,11 @@ index 0000000..b81db5b
+ return;
+}
+
++umode_t gr_acl_umask(void)
++{
++ return 0;
++}
++
+__u32
+gr_acl_handle_mknod(const struct dentry * new_dentry,
+ const struct dentry * parent_dentry,
@@ -66602,10 +66935,10 @@ index 297df45..b6a74ff 100644
struct blk_integrity *integrity;
diff --git a/include/linux/gracl.h b/include/linux/gracl.h
new file mode 100644
-index 0000000..0dc3943
+index 0000000..af663cf
--- /dev/null
+++ b/include/linux/gracl.h
-@@ -0,0 +1,317 @@
+@@ -0,0 +1,319 @@
+#ifndef GR_ACL_H
+#define GR_ACL_H
+
@@ -66617,8 +66950,8 @@ index 0000000..0dc3943
+
+/* Major status information */
+
-+#define GR_VERSION "grsecurity 2.2.2"
-+#define GRSECURITY_VERSION 0x2202
++#define GR_VERSION "grsecurity 2.9"
++#define GRSECURITY_VERSION 0x2900
+
+enum {
+ GR_SHUTDOWN = 0,
@@ -66781,6 +67114,8 @@ index 0000000..0dc3943
+ uid_t *domain_children;
+ __u16 domain_child_num;
+
++ mode_t umask;
++
+ struct acl_subject_label **subj_hash;
+ __u32 subj_hash_size;
+};
@@ -67311,10 +67646,10 @@ index 0000000..3826b91
+#endif
diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h
new file mode 100644
-index 0000000..8b9ed56
+index 0000000..f885406
--- /dev/null
+++ b/include/linux/grmsg.h
-@@ -0,0 +1,110 @@
+@@ -0,0 +1,109 @@
+#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
+#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
@@ -67358,7 +67693,6 @@ index 0000000..8b9ed56
+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
+#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
-+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
@@ -67427,7 +67761,7 @@ index 0000000..8b9ed56
+#define GR_BADPROCPID_MSG "denied read of sensitive /proc/pid/%s entry via fd passed across exec by "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..bb1e366
+index 0000000..c1793ae
--- /dev/null
+++ b/include/linux/grsecurity.h
@@ -0,0 +1,219 @@
@@ -67492,6 +67826,8 @@ index 0000000..bb1e366
+void gr_handle_ioperm(void);
+void gr_handle_iopl(void);
+
++umode_t gr_acl_umask(void);
++
+int gr_tpe_allow(const struct file *file);
+
+void gr_set_chroot_entries(struct task_struct *task, struct path *path);
@@ -67549,10 +67885,8 @@ index 0000000..bb1e366
+ const struct vfsmount *mnt);
+__u32 gr_acl_handle_access(const struct dentry *dentry,
+ const struct vfsmount *mnt, const int fmode);
-+__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, mode_t mode);
+__u32 gr_acl_handle_chmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, mode_t mode);
++ const struct vfsmount *mnt, umode_t *mode);
+__u32 gr_acl_handle_chown(const struct dentry *dentry,
+ const struct vfsmount *mnt);
+__u32 gr_acl_handle_setxattr(const struct dentry *dentry,
@@ -68568,18 +68902,19 @@ index 34066ff..e95d744 100644
/********** include/linux/timer.h **********/
/*
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
-index 4f71bf4..77ffa64 100644
+index 4f71bf4..cd2f68e 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
-@@ -67,7 +67,7 @@ struct k_itimer {
- };
+@@ -82,7 +82,8 @@ struct k_clock {
+ #define TIMER_RETRY 1
+ void (*timer_get) (struct k_itimer * timr,
+ struct itimerspec * cur_setting);
+-};
++} __do_const;
++typedef struct k_clock __no_const k_clock_no_const;
+
+ void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock);
- struct k_clock {
-- int res; /* in nanoseconds */
-+ const int res; /* in nanoseconds */
- int (*clock_getres) (const clockid_t which_clock, struct timespec *tp);
- int (*clock_set) (const clockid_t which_clock, struct timespec * tp);
- int (*clock_get) (const clockid_t which_clock, struct timespec * tp);
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 72b1a10..13303a9 100644
--- a/include/linux/preempt.h
@@ -68787,7 +69122,7 @@ index 3392c59..a746428 100644
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
/**
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 71849bf..03ceae8 100644
+index 71849bf..2ef383dc3 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -101,6 +101,7 @@ struct bio;
@@ -68922,7 +69257,7 @@ index 71849bf..03ceae8 100644
+#ifdef CONFIG_GRKERNSEC
+ /* grsecurity */
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ long long exec_id;
++ u64 exec_id;
+#endif
+#ifdef CONFIG_GRKERNSEC_SETXID
+ const struct cred *delayed_cred;
@@ -69130,7 +69465,7 @@ index d40d23f..d739b08 100644
static inline int security_settime(struct timespec *ts, struct timezone *tz)
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
-index 8366d8f..898f3c6 100644
+index 8366d8f..cc5f9d6 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -23,6 +23,9 @@ struct seq_file {
@@ -69138,7 +69473,7 @@ index 8366d8f..898f3c6 100644
struct mutex lock;
const struct seq_operations *op;
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ long long exec_id;
++ u64 exec_id;
+#endif
void *private;
};
@@ -71985,7 +72320,7 @@ index 0f8fae3..9344a56 100644
get_task_struct(p);
read_unlock(&tasklist_lock);
diff --git a/kernel/fork.c b/kernel/fork.c
-index 4bde56f..a07de53 100644
+index 4bde56f..29a9bab 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -253,7 +253,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
@@ -72083,20 +72418,16 @@ index 4bde56f..a07de53 100644
retval = copy_creds(p, clone_flags);
if (retval < 0)
-@@ -1183,6 +1214,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
+@@ -1183,6 +1214,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
goto bad_fork_free_pid;
}
+ gr_copy_label(p);
+
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ p->exec_id = current->exec_id;
-+#endif
-+
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
* Clear TID on mm_release()?
-@@ -1333,6 +1370,8 @@ bad_fork_cleanup_count:
+@@ -1333,6 +1366,8 @@ bad_fork_cleanup_count:
bad_fork_free:
free_task(p);
fork_out:
@@ -72105,7 +72436,7 @@ index 4bde56f..a07de53 100644
return ERR_PTR(retval);
}
-@@ -1426,6 +1465,8 @@ long do_fork(unsigned long clone_flags,
+@@ -1426,6 +1461,8 @@ long do_fork(unsigned long clone_flags,
if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr);
@@ -72114,7 +72445,7 @@ index 4bde56f..a07de53 100644
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
-@@ -1558,7 +1599,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+@@ -1558,7 +1595,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
return 0;
/* don't need lock here; in the worst case we'll do useless copy */
@@ -72123,7 +72454,7 @@ index 4bde56f..a07de53 100644
return 0;
*new_fsp = copy_fs_struct(fs);
-@@ -1681,7 +1722,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
+@@ -1681,7 +1718,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
fs = current->fs;
write_lock(&fs->lock);
current->fs = new_fs;
@@ -77705,7 +78036,7 @@ index 2d846cf..98134d2 100644
capable(CAP_IPC_LOCK))
ret = do_mlockall(flags);
diff --git a/mm/mmap.c b/mm/mmap.c
-index 4b80cbf..c5ce1df 100644
+index 4b80cbf..cd3731c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -45,6 +45,16 @@
@@ -78332,20 +78663,60 @@ index 4b80cbf..c5ce1df 100644
}
unsigned long
-@@ -1545,6 +1771,27 @@ out:
- return prev ? prev->vm_next : vma;
- }
+@@ -1510,40 +1736,41 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+ EXPORT_SYMBOL(find_vma);
+
+-/* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */
++/*
++ * Same as find_vma, but also return a pointer to the previous VMA in *pprev.
++ * Note: pprev is set to NULL when return value is NULL.
++ */
+ struct vm_area_struct *
+ find_vma_prev(struct mm_struct *mm, unsigned long addr,
+ struct vm_area_struct **pprev)
+ {
+- struct vm_area_struct *vma = NULL, *prev = NULL;
+- struct rb_node *rb_node;
+- if (!mm)
+- goto out;
++ struct vm_area_struct *vma;
+
+- /* Guard against addr being lower than the first VMA */
+- vma = mm->mmap;
++ vma = find_vma(mm, addr);
++ *pprev = vma ? vma->vm_prev : NULL;
++ return vma;
++}
+
+- /* Go through the RB tree quickly. */
+- rb_node = mm->mm_rb.rb_node;
+#ifdef CONFIG_PAX_SEGMEXEC
+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
+{
+ struct vm_area_struct *vma_m;
-+
+
+- while (rb_node) {
+- struct vm_area_struct *vma_tmp;
+- vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb);
+-
+- if (addr < vma_tmp->vm_end) {
+- rb_node = rb_node->rb_left;
+- } else {
+- prev = vma_tmp;
+- if (!prev->vm_next || (addr < prev->vm_next->vm_end))
+- break;
+- rb_node = rb_node->rb_right;
+- }
+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
+ BUG_ON(vma->vm_mirror);
+ return NULL;
-+ }
+ }
+-
+-out:
+- *pprev = prev;
+- return prev ? prev->vm_next : vma;
+ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
+ vma_m = vma->vm_mirror;
+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
@@ -78354,13 +78725,12 @@ index 4b80cbf..c5ce1df 100644
+ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_RESERVED));
+ return vma_m;
-+}
+ }
+#endif
-+
+
/*
* Verify that the stack growth is acceptable and
- * update accounting. This is shared with both the
-@@ -1561,6 +1808,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
+@@ -1561,6 +1788,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
return -ENOMEM;
/* Stack limit test */
@@ -78368,7 +78738,7 @@ index 4b80cbf..c5ce1df 100644
if (size > rlim[RLIMIT_STACK].rlim_cur)
return -ENOMEM;
-@@ -1570,6 +1818,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
+@@ -1570,6 +1798,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
unsigned long limit;
locked = mm->locked_vm + grow;
limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
@@ -78376,7 +78746,7 @@ index 4b80cbf..c5ce1df 100644
if (locked > limit && !capable(CAP_IPC_LOCK))
return -ENOMEM;
}
-@@ -1600,37 +1849,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
+@@ -1600,37 +1829,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
* PA-RISC uses this for its stack; IA64 for its Register Backing Store.
* vma is the last one with address > vma->vm_end. Have to extend vma.
*/
@@ -78434,7 +78804,7 @@ index 4b80cbf..c5ce1df 100644
unsigned long size, grow;
size = address - vma->vm_start;
-@@ -1643,6 +1903,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
+@@ -1643,6 +1883,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
vma->vm_end = address;
}
}
@@ -78443,7 +78813,7 @@ index 4b80cbf..c5ce1df 100644
anon_vma_unlock(vma);
return error;
}
-@@ -1655,6 +1917,8 @@ static int expand_downwards(struct vm_area_struct *vma,
+@@ -1655,6 +1897,8 @@ static int expand_downwards(struct vm_area_struct *vma,
unsigned long address)
{
int error;
@@ -78452,7 +78822,7 @@ index 4b80cbf..c5ce1df 100644
/*
* We must make sure the anon_vma is allocated
-@@ -1668,6 +1932,15 @@ static int expand_downwards(struct vm_area_struct *vma,
+@@ -1668,6 +1912,15 @@ static int expand_downwards(struct vm_area_struct *vma,
if (error)
return error;
@@ -78468,7 +78838,7 @@ index 4b80cbf..c5ce1df 100644
anon_vma_lock(vma);
/*
-@@ -1677,9 +1950,17 @@ static int expand_downwards(struct vm_area_struct *vma,
+@@ -1677,9 +1930,17 @@ static int expand_downwards(struct vm_area_struct *vma,
*/
/* Somebody else might have raced and expanded it already */
@@ -78487,7 +78857,7 @@ index 4b80cbf..c5ce1df 100644
size = vma->vm_end - address;
grow = (vma->vm_start - address) >> PAGE_SHIFT;
-@@ -1689,10 +1970,22 @@ static int expand_downwards(struct vm_area_struct *vma,
+@@ -1689,10 +1950,22 @@ static int expand_downwards(struct vm_area_struct *vma,
if (!error) {
vma->vm_start = address;
vma->vm_pgoff -= grow;
@@ -78510,7 +78880,7 @@ index 4b80cbf..c5ce1df 100644
return error;
}
-@@ -1768,6 +2061,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
+@@ -1768,6 +2041,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
do {
long nrpages = vma_pages(vma);
@@ -78524,7 +78894,7 @@ index 4b80cbf..c5ce1df 100644
mm->total_vm -= nrpages;
vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
vma = remove_vma(vma);
-@@ -1813,6 +2113,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -1813,6 +2093,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
insertion_point = (prev ? &prev->vm_next : &mm->mmap);
vma->vm_prev = NULL;
do {
@@ -78541,7 +78911,7 @@ index 4b80cbf..c5ce1df 100644
rb_erase(&vma->vm_rb, &mm->mm_rb);
mm->map_count--;
tail_vma = vma;
-@@ -1840,10 +2150,25 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1840,10 +2130,25 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
struct mempolicy *pol;
struct vm_area_struct *new;
@@ -78567,7 +78937,7 @@ index 4b80cbf..c5ce1df 100644
if (mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
-@@ -1851,6 +2176,16 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1851,6 +2156,16 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
if (!new)
return -ENOMEM;
@@ -78584,7 +78954,7 @@ index 4b80cbf..c5ce1df 100644
/* most fields are the same, copy all, and then fixup */
*new = *vma;
-@@ -1861,8 +2196,29 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1861,8 +2176,29 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
}
@@ -78614,7 +78984,7 @@ index 4b80cbf..c5ce1df 100644
kmem_cache_free(vm_area_cachep, new);
return PTR_ERR(pol);
}
-@@ -1883,6 +2239,28 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1883,6 +2219,28 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
else
vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
@@ -78643,7 +79013,7 @@ index 4b80cbf..c5ce1df 100644
return 0;
}
-@@ -1891,11 +2269,30 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1891,11 +2249,30 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
* work. This now handles partial unmappings.
* Jeremy Fitzhardinge <jeremy@goop.org>
*/
@@ -78674,7 +79044,7 @@ index 4b80cbf..c5ce1df 100644
if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
return -EINVAL;
-@@ -1959,6 +2356,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
+@@ -1959,6 +2336,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
/* Fix up all other VM information */
remove_vma_list(mm, vma);
@@ -78683,7 +79053,7 @@ index 4b80cbf..c5ce1df 100644
return 0;
}
-@@ -1971,22 +2370,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+@@ -1971,22 +2350,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
profile_munmap(addr);
@@ -78712,7 +79082,7 @@ index 4b80cbf..c5ce1df 100644
/*
* this is really a simplified "do_mmap". it only handles
* anonymous maps. eventually we may be able to do some
-@@ -2000,6 +2395,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2000,6 +2375,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
int error;
@@ -78720,7 +79090,7 @@ index 4b80cbf..c5ce1df 100644
len = PAGE_ALIGN(len);
if (!len)
-@@ -2011,16 +2407,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2011,16 +2387,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
@@ -78752,7 +79122,7 @@ index 4b80cbf..c5ce1df 100644
locked += mm->locked_vm;
lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
lock_limit >>= PAGE_SHIFT;
-@@ -2037,22 +2447,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2037,22 +2427,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
/*
* Clear old maps. this also does some error checking for us
*/
@@ -78779,7 +79149,7 @@ index 4b80cbf..c5ce1df 100644
return -ENOMEM;
/* Can we just expand an old private anonymous mapping? */
-@@ -2066,7 +2476,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2066,7 +2456,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (!vma) {
@@ -78788,7 +79158,7 @@ index 4b80cbf..c5ce1df 100644
return -ENOMEM;
}
-@@ -2078,11 +2488,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2078,11 +2468,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
vma->vm_page_prot = vm_get_page_prot(flags);
vma_link(mm, vma, prev, rb_link, rb_parent);
out:
@@ -78803,7 +79173,7 @@ index 4b80cbf..c5ce1df 100644
return addr;
}
-@@ -2129,8 +2540,10 @@ void exit_mmap(struct mm_struct *mm)
+@@ -2129,8 +2520,10 @@ void exit_mmap(struct mm_struct *mm)
* Walk the list again, actually closing and freeing it,
* with preemption enabled, without holding any MM locks.
*/
@@ -78815,7 +79185,7 @@ index 4b80cbf..c5ce1df 100644
BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
}
-@@ -2144,6 +2557,10 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+@@ -2144,6 +2537,10 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
struct vm_area_struct * __vma, * prev;
struct rb_node ** rb_link, * rb_parent;
@@ -78826,7 +79196,7 @@ index 4b80cbf..c5ce1df 100644
/*
* The vm_pgoff of a purely anonymous vma should be irrelevant
* until its first write fault, when page's anon_vma and index
-@@ -2166,7 +2583,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+@@ -2166,7 +2563,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
if ((vma->vm_flags & VM_ACCOUNT) &&
security_vm_enough_memory_mm(mm, vma_pages(vma)))
return -ENOMEM;
@@ -78849,7 +79219,7 @@ index 4b80cbf..c5ce1df 100644
return 0;
}
-@@ -2184,6 +2616,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2184,6 +2596,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
struct rb_node **rb_link, *rb_parent;
struct mempolicy *pol;
@@ -78858,7 +79228,7 @@ index 4b80cbf..c5ce1df 100644
/*
* If anonymous vma has not yet been faulted, update new pgoff
* to match new location, to increase its chance of merging.
-@@ -2227,6 +2661,35 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2227,6 +2641,35 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
return new_vma;
}
@@ -78894,7 +79264,7 @@ index 4b80cbf..c5ce1df 100644
/*
* Return true if the calling process may expand its vm space by the passed
* number of pages
-@@ -2237,7 +2700,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
+@@ -2237,7 +2680,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
unsigned long lim;
lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
@@ -78903,7 +79273,7 @@ index 4b80cbf..c5ce1df 100644
if (cur + npages > lim)
return 0;
return 1;
-@@ -2307,6 +2770,22 @@ int install_special_mapping(struct mm_struct *mm,
+@@ -2307,6 +2750,22 @@ int install_special_mapping(struct mm_struct *mm,
vma->vm_start = addr;
vma->vm_end = addr + len;
@@ -86584,7 +86954,7 @@ index 79633ea..9732e90 100644
}
diff --git a/tools/gcc/Makefile b/tools/gcc/Makefile
new file mode 100644
-index 0000000..b044b80
+index 0000000..29b6b75
--- /dev/null
+++ b/tools/gcc/Makefile
@@ -0,0 +1,21 @@
@@ -86592,9 +86962,9 @@ index 0000000..b044b80
+#PLUGIN_SOURCE_FILES := pax_plugin.c
+#PLUGIN_OBJECT_FILES := $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES))
+GCCPLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
-+#CFLAGS += -I$(GCCPLUGINS_DIR)/include -fPIC -O2 -Wall -W
++#CFLAGS += -I$(GCCPLUGINS_DIR)/include -fPIC -O2 -Wall -W -std=gnu99
+
-+HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include
++HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include -std=gnu99
+
+hostlibs-y := constify_plugin.so
+hostlibs-$(CONFIG_PAX_MEMORY_STACKLEAK) += stackleak_plugin.so
@@ -87270,10 +87640,10 @@ index 0000000..a5eabce
+}
diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
new file mode 100644
-index 0000000..51f747e
+index 0000000..008f159
--- /dev/null
+++ b/tools/gcc/kernexec_plugin.c
-@@ -0,0 +1,348 @@
+@@ -0,0 +1,427 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -87321,13 +87691,32 @@ index 0000000..51f747e
+ .help = "method=[bts|or]\tinstrumentation method\n"
+};
+
++static unsigned int execute_kernexec_reload(void);
+static unsigned int execute_kernexec_fptr(void);
+static unsigned int execute_kernexec_retaddr(void);
+static bool kernexec_cmodel_check(void);
+
-+static void (*kernexec_instrument_fptr)(gimple_stmt_iterator);
++static void (*kernexec_instrument_fptr)(gimple_stmt_iterator *);
+static void (*kernexec_instrument_retaddr)(rtx);
+
++static struct gimple_opt_pass kernexec_reload_pass = {
++ .pass = {
++ .type = GIMPLE_PASS,
++ .name = "kernexec_reload",
++ .gate = kernexec_cmodel_check,
++ .execute = execute_kernexec_reload,
++ .sub = NULL,
++ .next = NULL,
++ .static_pass_number = 0,
++ .tv_id = TV_NONE,
++ .properties_required = 0,
++ .properties_provided = 0,
++ .properties_destroyed = 0,
++ .todo_flags_start = 0,
++ .todo_flags_finish = TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_remove_unused_locals | TODO_update_ssa_no_phi
++ }
++};
++
+static struct gimple_opt_pass kernexec_fptr_pass = {
+ .pass = {
+ .type = GIMPLE_PASS,
@@ -87383,15 +87772,66 @@ index 0000000..51f747e
+}
+
+/*
++ * add special KERNEXEC instrumentation: reload %r10 after it has been clobbered
++ */
++static void kernexec_reload_fptr_mask(gimple_stmt_iterator *gsi)
++{
++ gimple asm_movabs_stmt;
++
++ // build asm volatile("movabs $0x8000000000000000, %%r10\n\t" : : : );
++ asm_movabs_stmt = gimple_build_asm_vec("movabs $0x8000000000000000, %%r10\n\t", NULL, NULL, NULL, NULL);
++ gimple_asm_set_volatile(asm_movabs_stmt, true);
++ gsi_insert_after(gsi, asm_movabs_stmt, GSI_CONTINUE_LINKING);
++ update_stmt(asm_movabs_stmt);
++}
++
++/*
++ * find all asm() stmts that clobber r10 and add a reload of r10
++ */
++static unsigned int execute_kernexec_reload(void)
++{
++ basic_block bb;
++
++ // 1. loop through BBs and GIMPLE statements
++ FOR_EACH_BB(bb) {
++ gimple_stmt_iterator gsi;
++
++ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
++ // gimple match: __asm__ ("" : : : "r10");
++ gimple asm_stmt;
++ size_t nclobbers;
++
++ // is it an asm ...
++ asm_stmt = gsi_stmt(gsi);
++ if (gimple_code(asm_stmt) != GIMPLE_ASM)
++ continue;
++
++ // ... clobbering r10
++ nclobbers = gimple_asm_nclobbers(asm_stmt);
++ while (nclobbers--) {
++ tree op = gimple_asm_clobber_op(asm_stmt, nclobbers);
++ if (strcmp(TREE_STRING_POINTER(TREE_VALUE(op)), "r10"))
++ continue;
++ kernexec_reload_fptr_mask(&gsi);
++//print_gimple_stmt(stderr, asm_stmt, 0, TDF_LINENO);
++ break;
++ }
++ }
++ }
++
++ return 0;
++}
++
++/*
+ * add special KERNEXEC instrumentation: force MSB of fptr to 1, which will produce
+ * a non-canonical address from a userland ptr and will just trigger a GPF on dereference
+ */
-+static void kernexec_instrument_fptr_bts(gimple_stmt_iterator gsi)
++static void kernexec_instrument_fptr_bts(gimple_stmt_iterator *gsi)
+{
+ gimple assign_intptr, assign_new_fptr, call_stmt;
+ tree intptr, old_fptr, new_fptr, kernexec_mask;
+
-+ call_stmt = gsi_stmt(gsi);
++ call_stmt = gsi_stmt(*gsi);
+ old_fptr = gimple_call_fn(call_stmt);
+
+ // create temporary unsigned long variable used for bitops and cast fptr to it
@@ -87399,14 +87839,14 @@ index 0000000..51f747e
+ add_referenced_var(intptr);
+ mark_sym_for_renaming(intptr);
+ assign_intptr = gimple_build_assign(intptr, fold_convert(long_unsigned_type_node, old_fptr));
-+ gsi_insert_before(&gsi, assign_intptr, GSI_SAME_STMT);
++ gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT);
+ update_stmt(assign_intptr);
+
+ // apply logical or to temporary unsigned long and bitmask
+ kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0x8000000000000000LL);
+// kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0xffffffff80000000LL);
+ assign_intptr = gimple_build_assign(intptr, fold_build2(BIT_IOR_EXPR, long_long_unsigned_type_node, intptr, kernexec_mask));
-+ gsi_insert_before(&gsi, assign_intptr, GSI_SAME_STMT);
++ gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT);
+ update_stmt(assign_intptr);
+
+ // cast temporary unsigned long back to a temporary fptr variable
@@ -87414,7 +87854,7 @@ index 0000000..51f747e
+ add_referenced_var(new_fptr);
+ mark_sym_for_renaming(new_fptr);
+ assign_new_fptr = gimple_build_assign(new_fptr, fold_convert(TREE_TYPE(old_fptr), intptr));
-+ gsi_insert_before(&gsi, assign_new_fptr, GSI_SAME_STMT);
++ gsi_insert_before(gsi, assign_new_fptr, GSI_SAME_STMT);
+ update_stmt(assign_new_fptr);
+
+ // replace call stmt fn with the new fptr
@@ -87422,14 +87862,14 @@ index 0000000..51f747e
+ update_stmt(call_stmt);
+}
+
-+static void kernexec_instrument_fptr_or(gimple_stmt_iterator gsi)
++static void kernexec_instrument_fptr_or(gimple_stmt_iterator *gsi)
+{
+ gimple asm_or_stmt, call_stmt;
+ tree old_fptr, new_fptr, input, output;
+ VEC(tree, gc) *inputs = NULL;
+ VEC(tree, gc) *outputs = NULL;
+
-+ call_stmt = gsi_stmt(gsi);
++ call_stmt = gsi_stmt(*gsi);
+ old_fptr = gimple_call_fn(call_stmt);
+
+ // create temporary fptr variable
@@ -87446,7 +87886,7 @@ index 0000000..51f747e
+ VEC_safe_push(tree, gc, outputs, output);
+ asm_or_stmt = gimple_build_asm_vec("orq %%r10, %0\n\t", inputs, outputs, NULL, NULL);
+ gimple_asm_set_volatile(asm_or_stmt, true);
-+ gsi_insert_before(&gsi, asm_or_stmt, GSI_SAME_STMT);
++ gsi_insert_before(gsi, asm_or_stmt, GSI_SAME_STMT);
+ update_stmt(asm_or_stmt);
+
+ // replace call stmt fn with the new fptr
@@ -87460,10 +87900,11 @@ index 0000000..51f747e
+static unsigned int execute_kernexec_fptr(void)
+{
+ basic_block bb;
-+ gimple_stmt_iterator gsi;
+
+ // 1. loop through BBs and GIMPLE statements
+ FOR_EACH_BB(bb) {
++ gimple_stmt_iterator gsi;
++
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
+ // gimple match: h_1 = get_fptr (); D.2709_3 = h_1 (x_2(D));
+ tree fn;
@@ -87490,7 +87931,7 @@ index 0000000..51f747e
+ if (TREE_CODE(fn) != FUNCTION_TYPE)
+ continue;
+
-+ kernexec_instrument_fptr(gsi);
++ kernexec_instrument_fptr(&gsi);
+
+//debug_tree(gimple_call_fn(call_stmt));
+//print_gimple_stmt(stderr, call_stmt, 0, TDF_LINENO);
@@ -87572,6 +88013,12 @@ index 0000000..51f747e
+ const int argc = plugin_info->argc;
+ const struct plugin_argument * const argv = plugin_info->argv;
+ int i;
++ struct register_pass_info kernexec_reload_pass_info = {
++ .pass = &kernexec_reload_pass.pass,
++ .reference_pass_name = "ssa",
++ .ref_pass_instance_number = 0,
++ .pos_op = PASS_POS_INSERT_AFTER
++ };
+ struct register_pass_info kernexec_fptr_pass_info = {
+ .pass = &kernexec_fptr_pass.pass,
+ .reference_pass_name = "ssa",
@@ -87617,6 +88064,8 @@ index 0000000..51f747e
+ if (!kernexec_instrument_fptr || !kernexec_instrument_retaddr)
+ error(G_("no instrumentation method was selected via '-fplugin-arg-%s-method'"), plugin_name);
+
++ if (kernexec_instrument_fptr == kernexec_instrument_fptr_or)
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &kernexec_reload_pass_info);
+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &kernexec_fptr_pass_info);
+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &kernexec_retaddr_pass_info);
+
@@ -87624,10 +88073,10 @@ index 0000000..51f747e
+}
diff --git a/tools/gcc/stackleak_plugin.c b/tools/gcc/stackleak_plugin.c
new file mode 100644
-index 0000000..d44f37c
+index 0000000..8b61031
--- /dev/null
+++ b/tools/gcc/stackleak_plugin.c
-@@ -0,0 +1,291 @@
+@@ -0,0 +1,295 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -87727,7 +88176,7 @@ index 0000000..d44f37c
+ return track_frame_size >= 0;
+}
+
-+static void stackleak_check_alloca(gimple_stmt_iterator gsi)
++static void stackleak_check_alloca(gimple_stmt_iterator *gsi)
+{
+ gimple check_alloca;
+ tree fndecl, fntype, alloca_size;
@@ -87736,12 +88185,12 @@ index 0000000..d44f37c
+ fntype = build_function_type_list(void_type_node, long_unsigned_type_node, NULL_TREE);
+ fndecl = build_fn_decl(check_function, fntype);
+ DECL_ASSEMBLER_NAME(fndecl); // for LTO
-+ alloca_size = gimple_call_arg(gsi_stmt(gsi), 0);
++ alloca_size = gimple_call_arg(gsi_stmt(*gsi), 0);
+ check_alloca = gimple_build_call(fndecl, 1, alloca_size);
-+ gsi_insert_before(&gsi, check_alloca, GSI_CONTINUE_LINKING);
++ gsi_insert_before(gsi, check_alloca, GSI_SAME_STMT);
+}
+
-+static void stackleak_add_instrumentation(gimple_stmt_iterator gsi)
++static void stackleak_add_instrumentation(gimple_stmt_iterator *gsi)
+{
+ gimple track_stack;
+ tree fndecl, fntype;
@@ -87751,7 +88200,7 @@ index 0000000..d44f37c
+ fndecl = build_fn_decl(track_function, fntype);
+ DECL_ASSEMBLER_NAME(fndecl); // for LTO
+ track_stack = gimple_build_call(fndecl, 0);
-+ gsi_insert_after(&gsi, track_stack, GSI_CONTINUE_LINKING);
++ gsi_insert_after(gsi, track_stack, GSI_CONTINUE_LINKING);
+}
+
+#if BUILDING_GCC_VERSION == 4005
@@ -87794,16 +88243,17 @@ index 0000000..d44f37c
+ // 1. loop through BBs and GIMPLE statements
+ FOR_EACH_BB(bb) {
+ gimple_stmt_iterator gsi;
++
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
+ // gimple match: align 8 built-in BUILT_IN_NORMAL:BUILT_IN_ALLOCA attributes <tree_list 0xb7576450>
+ if (!is_alloca(gsi_stmt(gsi)))
+ continue;
+
+ // 2. insert stack overflow check before each __builtin_alloca call
-+ stackleak_check_alloca(gsi);
++ stackleak_check_alloca(&gsi);
+
+ // 3. insert track call after each __builtin_alloca call
-+ stackleak_add_instrumentation(gsi);
++ stackleak_add_instrumentation(&gsi);
+ if (bb == entry_bb)
+ prologue_instrumented = true;
+ }
@@ -87811,10 +88261,13 @@ index 0000000..d44f37c
+
+ // 4. insert track call at the beginning
+ if (!prologue_instrumented) {
++ gimple_stmt_iterator gsi;
++
+ bb = split_block_after_labels(ENTRY_BLOCK_PTR)->dest;
+ if (dom_info_available_p(CDI_DOMINATORS))
+ set_immediate_dominator(CDI_DOMINATORS, bb, ENTRY_BLOCK_PTR);
-+ stackleak_add_instrumentation(gsi_start_bb(bb));
++ gsi = gsi_start_bb(bb);
++ stackleak_add_instrumentation(&gsi);
+ }
+
+ return 0;
diff --git a/3.2.6/0000_README b/3.2.7/0000_README
index 0295121..7342063 100644
--- a/3.2.6/0000_README
+++ b/3.2.7/0000_README
@@ -2,7 +2,11 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-2.2.2-3.2.6-201202131824.patch
+Patch: 1006_linux-3.2.7.patch
+From: http://www.kernel.org
+Desc: Linux 3.2.7
+
+Patch: 4420_grsecurity-2.9-3.2.7-201202251203.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.7/1006_linux-3.2.7.patch b/3.2.7/1006_linux-3.2.7.patch
new file mode 100644
index 0000000..08a6ba3
--- /dev/null
+++ b/3.2.7/1006_linux-3.2.7.patch
@@ -0,0 +1,994 @@
+diff --git a/Makefile b/Makefile
+index 47fe496..d1bdc90 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 2
+-SUBLEVEL = 6
++SUBLEVEL = 7
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+
+diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
+index 492ade8..d99346e 100644
+--- a/arch/x86/pci/xen.c
++++ b/arch/x86/pci/xen.c
+@@ -374,7 +374,7 @@ int __init pci_xen_init(void)
+
+ int __init pci_xen_hvm_init(void)
+ {
+- if (!xen_feature(XENFEAT_hvm_pirqs))
++ if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
+ return 0;
+
+ #ifdef CONFIG_ACPI
+diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
+index 88f160b..107f6f7 100644
+--- a/crypto/sha512_generic.c
++++ b/crypto/sha512_generic.c
+@@ -31,11 +31,6 @@ static inline u64 Maj(u64 x, u64 y, u64 z)
+ return (x & y) | (z & (x | y));
+ }
+
+-static inline u64 RORu64(u64 x, u64 y)
+-{
+- return (x >> y) | (x << (64 - y));
+-}
+-
+ static const u64 sha512_K[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+@@ -66,10 +61,10 @@ static const u64 sha512_K[80] = {
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
+ };
+
+-#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
+-#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
+-#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
+-#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
++#define e0(x) (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39))
++#define e1(x) (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41))
++#define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
++#define s1(x) (ror64(x,19) ^ ror64(x,61) ^ (x >> 6))
+
+ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+ {
+@@ -78,7 +73,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+
+ static inline void BLEND_OP(int I, u64 *W)
+ {
+- W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
++ W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
+ }
+
+ static void
+@@ -89,46 +84,42 @@ sha512_transform(u64 *state, const u8 *input)
+ int i;
+ u64 W[16];
+
+- /* load the input */
+- for (i = 0; i < 16; i++)
+- LOAD_OP(i, W, input);
+-
+ /* load the state into our registers */
+ a=state[0]; b=state[1]; c=state[2]; d=state[3];
+ e=state[4]; f=state[5]; g=state[6]; h=state[7];
+
+-#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \
+- t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \
+- t2 = e0(a) + Maj(a, b, c); \
+- d += t1; \
+- h = t1 + t2
+-
+-#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \
+- BLEND_OP(i, W); \
+- t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \
+- t2 = e0(a) + Maj(a, b, c); \
+- d += t1; \
+- h = t1 + t2
+-
+- for (i = 0; i < 16; i += 8) {
+- SHA512_0_15(i, a, b, c, d, e, f, g, h);
+- SHA512_0_15(i + 1, h, a, b, c, d, e, f, g);
+- SHA512_0_15(i + 2, g, h, a, b, c, d, e, f);
+- SHA512_0_15(i + 3, f, g, h, a, b, c, d, e);
+- SHA512_0_15(i + 4, e, f, g, h, a, b, c, d);
+- SHA512_0_15(i + 5, d, e, f, g, h, a, b, c);
+- SHA512_0_15(i + 6, c, d, e, f, g, h, a, b);
+- SHA512_0_15(i + 7, b, c, d, e, f, g, h, a);
+- }
+- for (i = 16; i < 80; i += 8) {
+- SHA512_16_79(i, a, b, c, d, e, f, g, h);
+- SHA512_16_79(i + 1, h, a, b, c, d, e, f, g);
+- SHA512_16_79(i + 2, g, h, a, b, c, d, e, f);
+- SHA512_16_79(i + 3, f, g, h, a, b, c, d, e);
+- SHA512_16_79(i + 4, e, f, g, h, a, b, c, d);
+- SHA512_16_79(i + 5, d, e, f, g, h, a, b, c);
+- SHA512_16_79(i + 6, c, d, e, f, g, h, a, b);
+- SHA512_16_79(i + 7, b, c, d, e, f, g, h, a);
++ /* now iterate */
++ for (i=0; i<80; i+=8) {
++ if (!(i & 8)) {
++ int j;
++
++ if (i < 16) {
++ /* load the input */
++ for (j = 0; j < 16; j++)
++ LOAD_OP(i + j, W, input);
++ } else {
++ for (j = 0; j < 16; j++) {
++ BLEND_OP(i + j, W);
++ }
++ }
++ }
++
++ t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[(i & 15)];
++ t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
++ t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1];
++ t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
++ t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2];
++ t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
++ t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3];
++ t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
++ t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4];
++ t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
++ t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5];
++ t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
++ t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6];
++ t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
++ t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7];
++ t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
+ }
+
+ state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index db3b461..94f860c 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -208,17 +208,8 @@ intel_dp_link_clock(uint8_t link_bw)
+ */
+
+ static int
+-intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp)
++intel_dp_link_required(int pixel_clock, int bpp)
+ {
+- struct drm_crtc *crtc = intel_dp->base.base.crtc;
+- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+- int bpp = 24;
+-
+- if (check_bpp)
+- bpp = check_bpp;
+- else if (intel_crtc)
+- bpp = intel_crtc->bpp;
+-
+ return (pixel_clock * bpp + 9) / 10;
+ }
+
+@@ -245,12 +236,11 @@ intel_dp_mode_valid(struct drm_connector *connector,
+ return MODE_PANEL;
+ }
+
+- mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0);
++ mode_rate = intel_dp_link_required(mode->clock, 24);
+ max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+
+ if (mode_rate > max_rate) {
+- mode_rate = intel_dp_link_required(intel_dp,
+- mode->clock, 18);
++ mode_rate = intel_dp_link_required(mode->clock, 18);
+ if (mode_rate > max_rate)
+ return MODE_CLOCK_HIGH;
+ else
+@@ -683,7 +673,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+ int lane_count, clock;
+ int max_lane_count = intel_dp_max_lane_count(intel_dp);
+ int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
+- int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0;
++ int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+ static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
+
+ if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
+@@ -701,7 +691,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+ for (clock = 0; clock <= max_clock; clock++) {
+ int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
+
+- if (intel_dp_link_required(intel_dp, mode->clock, bpp)
++ if (intel_dp_link_required(mode->clock, bpp)
+ <= link_avail) {
+ intel_dp->link_bw = bws[clock];
+ intel_dp->lane_count = lane_count;
+diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
+index e441911..b83f745 100644
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -694,6 +694,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
+ },
+ {
+ .callback = intel_no_lvds_dmi_callback,
++ .ident = "AOpen i45GMx-I",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
++ DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
++ },
++ },
++ {
++ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Aopen i945GTt-VFA",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
+diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
+index 95cbfb3..e4ab491 100644
+--- a/drivers/hwmon/f75375s.c
++++ b/drivers/hwmon/f75375s.c
+@@ -159,7 +159,7 @@ static inline void f75375_write8(struct i2c_client *client, u8 reg,
+ static inline void f75375_write16(struct i2c_client *client, u8 reg,
+ u16 value)
+ {
+- int err = i2c_smbus_write_byte_data(client, reg, (value << 8));
++ int err = i2c_smbus_write_byte_data(client, reg, (value >> 8));
+ if (err)
+ return;
+ i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
+@@ -311,7 +311,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
+ fanmode |= (3 << FAN_CTRL_MODE(nr));
+ break;
+ case 2: /* AUTOMATIC*/
+- fanmode |= (2 << FAN_CTRL_MODE(nr));
++ fanmode |= (1 << FAN_CTRL_MODE(nr));
+ break;
+ case 3: /* fan speed */
+ break;
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index a7ee502..72bc756 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -965,11 +965,14 @@ static void atmci_start_request(struct atmel_mci *host,
+ host->data_status = 0;
+
+ if (host->need_reset) {
++ iflags = atmci_readl(host, ATMCI_IMR);
++ iflags &= (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB);
+ atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
+ atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
+ atmci_writel(host, ATMCI_MR, host->mode_reg);
+ if (host->caps.has_cfg_reg)
+ atmci_writel(host, ATMCI_CFG, host->cfg_reg);
++ atmci_writel(host, ATMCI_IER, iflags);
+ host->need_reset = false;
+ }
+ atmci_writel(host, ATMCI_SDCR, slot->sdc_reg);
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index 3aaeb08..baf3d42 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -22,7 +22,6 @@
+ #include <linux/ioport.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+-#include <linux/scatterlist.h>
+ #include <linux/seq_file.h>
+ #include <linux/slab.h>
+ #include <linux/stat.h>
+@@ -502,8 +501,14 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
+ host->dir_status = DW_MCI_SEND_STATUS;
+
+ if (dw_mci_submit_data_dma(host, data)) {
++ int flags = SG_MITER_ATOMIC;
++ if (host->data->flags & MMC_DATA_READ)
++ flags |= SG_MITER_TO_SG;
++ else
++ flags |= SG_MITER_FROM_SG;
++
++ sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
+ host->sg = data->sg;
+- host->pio_offset = 0;
+ host->part_buf_start = 0;
+ host->part_buf_count = 0;
+
+@@ -953,6 +958,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
+ * generates a block interrupt, hence setting
+ * the scatter-gather pointer to NULL.
+ */
++ sg_miter_stop(&host->sg_miter);
+ host->sg = NULL;
+ ctrl = mci_readl(host, CTRL);
+ ctrl |= SDMMC_CTRL_FIFO_RESET;
+@@ -1286,54 +1292,44 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt)
+
+ static void dw_mci_read_data_pio(struct dw_mci *host)
+ {
+- struct scatterlist *sg = host->sg;
+- void *buf = sg_virt(sg);
+- unsigned int offset = host->pio_offset;
++ struct sg_mapping_iter *sg_miter = &host->sg_miter;
++ void *buf;
++ unsigned int offset;
+ struct mmc_data *data = host->data;
+ int shift = host->data_shift;
+ u32 status;
+ unsigned int nbytes = 0, len;
++ unsigned int remain, fcnt;
+
+ do {
+- len = host->part_buf_count +
+- (SDMMC_GET_FCNT(mci_readl(host, STATUS)) << shift);
+- if (offset + len <= sg->length) {
++ if (!sg_miter_next(sg_miter))
++ goto done;
++
++ host->sg = sg_miter->__sg;
++ buf = sg_miter->addr;
++ remain = sg_miter->length;
++ offset = 0;
++
++ do {
++ fcnt = (SDMMC_GET_FCNT(mci_readl(host, STATUS))
++ << shift) + host->part_buf_count;
++ len = min(remain, fcnt);
++ if (!len)
++ break;
+ dw_mci_pull_data(host, (void *)(buf + offset), len);
+-
+ offset += len;
+ nbytes += len;
+-
+- if (offset == sg->length) {
+- flush_dcache_page(sg_page(sg));
+- host->sg = sg = sg_next(sg);
+- if (!sg)
+- goto done;
+-
+- offset = 0;
+- buf = sg_virt(sg);
+- }
+- } else {
+- unsigned int remaining = sg->length - offset;
+- dw_mci_pull_data(host, (void *)(buf + offset),
+- remaining);
+- nbytes += remaining;
+-
+- flush_dcache_page(sg_page(sg));
+- host->sg = sg = sg_next(sg);
+- if (!sg)
+- goto done;
+-
+- offset = len - remaining;
+- buf = sg_virt(sg);
+- dw_mci_pull_data(host, buf, offset);
+- nbytes += offset;
+- }
++ remain -= len;
++ } while (remain);
++ sg_miter->consumed = offset;
+
+ status = mci_readl(host, MINTSTS);
+ mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
+ if (status & DW_MCI_DATA_ERROR_FLAGS) {
+ host->data_status = status;
+ data->bytes_xfered += nbytes;
++ sg_miter_stop(sg_miter);
++ host->sg = NULL;
+ smp_wmb();
+
+ set_bit(EVENT_DATA_ERROR, &host->pending_events);
+@@ -1342,65 +1338,66 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
+ return;
+ }
+ } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
+- host->pio_offset = offset;
+ data->bytes_xfered += nbytes;
++
++ if (!remain) {
++ if (!sg_miter_next(sg_miter))
++ goto done;
++ sg_miter->consumed = 0;
++ }
++ sg_miter_stop(sg_miter);
+ return;
+
+ done:
+ data->bytes_xfered += nbytes;
++ sg_miter_stop(sg_miter);
++ host->sg = NULL;
+ smp_wmb();
+ set_bit(EVENT_XFER_COMPLETE, &host->pending_events);
+ }
+
+ static void dw_mci_write_data_pio(struct dw_mci *host)
+ {
+- struct scatterlist *sg = host->sg;
+- void *buf = sg_virt(sg);
+- unsigned int offset = host->pio_offset;
++ struct sg_mapping_iter *sg_miter = &host->sg_miter;
++ void *buf;
++ unsigned int offset;
+ struct mmc_data *data = host->data;
+ int shift = host->data_shift;
+ u32 status;
+ unsigned int nbytes = 0, len;
++ unsigned int fifo_depth = host->fifo_depth;
++ unsigned int remain, fcnt;
+
+ do {
+- len = ((host->fifo_depth -
+- SDMMC_GET_FCNT(mci_readl(host, STATUS))) << shift)
+- - host->part_buf_count;
+- if (offset + len <= sg->length) {
++ if (!sg_miter_next(sg_miter))
++ goto done;
++
++ host->sg = sg_miter->__sg;
++ buf = sg_miter->addr;
++ remain = sg_miter->length;
++ offset = 0;
++
++ do {
++ fcnt = ((fifo_depth -
++ SDMMC_GET_FCNT(mci_readl(host, STATUS)))
++ << shift) - host->part_buf_count;
++ len = min(remain, fcnt);
++ if (!len)
++ break;
+ host->push_data(host, (void *)(buf + offset), len);
+-
+ offset += len;
+ nbytes += len;
+- if (offset == sg->length) {
+- host->sg = sg = sg_next(sg);
+- if (!sg)
+- goto done;
+-
+- offset = 0;
+- buf = sg_virt(sg);
+- }
+- } else {
+- unsigned int remaining = sg->length - offset;
+-
+- host->push_data(host, (void *)(buf + offset),
+- remaining);
+- nbytes += remaining;
+-
+- host->sg = sg = sg_next(sg);
+- if (!sg)
+- goto done;
+-
+- offset = len - remaining;
+- buf = sg_virt(sg);
+- host->push_data(host, (void *)buf, offset);
+- nbytes += offset;
+- }
++ remain -= len;
++ } while (remain);
++ sg_miter->consumed = offset;
+
+ status = mci_readl(host, MINTSTS);
+ mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
+ if (status & DW_MCI_DATA_ERROR_FLAGS) {
+ host->data_status = status;
+ data->bytes_xfered += nbytes;
++ sg_miter_stop(sg_miter);
++ host->sg = NULL;
+
+ smp_wmb();
+
+@@ -1410,12 +1407,20 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
+ return;
+ }
+ } while (status & SDMMC_INT_TXDR); /* if TXDR write again */
+- host->pio_offset = offset;
+ data->bytes_xfered += nbytes;
++
++ if (!remain) {
++ if (!sg_miter_next(sg_miter))
++ goto done;
++ sg_miter->consumed = 0;
++ }
++ sg_miter_stop(sg_miter);
+ return;
+
+ done:
+ data->bytes_xfered += nbytes;
++ sg_miter_stop(sg_miter);
++ host->sg = NULL;
+ smp_wmb();
+ set_bit(EVENT_XFER_COMPLETE, &host->pending_events);
+ }
+@@ -1618,6 +1623,7 @@ static void dw_mci_work_routine_card(struct work_struct *work)
+ * block interrupt, hence setting the
+ * scatter-gather pointer to NULL.
+ */
++ sg_miter_stop(&host->sg_miter);
+ host->sg = NULL;
+
+ ctrl = mci_readl(host, CTRL);
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index ced5444..222954d 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -4965,7 +4965,8 @@ static int igb_find_enabled_vfs(struct igb_adapter *adapter)
+ vf_devfn = pdev->devfn + 0x80;
+ pvfdev = pci_get_device(hw->vendor_id, device_id, NULL);
+ while (pvfdev) {
+- if (pvfdev->devfn == vf_devfn)
++ if (pvfdev->devfn == vf_devfn &&
++ (pvfdev->bus->number >= pdev->bus->number))
+ vfs_found++;
+ vf_devfn += vf_stride;
+ pvfdev = pci_get_device(hw->vendor_id,
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+index 00fcd39..e571356 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+@@ -67,7 +67,8 @@ static int ixgbe_find_enabled_vfs(struct ixgbe_adapter *adapter)
+ vf_devfn = pdev->devfn + 0x80;
+ pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID, device_id, NULL);
+ while (pvfdev) {
+- if (pvfdev->devfn == vf_devfn)
++ if (pvfdev->devfn == vf_devfn &&
++ (pvfdev->bus->number >= pdev->bus->number))
+ vfs_found++;
+ vf_devfn += 2;
+ pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID,
+diff --git a/drivers/net/ethernet/toshiba/Kconfig b/drivers/net/ethernet/toshiba/Kconfig
+index 0517647..74acb5c 100644
+--- a/drivers/net/ethernet/toshiba/Kconfig
++++ b/drivers/net/ethernet/toshiba/Kconfig
+@@ -5,7 +5,7 @@
+ config NET_VENDOR_TOSHIBA
+ bool "Toshiba devices"
+ default y
+- depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB) || PPC_PS3
++ depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB || MIPS) || PPC_PS3
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
+index 8873c6e..8b0c2ca 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1034,13 +1034,16 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
+
+ /*
+ * Workaround for early ACK timeouts, add an offset to match the
+- * initval's 64us ack timeout value.
++ * initval's 64us ack timeout value. Use 48us for the CTS timeout.
+ * This was initially only meant to work around an issue with delayed
+ * BA frames in some implementations, but it has been found to fix ACK
+ * timeout issues in other cases as well.
+ */
+- if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
++ if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) {
+ acktimeout += 64 - sifstime - ah->slottime;
++ ctstimeout += 48 - sifstime - ah->slottime;
++ }
++
+
+ ath9k_hw_set_sifs_time(ah, sifstime);
+ ath9k_hw_setslottime(ah, slottime);
+diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
+index d4c909f..57622e0 100644
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -775,6 +775,11 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
+ ARRAY_SIZE(ath9k_tpt_blink));
+ #endif
+
++ INIT_WORK(&sc->hw_reset_work, ath_reset_work);
++ INIT_WORK(&sc->hw_check_work, ath_hw_check);
++ INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
++ INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
++
+ /* Register with mac80211 */
+ error = ieee80211_register_hw(hw);
+ if (error)
+@@ -793,10 +798,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
+ goto error_world;
+ }
+
+- INIT_WORK(&sc->hw_reset_work, ath_reset_work);
+- INIT_WORK(&sc->hw_check_work, ath_hw_check);
+- INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+- INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
+ sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
+
+ ath_init_leds(sc);
+diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
+index 67b862c..2f3aeac 100644
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -824,6 +824,14 @@ static bool ath9k_rx_accept(struct ath_common *common,
+ (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
+ ATH9K_RXERR_KEYMISS));
+
++ /*
++ * Key miss events are only relevant for pairwise keys where the
++ * descriptor does contain a valid key index. This has been observed
++ * mostly with CCMP encryption.
++ */
++ if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
++ rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
++
+ if (!rx_stats->rs_datalen)
+ return false;
+ /*
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 63e4be4..720edf5 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -756,10 +756,11 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+ cifs_dump_mem("Bad SMB: ", buf,
+ min_t(unsigned int, server->total_read, 48));
+
+- if (mid)
+- handle_mid(mid, server, smb_buffer, length);
++ if (!mid)
++ return length;
+
+- return length;
++ handle_mid(mid, server, smb_buffer, length);
++ return 0;
+ }
+
+ static int
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index d7eeb9d..e4c3334 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -492,7 +492,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
+ {
+ int xid;
+ int rc = 0; /* to get around spurious gcc warning, set to zero here */
+- __u32 oplock = 0;
++ __u32 oplock = enable_oplocks ? REQ_OPLOCK : 0;
+ __u16 fileHandle = 0;
+ bool posix_open = false;
+ struct cifs_sb_info *cifs_sb;
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 517f211..54f5786 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -48,14 +48,6 @@ struct wb_writeback_work {
+ };
+
+ /*
+- * Include the creation of the trace points after defining the
+- * wb_writeback_work structure so that the definition remains local to this
+- * file.
+- */
+-#define CREATE_TRACE_POINTS
+-#include <trace/events/writeback.h>
+-
+-/*
+ * We don't actually have pdflush, but this one is exported though /proc...
+ */
+ int nr_pdflush_threads;
+@@ -87,6 +79,14 @@ static inline struct inode *wb_inode(struct list_head *head)
+ return list_entry(head, struct inode, i_wb_list);
+ }
+
++/*
++ * Include the creation of the trace points after defining the
++ * wb_writeback_work structure and inline functions so that the definition
++ * remains local to this file.
++ */
++#define CREATE_TRACE_POINTS
++#include <trace/events/writeback.h>
++
+ /* Wakeup flusher thread or forker thread to fork it. Requires bdi->wb_lock. */
+ static void bdi_wakeup_flusher(struct backing_dev_info *bdi)
+ {
+diff --git a/include/linux/bitops.h b/include/linux/bitops.h
+index a3ef66a..fc8a3ff 100644
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -50,6 +50,26 @@ static inline unsigned long hweight_long(unsigned long w)
+ }
+
+ /**
++ * rol64 - rotate a 64-bit value left
++ * @word: value to rotate
++ * @shift: bits to roll
++ */
++static inline __u64 rol64(__u64 word, unsigned int shift)
++{
++ return (word << shift) | (word >> (64 - shift));
++}
++
++/**
++ * ror64 - rotate a 64-bit value right
++ * @word: value to rotate
++ * @shift: bits to roll
++ */
++static inline __u64 ror64(__u64 word, unsigned int shift)
++{
++ return (word >> shift) | (word << (64 - shift));
++}
++
++/**
+ * rol32 - rotate a 32-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
+index 6dc9b80..107fcb3 100644
+--- a/include/linux/mmc/dw_mmc.h
++++ b/include/linux/mmc/dw_mmc.h
+@@ -14,6 +14,8 @@
+ #ifndef LINUX_MMC_DW_MMC_H
+ #define LINUX_MMC_DW_MMC_H
+
++#include <linux/scatterlist.h>
++
+ #define MAX_MCI_SLOTS 2
+
+ enum dw_mci_state {
+@@ -40,7 +42,7 @@ struct mmc_data;
+ * @lock: Spinlock protecting the queue and associated data.
+ * @regs: Pointer to MMIO registers.
+ * @sg: Scatterlist entry currently being processed by PIO code, if any.
+- * @pio_offset: Offset into the current scatterlist entry.
++ * @sg_miter: PIO mapping scatterlist iterator.
+ * @cur_slot: The slot which is currently using the controller.
+ * @mrq: The request currently being processed on @cur_slot,
+ * or NULL if the controller is idle.
+@@ -115,7 +117,7 @@ struct dw_mci {
+ void __iomem *regs;
+
+ struct scatterlist *sg;
+- unsigned int pio_offset;
++ struct sg_mapping_iter sg_miter;
+
+ struct dw_mci_slot *cur_slot;
+ struct mmc_request *mrq;
+diff --git a/include/linux/proportions.h b/include/linux/proportions.h
+index ef35bb7..26a8a4e 100644
+--- a/include/linux/proportions.h
++++ b/include/linux/proportions.h
+@@ -81,7 +81,11 @@ void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl)
+ * Limit the time part in order to ensure there are some bits left for the
+ * cycle counter and fraction multiply.
+ */
++#if BITS_PER_LONG == 32
+ #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4)
++#else
++#define PROP_MAX_SHIFT (BITS_PER_LONG/2)
++#endif
+
+ #define PROP_FRAC_SHIFT (BITS_PER_LONG - PROP_MAX_SHIFT - 1)
+ #define PROP_FRAC_BASE (1UL << PROP_FRAC_SHIFT)
+diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
+index 99d1d0d..1f48f14 100644
+--- a/include/trace/events/writeback.h
++++ b/include/trace/events/writeback.h
+@@ -47,7 +47,10 @@ DECLARE_EVENT_CLASS(writeback_work_class,
+ __field(int, reason)
+ ),
+ TP_fast_assign(
+- strncpy(__entry->name, dev_name(bdi->dev), 32);
++ struct device *dev = bdi->dev;
++ if (!dev)
++ dev = default_backing_dev_info.dev;
++ strncpy(__entry->name, dev_name(dev), 32);
+ __entry->nr_pages = work->nr_pages;
+ __entry->sb_dev = work->sb ? work->sb->s_dev : 0;
+ __entry->sync_mode = work->sync_mode;
+@@ -418,7 +421,7 @@ DECLARE_EVENT_CLASS(writeback_single_inode_template,
+
+ TP_fast_assign(
+ strncpy(__entry->name,
+- dev_name(inode->i_mapping->backing_dev_info->dev), 32);
++ dev_name(inode_to_bdi(inode)->dev), 32);
+ __entry->ino = inode->i_ino;
+ __entry->state = inode->i_state;
+ __entry->dirtied_when = inode->dirtied_when;
+diff --git a/kernel/relay.c b/kernel/relay.c
+index 226fade..b6f803a 100644
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -164,10 +164,14 @@ depopulate:
+ */
+ static struct rchan_buf *relay_create_buf(struct rchan *chan)
+ {
+- struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
+- if (!buf)
++ struct rchan_buf *buf;
++
++ if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
+ return NULL;
+
++ buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
++ if (!buf)
++ return NULL;
+ buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL);
+ if (!buf->padding)
+ goto free_buf;
+@@ -574,6 +578,8 @@ struct rchan *relay_open(const char *base_filename,
+
+ if (!(subbuf_size && n_subbufs))
+ return NULL;
++ if (subbuf_size > UINT_MAX / n_subbufs)
++ return NULL;
+
+ chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
+ if (!chan)
+diff --git a/mm/backing-dev.c b/mm/backing-dev.c
+index 71034f4..2b49dd2 100644
+--- a/mm/backing-dev.c
++++ b/mm/backing-dev.c
+@@ -318,7 +318,7 @@ static void wakeup_timer_fn(unsigned long data)
+ if (bdi->wb.task) {
+ trace_writeback_wake_thread(bdi);
+ wake_up_process(bdi->wb.task);
+- } else {
++ } else if (bdi->dev) {
+ /*
+ * When bdi tasks are inactive for long time, they are killed.
+ * In this case we have to wake-up the forker thread which
+@@ -584,6 +584,8 @@ EXPORT_SYMBOL(bdi_register_dev);
+ */
+ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
+ {
++ struct task_struct *task;
++
+ if (!bdi_cap_writeback_dirty(bdi))
+ return;
+
+@@ -604,9 +606,14 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
+ * unfreeze of the thread before calling kthread_stop(), otherwise
+ * it would never exet if it is currently stuck in the refrigerator.
+ */
+- if (bdi->wb.task) {
+- thaw_process(bdi->wb.task);
+- kthread_stop(bdi->wb.task);
++ spin_lock_bh(&bdi->wb_lock);
++ task = bdi->wb.task;
++ bdi->wb.task = NULL;
++ spin_unlock_bh(&bdi->wb_lock);
++
++ if (task) {
++ thaw_process(task);
++ kthread_stop(task);
+ }
+ }
+
+@@ -627,7 +634,9 @@ static void bdi_prune_sb(struct backing_dev_info *bdi)
+
+ void bdi_unregister(struct backing_dev_info *bdi)
+ {
+- if (bdi->dev) {
++ struct device *dev = bdi->dev;
++
++ if (dev) {
+ bdi_set_min_ratio(bdi, 0);
+ trace_writeback_bdi_unregister(bdi);
+ bdi_prune_sb(bdi);
+@@ -636,8 +645,12 @@ void bdi_unregister(struct backing_dev_info *bdi)
+ if (!bdi_cap_flush_forker(bdi))
+ bdi_wb_shutdown(bdi);
+ bdi_debug_unregister(bdi);
+- device_unregister(bdi->dev);
++
++ spin_lock_bh(&bdi->wb_lock);
+ bdi->dev = NULL;
++ spin_unlock_bh(&bdi->wb_lock);
++
++ device_unregister(dev);
+ }
+ }
+ EXPORT_SYMBOL(bdi_unregister);
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 5c51607..064d20f 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -616,7 +616,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
+ index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
+ tid_agg_rx->buf_size;
+ if (!tid_agg_rx->reorder_buf[index] &&
+- tid_agg_rx->stored_mpdu_num > 1) {
++ tid_agg_rx->stored_mpdu_num) {
+ /*
+ * No buffers ready to be released, but check whether any
+ * frames in the reorder buffer have timed out.
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 34e5fcc..9c197d4 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -4213,8 +4213,26 @@ enum {
+ PINFIX_PB_M5210,
+ PINFIX_ACER_ASPIRE_7736,
+ PINFIX_ASUS_W90V,
++ ALC889_FIXUP_DAC_ROUTE,
+ };
+
++/* Fix the connection of some pins for ALC889:
++ * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
++ * work correctly (bko#42740)
++ */
++static void alc889_fixup_dac_route(struct hda_codec *codec,
++ const struct alc_fixup *fix, int action)
++{
++ if (action == ALC_FIXUP_ACT_PRE_PROBE) {
++ hda_nid_t conn1[2] = { 0x0c, 0x0d };
++ hda_nid_t conn2[2] = { 0x0e, 0x0f };
++ snd_hda_override_conn_list(codec, 0x14, 2, conn1);
++ snd_hda_override_conn_list(codec, 0x15, 2, conn1);
++ snd_hda_override_conn_list(codec, 0x18, 2, conn2);
++ snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
++ }
++}
++
+ static const struct alc_fixup alc882_fixups[] = {
+ [PINFIX_ABIT_AW9D_MAX] = {
+ .type = ALC_FIXUP_PINS,
+@@ -4251,10 +4269,15 @@ static const struct alc_fixup alc882_fixups[] = {
+ { }
+ }
+ },
++ [ALC889_FIXUP_DAC_ROUTE] = {
++ .type = ALC_FIXUP_FUNC,
++ .v.func = alc889_fixup_dac_route,
++ },
+ };
+
+ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
++ SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
+ SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", PINFIX_ASUS_W90V),
+ SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
+ SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
+diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
+index a0a3f50..1fe1308 100644
+--- a/sound/pci/hda/patch_via.c
++++ b/sound/pci/hda/patch_via.c
+@@ -665,6 +665,9 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
+ /* init input-src */
+ for (i = 0; i < spec->num_adc_nids; i++) {
+ int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
++ /* secondary ADCs must have the unique MUX */
++ if (i > 0 && !spec->mux_nids[i])
++ break;
+ if (spec->mux_nids[adc_idx]) {
+ int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
+ snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
+diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
+index 11718b49..55f48fb 100644
+--- a/sound/pci/intel8x0.c
++++ b/sound/pci/intel8x0.c
+@@ -2102,6 +2102,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
+ },
+ {
+ .subvendor = 0x161f,
++ .subdevice = 0x202f,
++ .name = "Gateway M520",
++ .type = AC97_TUNE_INV_EAPD
++ },
++ {
++ .subvendor = 0x161f,
+ .subdevice = 0x203a,
+ .name = "Gateway 4525GZ", /* AD1981B */
+ .type = AC97_TUNE_INV_EAPD
+diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm.S b/tools/perf/bench/mem-memcpy-x86-64-asm.S
+index a57b66e..185a96d 100644
+--- a/tools/perf/bench/mem-memcpy-x86-64-asm.S
++++ b/tools/perf/bench/mem-memcpy-x86-64-asm.S
+@@ -1,2 +1,8 @@
+
+ #include "../../../arch/x86/lib/memcpy_64.S"
++/*
++ * We need to provide note.GNU-stack section, saying that we want
++ * NOT executable stack. Otherwise the final linking will assume that
++ * the ELF stack should not be restricted at all and set it RWX.
++ */
++.section .note.GNU-stack,"",@progbits
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index d7915d4..efca198 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -390,6 +390,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
+
+ data->cpu = data->pid = data->tid = -1;
+ data->stream_id = data->id = data->time = -1ULL;
++ data->period = 1;
+
+ if (event->header.type != PERF_RECORD_SAMPLE) {
+ if (!sample_id_all)
diff --git a/3.2.6/4420_grsecurity-2.2.2-3.2.6-201202131824.patch b/3.2.7/4420_grsecurity-2.9-3.2.7-201202251203.patch
index 2ac6312..be7621a 100644
--- a/3.2.6/4420_grsecurity-2.2.2-3.2.6-201202131824.patch
+++ b/3.2.7/4420_grsecurity-2.9-3.2.7-201202251203.patch
@@ -186,7 +186,7 @@ index 81c287f..d456d02 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 47fe496..c50bd2a 100644
+index d1bdc90..e95fe1a 100644
--- a/Makefile
+++ b/Makefile
@@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -366,6 +366,27 @@ index 47fe496..c50bd2a 100644
$(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(@:.ko=.o)
+diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
+index 640f909..48b6597 100644
+--- a/arch/alpha/include/asm/atomic.h
++++ b/arch/alpha/include/asm/atomic.h
+@@ -250,6 +250,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ #define atomic_dec(v) atomic_sub(1,(v))
+ #define atomic64_dec(v) atomic64_sub(1,(v))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #define smp_mb__before_atomic_dec() smp_mb()
+ #define smp_mb__after_atomic_dec() smp_mb()
+ #define smp_mb__before_atomic_inc() smp_mb()
diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
index da5449e..7418343 100644
--- a/arch/alpha/include/asm/elf.h
@@ -615,10 +636,21 @@ index fadd5f8..904e73a 100644
/* Allow reads even for write-only mappings */
if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
-index 86976d0..8a57797 100644
+index 86976d0..6610950 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
-@@ -239,6 +239,14 @@ typedef struct {
+@@ -15,6 +15,10 @@
+ #include <linux/types.h>
+ #include <asm/system.h>
+
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i) { (i) }
+
+ #ifdef __KERNEL__
+@@ -239,6 +243,14 @@ typedef struct {
u64 __aligned(8) counter;
} atomic64_t;
@@ -633,6 +665,23 @@ index 86976d0..8a57797 100644
#define ATOMIC64_INIT(i) { (i) }
static inline u64 atomic64_read(atomic64_t *v)
+@@ -459,6 +471,16 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+ #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* !CONFIG_GENERIC_ATOMIC64 */
+ #endif
+ #endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 0e9ce8d..6ef1e03 100644
--- a/arch/arm/include/asm/elf.h
@@ -1119,6 +1168,27 @@ index f7040a1..db9f300 100644
if (exception_trace && printk_ratelimit())
printk("%s%s[%d]: segfault at %08lx pc %08lx "
"sp %08lx ecr %lu\n",
+diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
+index 0d8a7d6..d0c9ff5 100644
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -241,6 +241,16 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v);
+ #define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter))
+ #define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ {
+ int c, old;
diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h
index f8e16b2..c73ff79 100644
--- a/arch/frv/include/asm/kmap_types.h
@@ -1163,6 +1233,27 @@ index 385fd30..6c3d97e 100644
goto success;
addr = vma->vm_end;
}
+diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
+index 3fad89e..3047da5 100644
+--- a/arch/ia64/include/asm/atomic.h
++++ b/arch/ia64/include/asm/atomic.h
+@@ -209,6 +209,16 @@ atomic64_add_negative (__s64 i, atomic64_t *v)
+ #define atomic64_inc(v) atomic64_add(1, (v))
+ #define atomic64_dec(v) atomic64_sub(1, (v))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ /* Atomic operations are already serializing */
+ #define smp_mb__before_atomic_dec() barrier()
+ #define smp_mb__after_atomic_dec() barrier()
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index b5298eb..67c6e62 100644
--- a/arch/ia64/include/asm/elf.h
@@ -1502,6 +1593,38 @@ index 82abd15..d95ae5d 100644
prefetchw(to);
if (access_ok(VERIFY_READ, from, n))
__copy_user_zeroing(to,from,n);
+diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
+index 1d93f81..67794d0 100644
+--- a/arch/mips/include/asm/atomic.h
++++ b/arch/mips/include/asm/atomic.h
+@@ -21,6 +21,10 @@
+ #include <asm/war.h>
+ #include <asm/system.h>
+
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i) { (i) }
+
+ /*
+@@ -765,6 +769,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ */
+ #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* CONFIG_64BIT */
+
+ /*
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index 455c0ac..ad65fbe 100644
--- a/arch/mips/include/asm/elf.h
@@ -1720,6 +1843,27 @@ index 302d779..7d35bf8 100644
-
- return ret;
-}
+diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
+index 4054b31..a10c105 100644
+--- a/arch/parisc/include/asm/atomic.h
++++ b/arch/parisc/include/asm/atomic.h
+@@ -335,6 +335,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* !CONFIG_64BIT */
+
+
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 19f6cb1..6c78cf2 100644
--- a/arch/parisc/include/asm/elf.h
@@ -2082,6 +2226,27 @@ index 18162ce..94de376 100644
/*
* If for any reason at all we couldn't handle the fault, make
+diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
+index 02e41b5..ec6e26c 100644
+--- a/arch/powerpc/include/asm/atomic.h
++++ b/arch/powerpc/include/asm/atomic.h
+@@ -469,6 +469,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* __powerpc64__ */
+
+ #endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 3bf9cca..e7457d0 100644
--- a/arch/powerpc/include/asm/elf.h
@@ -2909,6 +3074,27 @@ index 73709f7..6b90313 100644
/* If hint, make sure it matches our alignment restrictions */
if (!fixed && addr) {
addr = _ALIGN_UP(addr, 1ul << pshift);
+diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
+index 8517d2a..d2738d4 100644
+--- a/arch/s390/include/asm/atomic.h
++++ b/arch/s390/include/asm/atomic.h
+@@ -326,6 +326,16 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v)
+ #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0)
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #define smp_mb__before_atomic_dec() smp_mb()
+ #define smp_mb__after_atomic_dec() smp_mb()
+ #define smp_mb__before_atomic_inc() smp_mb()
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index 547f1a6..0b22b53 100644
--- a/arch/s390/include/asm/elf.h
@@ -3260,6 +3446,18 @@ index afeb710..d1d1289 100644
bottomup:
/*
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
+index f92602e..27060b2 100644
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -31,6 +31,7 @@ config SPARC
+
+ config SPARC32
+ def_bool !64BIT
++ select GENERIC_ATOMIC64
+
+ config SPARC64
+ def_bool 64BIT
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index ad1fb5d..fc5315b 100644
--- a/arch/sparc/Makefile
@@ -3273,6 +3471,17 @@ index ad1fb5d..fc5315b 100644
VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
VMLINUX_MAIN += $(drivers-y) $(net-y)
+diff --git a/arch/sparc/include/asm/atomic.h b/arch/sparc/include/asm/atomic.h
+index 8ff83d8..4a459c2 100644
+--- a/arch/sparc/include/asm/atomic.h
++++ b/arch/sparc/include/asm/atomic.h
+@@ -4,5 +4,6 @@
+ #include <asm/atomic_64.h>
+ #else
+ #include <asm/atomic_32.h>
++#include <asm-generic/atomic64.h>
+ #endif
+ #endif
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index 9f421df..b81fc12 100644
--- a/arch/sparc/include/asm/atomic_64.h
@@ -3512,6 +3721,19 @@ index 7df8b7f..4946269 100644
extern unsigned long sparc64_elf_hwcap;
#define ELF_HWCAP sparc64_elf_hwcap
+diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
+index 156707b..aefa786 100644
+--- a/arch/sparc/include/asm/page_32.h
++++ b/arch/sparc/include/asm/page_32.h
+@@ -8,6 +8,8 @@
+ #ifndef _SPARC_PAGE_H
+ #define _SPARC_PAGE_H
+
++#include <linux/const.h>
++
+ #define PAGE_SHIFT 12
+
+ #ifndef __ASSEMBLY__
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index a790cc6..091ed94 100644
--- a/arch/sparc/include/asm/pgtable_32.h
@@ -5487,6 +5709,27 @@ index cbef74e..c38fead 100644
BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
+diff --git a/arch/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h
+index 27fe667..36d474c 100644
+--- a/arch/tile/include/asm/atomic_64.h
++++ b/arch/tile/include/asm/atomic_64.h
+@@ -142,6 +142,16 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ /* Atomic dec and inc don't implement barrier, so provide them if needed. */
+ #define smp_mb__before_atomic_dec() smp_mb()
+ #define smp_mb__after_atomic_dec() smp_mb()
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 7730af6..cce5b19 100644
--- a/arch/um/Makefile
@@ -10910,7 +11153,7 @@ index 566e803..b9521e9 100644
}
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
-index 1c66d30..23ab77d 100644
+index 1c66d30..e66922c 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -10,6 +10,9 @@
@@ -10939,7 +11182,12 @@ index 1c66d30..23ab77d 100644
{
unsigned ret;
-@@ -36,138 +39,222 @@ copy_user_generic(void *to, const void *from, unsigned len)
+@@ -32,142 +35,226 @@ copy_user_generic(void *to, const void *from, unsigned len)
+ ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from),
+ "=d" (len)),
+ "1" (to), "2" (from), "3" (len)
+- : "memory", "rcx", "r8", "r9", "r10", "r11");
++ : "memory", "rcx", "r8", "r9", "r11");
return ret;
}
@@ -41441,7 +41689,7 @@ index 608c1c3..7d040a8 100644
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
-index 3625464..7949233 100644
+index 3625464..04855f9 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,12 +55,28 @@
@@ -41504,7 +41752,25 @@ index 3625464..7949233 100644
return NULL;
if (write) {
-@@ -274,6 +282,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+@@ -215,6 +223,17 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+ if (size <= ARG_MAX)
+ return page;
+
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++ // only allow 1MB for argv+env on suid/sgid binaries
++ // to prevent easy ASLR exhaustion
++ if (((bprm->cred->euid != current_euid()) ||
++ (bprm->cred->egid != current_egid())) &&
++ (size > (1024 * 1024))) {
++ put_page(page);
++ return NULL;
++ }
++#endif
++
+ /*
+ * Limit to 1/4-th the stack size for the argv+env strings.
+ * This ensures that:
+@@ -274,6 +293,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
vma->vm_end = STACK_TOP_MAX;
vma->vm_start = vma->vm_end - PAGE_SIZE;
vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
@@ -41516,7 +41782,7 @@ index 3625464..7949233 100644
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
INIT_LIST_HEAD(&vma->anon_vma_chain);
-@@ -288,6 +301,12 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+@@ -288,6 +312,12 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
mm->stack_vm = mm->total_vm = 1;
up_write(&mm->mmap_sem);
bprm->p = vma->vm_end - sizeof(void *);
@@ -41529,7 +41795,7 @@ index 3625464..7949233 100644
return 0;
err:
up_write(&mm->mmap_sem);
-@@ -396,19 +415,7 @@ err:
+@@ -396,19 +426,7 @@ err:
return err;
}
@@ -41550,7 +41816,7 @@ index 3625464..7949233 100644
{
const char __user *native;
-@@ -417,14 +424,14 @@ static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr)
+@@ -417,14 +435,14 @@ static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr)
compat_uptr_t compat;
if (get_user(compat, argv.ptr.compat + nr))
@@ -41567,7 +41833,7 @@ index 3625464..7949233 100644
return native;
}
-@@ -443,7 +450,7 @@ static int count(struct user_arg_ptr argv, int max)
+@@ -443,7 +461,7 @@ static int count(struct user_arg_ptr argv, int max)
if (!p)
break;
@@ -41576,7 +41842,7 @@ index 3625464..7949233 100644
return -EFAULT;
if (i++ >= max)
-@@ -477,7 +484,7 @@ static int copy_strings(int argc, struct user_arg_ptr argv,
+@@ -477,7 +495,7 @@ static int copy_strings(int argc, struct user_arg_ptr argv,
ret = -EFAULT;
str = get_user_arg_ptr(argv, argc);
@@ -41585,7 +41851,7 @@ index 3625464..7949233 100644
goto out;
len = strnlen_user(str, MAX_ARG_STRLEN);
-@@ -559,7 +566,7 @@ int copy_strings_kernel(int argc, const char *const *__argv,
+@@ -559,7 +577,7 @@ int copy_strings_kernel(int argc, const char *const *__argv,
int r;
mm_segment_t oldfs = get_fs();
struct user_arg_ptr argv = {
@@ -41594,7 +41860,7 @@ index 3625464..7949233 100644
};
set_fs(KERNEL_DS);
-@@ -594,7 +601,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+@@ -594,7 +612,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
unsigned long new_end = old_end - shift;
struct mmu_gather tlb;
@@ -41604,7 +41870,7 @@ index 3625464..7949233 100644
/*
* ensure there are no vmas between where we want to go
-@@ -603,6 +611,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+@@ -603,6 +622,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
if (vma != find_vma(mm, new_start))
return -EFAULT;
@@ -41615,7 +41881,7 @@ index 3625464..7949233 100644
/*
* cover the whole range: [new_start, old_end)
*/
-@@ -683,10 +695,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -683,10 +706,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
stack_top = arch_align_stack(stack_top);
stack_top = PAGE_ALIGN(stack_top);
@@ -41626,7 +41892,7 @@ index 3625464..7949233 100644
stack_shift = vma->vm_end - stack_top;
bprm->p -= stack_shift;
-@@ -698,8 +706,28 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -698,8 +717,28 @@ int setup_arg_pages(struct linux_binprm *bprm,
bprm->exec -= stack_shift;
down_write(&mm->mmap_sem);
@@ -41655,7 +41921,7 @@ index 3625464..7949233 100644
/*
* Adjust stack execute permissions; explicitly enable for
* EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X and leave alone
-@@ -718,13 +746,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -718,13 +757,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
goto out_unlock;
BUG_ON(prev != vma);
@@ -41669,7 +41935,7 @@ index 3625464..7949233 100644
/* mprotect_fixup is overkill to remove the temporary stack flags */
vma->vm_flags &= ~VM_STACK_INCOMPLETE_SETUP;
-@@ -805,7 +826,7 @@ int kernel_read(struct file *file, loff_t offset,
+@@ -805,7 +837,7 @@ int kernel_read(struct file *file, loff_t offset,
old_fs = get_fs();
set_fs(get_ds());
/* The cast to a user pointer is valid due to the set_fs() */
@@ -41678,7 +41944,7 @@ index 3625464..7949233 100644
set_fs(old_fs);
return result;
}
-@@ -1067,6 +1088,21 @@ void set_task_comm(struct task_struct *tsk, char *buf)
+@@ -1067,6 +1099,21 @@ void set_task_comm(struct task_struct *tsk, char *buf)
perf_event_comm(tsk);
}
@@ -41700,7 +41966,7 @@ index 3625464..7949233 100644
int flush_old_exec(struct linux_binprm * bprm)
{
int retval;
-@@ -1081,6 +1117,7 @@ int flush_old_exec(struct linux_binprm * bprm)
+@@ -1081,6 +1128,7 @@ int flush_old_exec(struct linux_binprm * bprm)
set_mm_exe_file(bprm->mm, bprm->file);
@@ -41708,7 +41974,7 @@ index 3625464..7949233 100644
/*
* Release all of the old mmap stuff
*/
-@@ -1112,10 +1149,6 @@ EXPORT_SYMBOL(would_dump);
+@@ -1112,10 +1160,6 @@ EXPORT_SYMBOL(would_dump);
void setup_new_exec(struct linux_binprm * bprm)
{
@@ -41719,7 +41985,7 @@ index 3625464..7949233 100644
arch_pick_mmap_layout(current->mm);
/* This is the point of no return */
-@@ -1126,18 +1159,7 @@ void setup_new_exec(struct linux_binprm * bprm)
+@@ -1126,18 +1170,7 @@ void setup_new_exec(struct linux_binprm * bprm)
else
set_dumpable(current->mm, suid_dumpable);
@@ -41739,7 +42005,7 @@ index 3625464..7949233 100644
/* Set the new mm task size. We have to do that late because it may
* depend on TIF_32BIT which is only updated in flush_thread() on
-@@ -1247,7 +1269,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
+@@ -1247,7 +1280,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
}
rcu_read_unlock();
@@ -41748,18 +42014,18 @@ index 3625464..7949233 100644
bprm->unsafe |= LSM_UNSAFE_SHARE;
} else {
res = -EAGAIN;
-@@ -1442,6 +1464,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
+@@ -1442,6 +1475,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
EXPORT_SYMBOL(search_binary_handler);
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+atomic64_unchecked_t global_exec_counter = ATOMIC64_INIT(0);
++static atomic64_unchecked_t global_exec_counter = ATOMIC64_INIT(0);
+#endif
+
/*
* sys_execve() executes a new program.
*/
-@@ -1450,6 +1476,11 @@ static int do_execve_common(const char *filename,
+@@ -1450,6 +1487,11 @@ static int do_execve_common(const char *filename,
struct user_arg_ptr envp,
struct pt_regs *regs)
{
@@ -41771,7 +42037,7 @@ index 3625464..7949233 100644
struct linux_binprm *bprm;
struct file *file;
struct files_struct *displaced;
-@@ -1457,6 +1488,8 @@ static int do_execve_common(const char *filename,
+@@ -1457,6 +1499,8 @@ static int do_execve_common(const char *filename,
int retval;
const struct cred *cred = current_cred();
@@ -41780,7 +42046,7 @@ index 3625464..7949233 100644
/*
* We move the actual failure in case of RLIMIT_NPROC excess from
* set*uid() to execve() because too many poorly written programs
-@@ -1497,12 +1530,27 @@ static int do_execve_common(const char *filename,
+@@ -1497,12 +1541,27 @@ static int do_execve_common(const char *filename,
if (IS_ERR(file))
goto out_unmark;
@@ -41808,7 +42074,7 @@ index 3625464..7949233 100644
retval = bprm_mm_init(bprm);
if (retval)
goto out_file;
-@@ -1532,11 +1580,46 @@ static int do_execve_common(const char *filename,
+@@ -1532,11 +1591,46 @@ static int do_execve_common(const char *filename,
if (retval < 0)
goto out;
@@ -41856,7 +42122,7 @@ index 3625464..7949233 100644
current->fs->in_exec = 0;
current->in_execve = 0;
acct_update_integrals(current);
-@@ -1545,6 +1628,14 @@ static int do_execve_common(const char *filename,
+@@ -1545,6 +1639,14 @@ static int do_execve_common(const char *filename,
put_files_struct(displaced);
return retval;
@@ -41871,7 +42137,7 @@ index 3625464..7949233 100644
out:
if (bprm->mm) {
acct_arg_size(bprm, 0);
-@@ -1618,7 +1709,7 @@ static int expand_corename(struct core_name *cn)
+@@ -1618,7 +1720,7 @@ static int expand_corename(struct core_name *cn)
{
char *old_corename = cn->corename;
@@ -41880,7 +42146,7 @@ index 3625464..7949233 100644
cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL);
if (!cn->corename) {
-@@ -1715,7 +1806,7 @@ static int format_corename(struct core_name *cn, long signr)
+@@ -1715,7 +1817,7 @@ static int format_corename(struct core_name *cn, long signr)
int pid_in_pattern = 0;
int err = 0;
@@ -41889,7 +42155,7 @@ index 3625464..7949233 100644
cn->corename = kmalloc(cn->size, GFP_KERNEL);
cn->used = 0;
-@@ -1812,6 +1903,218 @@ out:
+@@ -1812,6 +1914,218 @@ out:
return ispipe;
}
@@ -42108,7 +42374,7 @@ index 3625464..7949233 100644
static int zap_process(struct task_struct *start, int exit_code)
{
struct task_struct *t;
-@@ -2023,17 +2326,17 @@ static void wait_for_dump_helpers(struct file *file)
+@@ -2023,17 +2337,17 @@ static void wait_for_dump_helpers(struct file *file)
pipe = file->f_path.dentry->d_inode->i_pipe;
pipe_lock(pipe);
@@ -42131,7 +42397,7 @@ index 3625464..7949233 100644
pipe_unlock(pipe);
}
-@@ -2094,7 +2397,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2094,7 +2408,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
int retval = 0;
int flag = 0;
int ispipe;
@@ -42140,7 +42406,7 @@ index 3625464..7949233 100644
struct coredump_params cprm = {
.signr = signr,
.regs = regs,
-@@ -2109,6 +2412,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2109,6 +2423,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
audit_core_dumps(signr);
@@ -42150,7 +42416,7 @@ index 3625464..7949233 100644
binfmt = mm->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
-@@ -2176,7 +2482,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2176,7 +2493,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
}
cprm.limit = RLIM_INFINITY;
@@ -42159,7 +42425,7 @@ index 3625464..7949233 100644
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
task_tgid_vnr(current), current->comm);
-@@ -2203,6 +2509,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2203,6 +2520,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
} else {
struct inode *inode;
@@ -42168,7 +42434,7 @@ index 3625464..7949233 100644
if (cprm.limit < binfmt->min_coredump)
goto fail_unlock;
-@@ -2246,7 +2554,7 @@ close_fail:
+@@ -2246,7 +2565,7 @@ close_fail:
filp_close(cprm.file, NULL);
fail_dropcount:
if (ispipe)
@@ -42177,7 +42443,7 @@ index 3625464..7949233 100644
fail_unlock:
kfree(cn.corename);
fail_corename:
-@@ -2265,7 +2573,7 @@ fail:
+@@ -2265,7 +2584,7 @@ fail:
*/
int dump_write(struct file *file, const void *addr, int nr)
{
@@ -42536,7 +42802,7 @@ index 0845f84..7b4ebef 100644
if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
-index 78b519c..212c0d0 100644
+index 78b519c..a8b4979 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -4,6 +4,7 @@
@@ -42603,7 +42869,14 @@ index 78b519c..212c0d0 100644
spin_unlock(&fs->lock);
task_unlock(current);
-@@ -170,7 +178,7 @@ EXPORT_SYMBOL(current_umask);
+@@ -164,13 +172,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
+
+ int current_umask(void)
+ {
+- return current->fs->umask;
++ return current->fs->umask | gr_acl_umask();
+ }
+ EXPORT_SYMBOL(current_umask);
/* to be mentioned only in INIT_TASK */
struct fs_struct init_fs = {
@@ -44967,7 +45240,7 @@ index 5d22872..523db20 100644
kfree(link);
}
diff --git a/fs/open.c b/fs/open.c
-index 22c41b5..695cb17 100644
+index 22c41b5..78894cf 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -112,6 +112,10 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
@@ -45033,7 +45306,7 @@ index 22c41b5..695cb17 100644
return error;
mutex_lock(&inode->i_mutex);
+
-+ if (!gr_acl_handle_fchmod(path->dentry, path->mnt, mode)) {
++ if (!gr_acl_handle_chmod(path->dentry, path->mnt, &mode)) {
+ error = -EACCES;
+ goto out_unlock;
+ }
@@ -45394,7 +45667,7 @@ index 3a1dafd..1456746 100644
+}
+#endif
diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 1ace83d..357b933 100644
+index 1ace83d..f5e575d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -107,6 +107,22 @@ struct pid_entry {
@@ -45534,7 +45807,18 @@ index 1ace83d..357b933 100644
put_task_struct(task);
}
return allowed;
-@@ -797,6 +815,11 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
+@@ -786,6 +804,10 @@ static int mem_open(struct inode* inode, struct file* file)
+ file->f_mode |= FMODE_UNSIGNED_OFFSET;
+ file->private_data = mm;
+
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++ file->f_version = current->exec_id;
++#endif
++
+ return 0;
+ }
+
+@@ -797,6 +819,17 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
ssize_t copied;
char *page;
@@ -45542,11 +45826,17 @@ index 1ace83d..357b933 100644
+ if (write)
+ return -EPERM;
+#endif
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++ if (file->f_version != current->exec_id) {
++ gr_log_badprocpid("mem");
++ return 0;
++ }
++#endif
+
if (!mm)
return 0;
-@@ -897,6 +920,9 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+@@ -897,6 +930,9 @@ static ssize_t environ_read(struct file *file, char __user *buf,
if (!task)
goto out_no_task;
@@ -45556,7 +45846,7 @@ index 1ace83d..357b933 100644
ret = -ENOMEM;
page = (char *)__get_free_page(GFP_TEMPORARY);
if (!page)
-@@ -1519,7 +1545,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+@@ -1519,7 +1555,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
path_put(&nd->path);
/* Are we allowed to snoop on the tasks file descriptors? */
@@ -45565,7 +45855,7 @@ index 1ace83d..357b933 100644
goto out;
error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
-@@ -1558,8 +1584,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
+@@ -1558,8 +1594,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
struct path path;
/* Are we allowed to snoop on the tasks file descriptors? */
@@ -45586,7 +45876,7 @@ index 1ace83d..357b933 100644
error = PROC_I(inode)->op.proc_get_link(inode, &path);
if (error)
-@@ -1624,7 +1660,11 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t
+@@ -1624,7 +1670,11 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t
rcu_read_lock();
cred = __task_cred(task);
inode->i_uid = cred->euid;
@@ -45598,7 +45888,7 @@ index 1ace83d..357b933 100644
rcu_read_unlock();
}
security_task_to_inode(task, inode);
-@@ -1642,6 +1682,9 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+@@ -1642,6 +1692,9 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
struct inode *inode = dentry->d_inode;
struct task_struct *task;
const struct cred *cred;
@@ -45608,7 +45898,7 @@ index 1ace83d..357b933 100644
generic_fillattr(inode, stat);
-@@ -1649,13 +1692,41 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+@@ -1649,13 +1702,41 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
stat->uid = 0;
stat->gid = 0;
task = pid_task(proc_pid(inode), PIDTYPE_PID);
@@ -45651,7 +45941,7 @@ index 1ace83d..357b933 100644
}
rcu_read_unlock();
return 0;
-@@ -1692,11 +1763,20 @@ int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
+@@ -1692,11 +1773,20 @@ int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
if (task) {
if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
@@ -45672,7 +45962,7 @@ index 1ace83d..357b933 100644
rcu_read_unlock();
} else {
inode->i_uid = 0;
-@@ -1814,7 +1894,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
+@@ -1814,7 +1904,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
int fd = proc_fd(inode);
if (task) {
@@ -45682,7 +45972,7 @@ index 1ace83d..357b933 100644
put_task_struct(task);
}
if (files) {
-@@ -2082,11 +2163,21 @@ static const struct file_operations proc_fd_operations = {
+@@ -2082,11 +2173,21 @@ static const struct file_operations proc_fd_operations = {
*/
static int proc_fd_permission(struct inode *inode, int mask)
{
@@ -45706,7 +45996,7 @@ index 1ace83d..357b933 100644
return rv;
}
-@@ -2196,6 +2287,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
+@@ -2196,6 +2297,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
if (!task)
goto out_no_task;
@@ -45716,7 +46006,7 @@ index 1ace83d..357b933 100644
/*
* Yes, it does not scale. And it should not. Don't add
* new entries into /proc/<tgid>/ without very good reasons.
-@@ -2240,6 +2334,9 @@ static int proc_pident_readdir(struct file *filp,
+@@ -2240,6 +2344,9 @@ static int proc_pident_readdir(struct file *filp,
if (!task)
goto out_no_task;
@@ -45726,7 +46016,7 @@ index 1ace83d..357b933 100644
ret = 0;
i = filp->f_pos;
switch (i) {
-@@ -2510,7 +2607,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+@@ -2510,7 +2617,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
void *cookie)
{
@@ -45735,7 +46025,7 @@ index 1ace83d..357b933 100644
if (!IS_ERR(s))
__putname(s);
}
-@@ -2708,7 +2805,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2708,7 +2815,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
#endif
REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
@@ -45744,7 +46034,7 @@ index 1ace83d..357b933 100644
INF("syscall", S_IRUGO, proc_pid_syscall),
#endif
INF("cmdline", S_IRUGO, proc_pid_cmdline),
-@@ -2733,10 +2830,10 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2733,10 +2840,10 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -45757,7 +46047,7 @@ index 1ace83d..357b933 100644
ONE("stack", S_IRUGO, proc_pid_stack),
#endif
#ifdef CONFIG_SCHEDSTATS
-@@ -2770,6 +2867,9 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2770,6 +2877,9 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_HARDWALL
INF("hardwall", S_IRUGO, proc_pid_hardwall),
#endif
@@ -45767,7 +46057,7 @@ index 1ace83d..357b933 100644
};
static int proc_tgid_base_readdir(struct file * filp,
-@@ -2895,7 +2995,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
+@@ -2895,7 +3005,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
if (!inode)
goto out;
@@ -45782,7 +46072,7 @@ index 1ace83d..357b933 100644
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
-@@ -2937,7 +3044,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
+@@ -2937,7 +3054,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
if (!task)
goto out;
@@ -45794,7 +46084,7 @@ index 1ace83d..357b933 100644
put_task_struct(task);
out:
return result;
-@@ -3002,6 +3113,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+@@ -3002,6 +3123,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
unsigned int nr;
struct task_struct *reaper;
@@ -45806,7 +46096,7 @@ index 1ace83d..357b933 100644
struct tgid_iter iter;
struct pid_namespace *ns;
-@@ -3025,8 +3141,27 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+@@ -3025,8 +3151,27 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
for (iter = next_tgid(ns, iter);
iter.task;
iter.tgid += 1, iter = next_tgid(ns, iter)) {
@@ -45835,7 +46125,7 @@ index 1ace83d..357b933 100644
put_task_struct(iter.task);
goto out;
}
-@@ -3054,7 +3189,7 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3054,7 +3199,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
@@ -45844,7 +46134,7 @@ index 1ace83d..357b933 100644
INF("syscall", S_IRUGO, proc_pid_syscall),
#endif
INF("cmdline", S_IRUGO, proc_pid_cmdline),
-@@ -3078,10 +3213,10 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3078,10 +3223,10 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -46563,10 +46853,18 @@ index d33418f..2a5345e 100644
return -EINVAL;
diff --git a/fs/seq_file.c b/fs/seq_file.c
-index dba43c3..1dfaf14 100644
+index dba43c3..9fb8511 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
-@@ -40,6 +40,9 @@ int seq_open(struct file *file, const struct seq_operations *op)
+@@ -9,6 +9,7 @@
+ #include <linux/module.h>
+ #include <linux/seq_file.h>
+ #include <linux/slab.h>
++#include <linux/sched.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/page.h>
+@@ -40,6 +41,9 @@ int seq_open(struct file *file, const struct seq_operations *op)
memset(p, 0, sizeof(*p));
mutex_init(&p->lock);
p->op = op;
@@ -46576,7 +46874,7 @@ index dba43c3..1dfaf14 100644
/*
* Wrappers around seq_open(e.g. swaps_open) need to be
-@@ -76,7 +79,8 @@ static int traverse(struct seq_file *m, loff_t offset)
+@@ -76,7 +80,8 @@ static int traverse(struct seq_file *m, loff_t offset)
return 0;
}
if (!m->buf) {
@@ -46586,7 +46884,7 @@ index dba43c3..1dfaf14 100644
if (!m->buf)
return -ENOMEM;
}
-@@ -116,7 +120,8 @@ static int traverse(struct seq_file *m, loff_t offset)
+@@ -116,7 +121,8 @@ static int traverse(struct seq_file *m, loff_t offset)
Eoverflow:
m->op->stop(m, p);
kfree(m->buf);
@@ -46596,7 +46894,7 @@ index dba43c3..1dfaf14 100644
return !m->buf ? -ENOMEM : -EAGAIN;
}
-@@ -169,7 +174,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+@@ -169,7 +175,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
m->version = file->f_version;
/* grab buffer if we didn't have one */
if (!m->buf) {
@@ -46606,7 +46904,7 @@ index dba43c3..1dfaf14 100644
if (!m->buf)
goto Enomem;
}
-@@ -210,7 +216,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+@@ -210,7 +217,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
goto Fill;
m->op->stop(m, p);
kfree(m->buf);
@@ -46616,7 +46914,7 @@ index dba43c3..1dfaf14 100644
if (!m->buf)
goto Enomem;
m->count = 0;
-@@ -549,7 +556,7 @@ static void single_stop(struct seq_file *p, void *v)
+@@ -549,7 +557,7 @@ static void single_stop(struct seq_file *p, void *v)
int single_open(struct file *file, int (*show)(struct seq_file *, void *),
void *data)
{
@@ -47033,10 +47331,10 @@ index 23ce927..e274cc1 100644
kfree(s);
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..8faa28b
+index 0000000..41df561
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,1073 @@
+@@ -0,0 +1,1075 @@
+#
+# grecurity configuration
+#
@@ -47243,7 +47541,7 @@ index 0000000..8faa28b
+
+endchoice
+
-+menu "Address Space Protection"
++menu "Memory Protections"
+depends on GRKERNSEC
+
+config GRKERNSEC_KMEM
@@ -47300,7 +47598,7 @@ index 0000000..8faa28b
+ protect your kernel against modification, use the RBAC system.
+
+config GRKERNSEC_PROC_MEMMAP
-+ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
++ bool "Harden ASLR against information leaks and entropy reduction"
+ default y if (PAX_NOEXEC || PAX_ASLR)
+ depends on PAX_NOEXEC || PAX_ASLR
+ help
@@ -47311,9 +47609,11 @@ index 0000000..8faa28b
+ dangerous sources of information, this option causes reads of sensitive
+ /proc/<pid> entries where the file descriptor was opened in a different
+ task than the one performing the read. Such attempts are logged.
-+ If you use PaX it is greatly recommended that you say Y here as it
-+ closes up a hole that makes the full ASLR useless for suid
-+ binaries.
++ Finally, this option limits argv/env strings for suid/sgid binaries
++ to 1MB to prevent a complete exhaustion of the stack entropy provided
++ by ASLR.
++ If you use PaX it is essential that you say Y here as it closes up
++ several holes that make full ASLR useless for suid/sgid binaries.
+
+config GRKERNSEC_BRUTE
+ bool "Deter exploit bruteforcing"
@@ -48112,10 +48412,10 @@ index 0000000..8faa28b
+endmenu
diff --git a/grsecurity/Makefile b/grsecurity/Makefile
new file mode 100644
-index 0000000..1b9afa9
+index 0000000..496e60d
--- /dev/null
+++ b/grsecurity/Makefile
-@@ -0,0 +1,38 @@
+@@ -0,0 +1,40 @@
+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
+# during 2001-2009 it has been completely redesigned by Brad Spengler
+# into an RBAC system
@@ -48124,7 +48424,9 @@ index 0000000..1b9afa9
+# are copyright Brad Spengler - Open Source Security, Inc., and released
+# under the GPL v2 or higher
+
++ifndef CONFIG_IA64
+KBUILD_CFLAGS += -Werror
++endif
+
+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
+ grsec_mount.o grsec_sig.o grsec_sysctl.o \
@@ -48156,10 +48458,10 @@ index 0000000..1b9afa9
+endif
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
new file mode 100644
-index 0000000..6e989da
+index 0000000..7715893
--- /dev/null
+++ b/grsecurity/gracl.c
-@@ -0,0 +1,4163 @@
+@@ -0,0 +1,4164 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -50431,17 +50733,18 @@ index 0000000..6e989da
+void
+gr_copy_label(struct task_struct *tsk)
+{
++ /* plain copying of fields is already done by dup_task_struct */
+ tsk->signal->used_accept = 0;
+ tsk->acl_sp_role = 0;
-+ tsk->acl_role_id = current->acl_role_id;
-+ tsk->acl = current->acl;
-+ tsk->role = current->role;
++ //tsk->acl_role_id = current->acl_role_id;
++ //tsk->acl = current->acl;
++ //tsk->role = current->role;
+ tsk->signal->curr_ip = current->signal->curr_ip;
+ tsk->signal->saved_ip = current->signal->saved_ip;
+ if (current->exec_file)
+ get_file(current->exec_file);
-+ tsk->exec_file = current->exec_file;
-+ tsk->is_writable = current->is_writable;
++ //tsk->exec_file = current->exec_file;
++ //tsk->is_writable = current->is_writable;
+ if (unlikely(current->signal->used_accept)) {
+ current->signal->curr_ip = 0;
+ current->signal->saved_ip = 0;
@@ -50653,8 +50956,8 @@ index 0000000..6e989da
+
+ /* don't change the role if we're not a privileged process */
+ if (role && task->role != role &&
-+ (((role->roletype & GR_ROLE_USER) && gr_acl_is_capable(CAP_SETUID)) ||
-+ ((role->roletype & GR_ROLE_GROUP) && gr_acl_is_capable(CAP_SETGID))))
++ (((role->roletype & GR_ROLE_USER) && !gr_acl_is_capable(CAP_SETUID)) ||
++ ((role->roletype & GR_ROLE_GROUP) && !gr_acl_is_capable(CAP_SETGID))))
+ return;
+
+ /* perform subject lookup in possibly new role
@@ -52543,10 +52846,10 @@ index 0000000..955ddfb
+
diff --git a/grsecurity/gracl_fs.c b/grsecurity/gracl_fs.c
new file mode 100644
-index 0000000..4eda5c3
+index 0000000..88d0e87
--- /dev/null
+++ b/grsecurity/gracl_fs.c
-@@ -0,0 +1,433 @@
+@@ -0,0 +1,435 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
@@ -52557,6 +52860,15 @@ index 0000000..4eda5c3
+#include <linux/grinternal.h>
+#include <linux/gracl.h>
+
++umode_t
++gr_acl_umask(void)
++{
++ if (unlikely(!gr_acl_is_enabled()))
++ return 0;
++
++ return current->role->umask;
++}
++
+__u32
+gr_acl_handle_hidden_file(const struct dentry * dentry,
+ const struct vfsmount * mnt)
@@ -52745,25 +53057,18 @@ index 0000000..4eda5c3
+}
+
+__u32
-+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
-+ mode_t mode)
++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
++ umode_t *modeptr)
+{
++ umode_t mode;
++
++ *modeptr &= ~gr_acl_umask();
++ mode = *modeptr;
++
+ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
+ return 1;
+
-+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
-+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
-+ GR_FCHMOD_ACL_MSG);
-+ } else {
-+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
-+ }
-+}
-+
-+__u32
-+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
-+ mode_t mode)
-+{
-+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
++ if (unlikely(mode & (S_ISUID | S_ISGID))) {
+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
+ GR_CHMOD_ACL_MSG);
+ } else {
@@ -54389,10 +54694,10 @@ index 0000000..a2dc675
+}
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
new file mode 100644
-index 0000000..d81a586
+index 0000000..213ad8b
--- /dev/null
+++ b/grsecurity/grsec_disabled.c
-@@ -0,0 +1,439 @@
+@@ -0,0 +1,437 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -54632,15 +54937,8 @@ index 0000000..d81a586
+}
+
+__u32
-+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
-+ mode_t mode)
-+{
-+ return 1;
-+}
-+
-+__u32
+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
-+ mode_t mode)
++ umode_t *mode)
+{
+ return 1;
+}
@@ -54663,6 +54961,11 @@ index 0000000..d81a586
+ return;
+}
+
++umode_t gr_acl_umask(void)
++{
++ return 0;
++}
++
+__u32
+gr_acl_handle_mknod(const struct dentry * new_dentry,
+ const struct dentry * parent_dentry,
@@ -58245,10 +58548,10 @@ index 6d18f35..ab71e2c 100644
struct blk_integrity *integrity;
diff --git a/include/linux/gracl.h b/include/linux/gracl.h
new file mode 100644
-index 0000000..0dc3943
+index 0000000..8a130b6
--- /dev/null
+++ b/include/linux/gracl.h
-@@ -0,0 +1,317 @@
+@@ -0,0 +1,319 @@
+#ifndef GR_ACL_H
+#define GR_ACL_H
+
@@ -58260,8 +58563,8 @@ index 0000000..0dc3943
+
+/* Major status information */
+
-+#define GR_VERSION "grsecurity 2.2.2"
-+#define GRSECURITY_VERSION 0x2202
++#define GR_VERSION "grsecurity 2.9"
++#define GRSECURITY_VERSION 0x2900
+
+enum {
+ GR_SHUTDOWN = 0,
@@ -58424,6 +58727,8 @@ index 0000000..0dc3943
+ uid_t *domain_children;
+ __u16 domain_child_num;
+
++ umode_t umask;
++
+ struct acl_subject_label **subj_hash;
+ __u32 subj_hash_size;
+};
@@ -58956,10 +59261,10 @@ index 0000000..da390f1
+#endif
diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h
new file mode 100644
-index 0000000..8b9ed56
+index 0000000..f885406
--- /dev/null
+++ b/include/linux/grmsg.h
-@@ -0,0 +1,110 @@
+@@ -0,0 +1,109 @@
+#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
+#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
@@ -59003,7 +59308,6 @@ index 0000000..8b9ed56
+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
+#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
-+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
@@ -59072,7 +59376,7 @@ index 0000000..8b9ed56
+#define GR_BADPROCPID_MSG "denied read of sensitive /proc/pid/%s entry via fd passed across exec by "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..10c8ced
+index 0000000..2ccf677
--- /dev/null
+++ b/include/linux/grsecurity.h
@@ -0,0 +1,229 @@
@@ -59150,6 +59454,8 @@ index 0000000..10c8ced
+void gr_handle_ioperm(void);
+void gr_handle_iopl(void);
+
++umode_t gr_acl_umask(void);
++
+int gr_tpe_allow(const struct file *file);
+
+void gr_set_chroot_entries(struct task_struct *task, struct path *path);
@@ -59204,10 +59510,8 @@ index 0000000..10c8ced
+ const struct vfsmount *mnt);
+__u32 gr_acl_handle_access(const struct dentry *dentry,
+ const struct vfsmount *mnt, const int fmode);
-+__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, mode_t mode);
+__u32 gr_acl_handle_chmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, mode_t mode);
++ const struct vfsmount *mnt, umode_t *mode);
+__u32 gr_acl_handle_chown(const struct dentry *dentry,
+ const struct vfsmount *mnt);
+__u32 gr_acl_handle_setxattr(const struct dentry *dentry,
@@ -60374,7 +60678,7 @@ index 2148b12..519b820 100644
static inline void anon_vma_merge(struct vm_area_struct *vma,
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 1c4f3e9..dafcd27 100644
+index 1c4f3e9..b4e4851 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -101,6 +101,7 @@ struct bio_list;
@@ -60491,7 +60795,7 @@ index 1c4f3e9..dafcd27 100644
+#ifdef CONFIG_GRKERNSEC
+ /* grsecurity */
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ long long exec_id;
++ u64 exec_id;
+#endif
+#ifdef CONFIG_GRKERNSEC_SETXID
+ const struct cred *delayed_cred;
@@ -60650,7 +60954,7 @@ index e8c619d..e0cbd1c 100644
/* Maximum number of letters for an LSM name string */
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
-index 0b69a46..4796016 100644
+index 0b69a46..b2ffa4c 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -24,6 +24,9 @@ struct seq_file {
@@ -60658,7 +60962,7 @@ index 0b69a46..4796016 100644
const struct seq_operations *op;
int poll_event;
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ long long exec_id;
++ u64 exec_id;
+#endif
void *private;
};
@@ -63322,7 +63626,7 @@ index e6e01b9..619f837 100644
if (group_dead)
diff --git a/kernel/fork.c b/kernel/fork.c
-index da4a6a1..0483b61 100644
+index da4a6a1..0973380 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -280,7 +280,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
@@ -63592,20 +63896,16 @@ index da4a6a1..0483b61 100644
if (atomic_read(&p->real_cred->user->processes) >=
task_rlimit(p, RLIMIT_NPROC)) {
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
-@@ -1256,6 +1317,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
+@@ -1256,6 +1317,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if (clone_flags & CLONE_THREAD)
p->tgid = current->tgid;
+ gr_copy_label(p);
+
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ p->exec_id = current->exec_id;
-+#endif
-+
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
* Clear TID on mm_release()?
-@@ -1418,6 +1485,8 @@ bad_fork_cleanup_count:
+@@ -1418,6 +1481,8 @@ bad_fork_cleanup_count:
bad_fork_free:
free_task(p);
fork_out:
@@ -63614,7 +63914,7 @@ index da4a6a1..0483b61 100644
return ERR_PTR(retval);
}
-@@ -1518,6 +1587,8 @@ long do_fork(unsigned long clone_flags,
+@@ -1518,6 +1583,8 @@ long do_fork(unsigned long clone_flags,
if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr);
@@ -63623,7 +63923,7 @@ index da4a6a1..0483b61 100644
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
-@@ -1627,7 +1698,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+@@ -1627,7 +1694,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
return 0;
/* don't need lock here; in the worst case we'll do useless copy */
@@ -63632,7 +63932,7 @@ index da4a6a1..0483b61 100644
return 0;
*new_fsp = copy_fs_struct(fs);
-@@ -1716,7 +1787,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
+@@ -1716,7 +1783,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
fs = current->fs;
spin_lock(&fs->lock);
current->fs = new_fs;
@@ -65836,36 +66136,6 @@ index 9feffa4..54058df 100644
rdp->dynticks->dynticks_nesting,
rdp->dynticks->dynticks_nmi_nesting,
rdp->dynticks_fqs);
-diff --git a/kernel/relay.c b/kernel/relay.c
-index 226fade..b6f803a 100644
---- a/kernel/relay.c
-+++ b/kernel/relay.c
-@@ -164,10 +164,14 @@ depopulate:
- */
- static struct rchan_buf *relay_create_buf(struct rchan *chan)
- {
-- struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
-+ struct rchan_buf *buf;
-+
-+ if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
-+ return NULL;
-+
-+ buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
- if (!buf)
- return NULL;
--
- buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL);
- if (!buf->padding)
- goto free_buf;
-@@ -574,6 +578,8 @@ struct rchan *relay_open(const char *base_filename,
-
- if (!(subbuf_size && n_subbufs))
- return NULL;
-+ if (subbuf_size > UINT_MAX / n_subbufs)
-+ return NULL;
-
- chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
- if (!chan)
diff --git a/kernel/resource.c b/kernel/resource.c
index 7640b3a..5879283 100644
--- a/kernel/resource.c
@@ -68676,7 +68946,7 @@ index 4f4f53b..9511904 100644
capable(CAP_IPC_LOCK))
ret = do_mlockall(flags);
diff --git a/mm/mmap.c b/mm/mmap.c
-index eae90af..51ca80b 100644
+index eae90af..44552cf 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -46,6 +46,16 @@
@@ -69301,20 +69571,60 @@ index eae90af..51ca80b 100644
}
unsigned long
-@@ -1638,6 +1864,28 @@ out:
- return prev ? prev->vm_next : vma;
- }
+@@ -1603,40 +1829,42 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+
+ EXPORT_SYMBOL(find_vma);
+
+-/* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */
++/*
++ * Same as find_vma, but also return a pointer to the previous VMA in *pprev.
++ * Note: pprev is set to NULL when return value is NULL.
++ */
+ struct vm_area_struct *
+ find_vma_prev(struct mm_struct *mm, unsigned long addr,
+ struct vm_area_struct **pprev)
+ {
+- struct vm_area_struct *vma = NULL, *prev = NULL;
+- struct rb_node *rb_node;
+- if (!mm)
+- goto out;
++ struct vm_area_struct *vma;
+
+- /* Guard against addr being lower than the first VMA */
+- vma = mm->mmap;
++ vma = find_vma(mm, addr);
++ *pprev = vma ? vma->vm_prev : NULL;
++ return vma;
++}
+- /* Go through the RB tree quickly. */
+- rb_node = mm->mm_rb.rb_node;
+#ifdef CONFIG_PAX_SEGMEXEC
+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
+{
+ struct vm_area_struct *vma_m;
-+
+
+- while (rb_node) {
+- struct vm_area_struct *vma_tmp;
+- vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb);
+-
+- if (addr < vma_tmp->vm_end) {
+- rb_node = rb_node->rb_left;
+- } else {
+- prev = vma_tmp;
+- if (!prev->vm_next || (addr < prev->vm_next->vm_end))
+- break;
+- rb_node = rb_node->rb_right;
+- }
+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
+ BUG_ON(vma->vm_mirror);
+ return NULL;
-+ }
+ }
+-
+-out:
+- *pprev = prev;
+- return prev ? prev->vm_next : vma;
+ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
+ vma_m = vma->vm_mirror;
+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
@@ -69324,13 +69634,12 @@ index eae90af..51ca80b 100644
+ BUG_ON(vma->anon_vma != vma_m->anon_vma && vma->anon_vma->root != vma_m->anon_vma->root);
+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_RESERVED));
+ return vma_m;
-+}
+ }
+#endif
-+
+
/*
* Verify that the stack growth is acceptable and
- * update accounting. This is shared with both the
-@@ -1654,6 +1902,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
+@@ -1654,6 +1882,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
return -ENOMEM;
/* Stack limit test */
@@ -69338,7 +69647,7 @@ index eae90af..51ca80b 100644
if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
return -ENOMEM;
-@@ -1664,6 +1913,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
+@@ -1664,6 +1893,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
locked = mm->locked_vm + grow;
limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur);
limit >>= PAGE_SHIFT;
@@ -69346,7 +69655,7 @@ index eae90af..51ca80b 100644
if (locked > limit && !capable(CAP_IPC_LOCK))
return -ENOMEM;
}
-@@ -1694,37 +1944,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
+@@ -1694,37 +1924,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
* PA-RISC uses this for its stack; IA64 for its Register Backing Store.
* vma is the last one with address > vma->vm_end. Have to extend vma.
*/
@@ -69404,7 +69713,7 @@ index eae90af..51ca80b 100644
unsigned long size, grow;
size = address - vma->vm_start;
-@@ -1739,6 +2000,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
+@@ -1739,6 +1980,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
}
}
}
@@ -69413,7 +69722,7 @@ index eae90af..51ca80b 100644
vma_unlock_anon_vma(vma);
khugepaged_enter_vma_merge(vma);
return error;
-@@ -1752,6 +2015,8 @@ int expand_downwards(struct vm_area_struct *vma,
+@@ -1752,6 +1995,8 @@ int expand_downwards(struct vm_area_struct *vma,
unsigned long address)
{
int error;
@@ -69422,7 +69731,7 @@ index eae90af..51ca80b 100644
/*
* We must make sure the anon_vma is allocated
-@@ -1765,6 +2030,15 @@ int expand_downwards(struct vm_area_struct *vma,
+@@ -1765,6 +2010,15 @@ int expand_downwards(struct vm_area_struct *vma,
if (error)
return error;
@@ -69438,7 +69747,7 @@ index eae90af..51ca80b 100644
vma_lock_anon_vma(vma);
/*
-@@ -1774,9 +2048,17 @@ int expand_downwards(struct vm_area_struct *vma,
+@@ -1774,9 +2028,17 @@ int expand_downwards(struct vm_area_struct *vma,
*/
/* Somebody else might have raced and expanded it already */
@@ -69457,7 +69766,7 @@ index eae90af..51ca80b 100644
size = vma->vm_end - address;
grow = (vma->vm_start - address) >> PAGE_SHIFT;
-@@ -1786,11 +2068,22 @@ int expand_downwards(struct vm_area_struct *vma,
+@@ -1786,11 +2048,22 @@ int expand_downwards(struct vm_area_struct *vma,
if (!error) {
vma->vm_start = address;
vma->vm_pgoff -= grow;
@@ -69480,7 +69789,7 @@ index eae90af..51ca80b 100644
khugepaged_enter_vma_merge(vma);
return error;
}
-@@ -1860,6 +2153,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
+@@ -1860,6 +2133,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
do {
long nrpages = vma_pages(vma);
@@ -69494,7 +69803,7 @@ index eae90af..51ca80b 100644
mm->total_vm -= nrpages;
vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
vma = remove_vma(vma);
-@@ -1905,6 +2205,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -1905,6 +2185,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
insertion_point = (prev ? &prev->vm_next : &mm->mmap);
vma->vm_prev = NULL;
do {
@@ -69511,7 +69820,7 @@ index eae90af..51ca80b 100644
rb_erase(&vma->vm_rb, &mm->mm_rb);
mm->map_count--;
tail_vma = vma;
-@@ -1933,14 +2243,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1933,14 +2223,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
struct vm_area_struct *new;
int err = -ENOMEM;
@@ -69545,7 +69854,7 @@ index eae90af..51ca80b 100644
/* most fields are the same, copy all, and then fixup */
*new = *vma;
-@@ -1953,6 +2282,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1953,6 +2262,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
}
@@ -69568,7 +69877,7 @@ index eae90af..51ca80b 100644
pol = mpol_dup(vma_policy(vma));
if (IS_ERR(pol)) {
err = PTR_ERR(pol);
-@@ -1978,6 +2323,42 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1978,6 +2303,42 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
else
err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
@@ -69611,7 +69920,7 @@ index eae90af..51ca80b 100644
/* Success. */
if (!err)
return 0;
-@@ -1990,10 +2371,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1990,10 +2351,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
removed_exe_file_vma(mm);
fput(new->vm_file);
}
@@ -69631,7 +69940,7 @@ index eae90af..51ca80b 100644
kmem_cache_free(vm_area_cachep, new);
out_err:
return err;
-@@ -2006,6 +2395,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2006,6 +2375,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, int new_below)
{
@@ -69647,7 +69956,7 @@ index eae90af..51ca80b 100644
if (mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
-@@ -2017,11 +2415,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2017,11 +2395,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
* work. This now handles partial unmappings.
* Jeremy Fitzhardinge <jeremy@goop.org>
*/
@@ -69678,7 +69987,7 @@ index eae90af..51ca80b 100644
if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
return -EINVAL;
-@@ -2096,6 +2513,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
+@@ -2096,6 +2493,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
/* Fix up all other VM information */
remove_vma_list(mm, vma);
@@ -69687,7 +69996,7 @@ index eae90af..51ca80b 100644
return 0;
}
-@@ -2108,22 +2527,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+@@ -2108,22 +2507,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
profile_munmap(addr);
@@ -69716,7 +70025,7 @@ index eae90af..51ca80b 100644
/*
* this is really a simplified "do_mmap". it only handles
* anonymous maps. eventually we may be able to do some
-@@ -2137,6 +2552,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2137,6 +2532,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
int error;
@@ -69724,7 +70033,7 @@ index eae90af..51ca80b 100644
len = PAGE_ALIGN(len);
if (!len)
-@@ -2148,16 +2564,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2148,16 +2544,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
@@ -69756,7 +70065,7 @@ index eae90af..51ca80b 100644
locked += mm->locked_vm;
lock_limit = rlimit(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
-@@ -2174,22 +2604,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2174,22 +2584,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
/*
* Clear old maps. this also does some error checking for us
*/
@@ -69783,7 +70092,7 @@ index eae90af..51ca80b 100644
return -ENOMEM;
/* Can we just expand an old private anonymous mapping? */
-@@ -2203,7 +2633,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2203,7 +2613,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (!vma) {
@@ -69792,7 +70101,7 @@ index eae90af..51ca80b 100644
return -ENOMEM;
}
-@@ -2217,11 +2647,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2217,11 +2627,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
vma_link(mm, vma, prev, rb_link, rb_parent);
out:
perf_event_mmap(vma);
@@ -69807,7 +70116,7 @@ index eae90af..51ca80b 100644
return addr;
}
-@@ -2268,8 +2699,10 @@ void exit_mmap(struct mm_struct *mm)
+@@ -2268,8 +2679,10 @@ void exit_mmap(struct mm_struct *mm)
* Walk the list again, actually closing and freeing it,
* with preemption enabled, without holding any MM locks.
*/
@@ -69819,7 +70128,7 @@ index eae90af..51ca80b 100644
BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
}
-@@ -2283,6 +2716,13 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+@@ -2283,6 +2696,13 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
struct vm_area_struct * __vma, * prev;
struct rb_node ** rb_link, * rb_parent;
@@ -69833,7 +70142,7 @@ index eae90af..51ca80b 100644
/*
* The vm_pgoff of a purely anonymous vma should be irrelevant
* until its first write fault, when page's anon_vma and index
-@@ -2305,7 +2745,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+@@ -2305,7 +2725,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
if ((vma->vm_flags & VM_ACCOUNT) &&
security_vm_enough_memory_mm(mm, vma_pages(vma)))
return -ENOMEM;
@@ -69856,7 +70165,7 @@ index eae90af..51ca80b 100644
return 0;
}
-@@ -2323,6 +2778,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2323,6 +2758,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
struct rb_node **rb_link, *rb_parent;
struct mempolicy *pol;
@@ -69865,7 +70174,7 @@ index eae90af..51ca80b 100644
/*
* If anonymous vma has not yet been faulted, update new pgoff
* to match new location, to increase its chance of merging.
-@@ -2373,6 +2830,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2373,6 +2810,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
return NULL;
}
@@ -69905,7 +70214,7 @@ index eae90af..51ca80b 100644
/*
* Return true if the calling process may expand its vm space by the passed
* number of pages
-@@ -2383,7 +2873,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
+@@ -2383,7 +2853,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
unsigned long lim;
lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;
@@ -69914,7 +70223,7 @@ index eae90af..51ca80b 100644
if (cur + npages > lim)
return 0;
return 1;
-@@ -2454,6 +2944,22 @@ int install_special_mapping(struct mm_struct *mm,
+@@ -2454,6 +2924,22 @@ int install_special_mapping(struct mm_struct *mm,
vma->vm_start = addr;
vma->vm_end = addr + len;
@@ -77495,7 +77804,7 @@ index a39edcc..1014050 100644
};
diff --git a/tools/gcc/Makefile b/tools/gcc/Makefile
new file mode 100644
-index 0000000..b044b80
+index 0000000..29b6b75
--- /dev/null
+++ b/tools/gcc/Makefile
@@ -0,0 +1,21 @@
@@ -77503,9 +77812,9 @@ index 0000000..b044b80
+#PLUGIN_SOURCE_FILES := pax_plugin.c
+#PLUGIN_OBJECT_FILES := $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES))
+GCCPLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
-+#CFLAGS += -I$(GCCPLUGINS_DIR)/include -fPIC -O2 -Wall -W
++#CFLAGS += -I$(GCCPLUGINS_DIR)/include -fPIC -O2 -Wall -W -std=gnu99
+
-+HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include
++HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include -std=gnu99
+
+hostlibs-y := constify_plugin.so
+hostlibs-$(CONFIG_PAX_MEMORY_STACKLEAK) += stackleak_plugin.so
@@ -78181,10 +78490,10 @@ index 0000000..a5eabce
+}
diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
new file mode 100644
-index 0000000..51f747e
+index 0000000..008f159
--- /dev/null
+++ b/tools/gcc/kernexec_plugin.c
-@@ -0,0 +1,348 @@
+@@ -0,0 +1,427 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -78232,13 +78541,32 @@ index 0000000..51f747e
+ .help = "method=[bts|or]\tinstrumentation method\n"
+};
+
++static unsigned int execute_kernexec_reload(void);
+static unsigned int execute_kernexec_fptr(void);
+static unsigned int execute_kernexec_retaddr(void);
+static bool kernexec_cmodel_check(void);
+
-+static void (*kernexec_instrument_fptr)(gimple_stmt_iterator);
++static void (*kernexec_instrument_fptr)(gimple_stmt_iterator *);
+static void (*kernexec_instrument_retaddr)(rtx);
+
++static struct gimple_opt_pass kernexec_reload_pass = {
++ .pass = {
++ .type = GIMPLE_PASS,
++ .name = "kernexec_reload",
++ .gate = kernexec_cmodel_check,
++ .execute = execute_kernexec_reload,
++ .sub = NULL,
++ .next = NULL,
++ .static_pass_number = 0,
++ .tv_id = TV_NONE,
++ .properties_required = 0,
++ .properties_provided = 0,
++ .properties_destroyed = 0,
++ .todo_flags_start = 0,
++ .todo_flags_finish = TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_remove_unused_locals | TODO_update_ssa_no_phi
++ }
++};
++
+static struct gimple_opt_pass kernexec_fptr_pass = {
+ .pass = {
+ .type = GIMPLE_PASS,
@@ -78294,15 +78622,66 @@ index 0000000..51f747e
+}
+
+/*
++ * add special KERNEXEC instrumentation: reload %r10 after it has been clobbered
++ */
++static void kernexec_reload_fptr_mask(gimple_stmt_iterator *gsi)
++{
++ gimple asm_movabs_stmt;
++
++ // build asm volatile("movabs $0x8000000000000000, %%r10\n\t" : : : );
++ asm_movabs_stmt = gimple_build_asm_vec("movabs $0x8000000000000000, %%r10\n\t", NULL, NULL, NULL, NULL);
++ gimple_asm_set_volatile(asm_movabs_stmt, true);
++ gsi_insert_after(gsi, asm_movabs_stmt, GSI_CONTINUE_LINKING);
++ update_stmt(asm_movabs_stmt);
++}
++
++/*
++ * find all asm() stmts that clobber r10 and add a reload of r10
++ */
++static unsigned int execute_kernexec_reload(void)
++{
++ basic_block bb;
++
++ // 1. loop through BBs and GIMPLE statements
++ FOR_EACH_BB(bb) {
++ gimple_stmt_iterator gsi;
++
++ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
++ // gimple match: __asm__ ("" : : : "r10");
++ gimple asm_stmt;
++ size_t nclobbers;
++
++ // is it an asm ...
++ asm_stmt = gsi_stmt(gsi);
++ if (gimple_code(asm_stmt) != GIMPLE_ASM)
++ continue;
++
++ // ... clobbering r10
++ nclobbers = gimple_asm_nclobbers(asm_stmt);
++ while (nclobbers--) {
++ tree op = gimple_asm_clobber_op(asm_stmt, nclobbers);
++ if (strcmp(TREE_STRING_POINTER(TREE_VALUE(op)), "r10"))
++ continue;
++ kernexec_reload_fptr_mask(&gsi);
++//print_gimple_stmt(stderr, asm_stmt, 0, TDF_LINENO);
++ break;
++ }
++ }
++ }
++
++ return 0;
++}
++
++/*
+ * add special KERNEXEC instrumentation: force MSB of fptr to 1, which will produce
+ * a non-canonical address from a userland ptr and will just trigger a GPF on dereference
+ */
-+static void kernexec_instrument_fptr_bts(gimple_stmt_iterator gsi)
++static void kernexec_instrument_fptr_bts(gimple_stmt_iterator *gsi)
+{
+ gimple assign_intptr, assign_new_fptr, call_stmt;
+ tree intptr, old_fptr, new_fptr, kernexec_mask;
+
-+ call_stmt = gsi_stmt(gsi);
++ call_stmt = gsi_stmt(*gsi);
+ old_fptr = gimple_call_fn(call_stmt);
+
+ // create temporary unsigned long variable used for bitops and cast fptr to it
@@ -78310,14 +78689,14 @@ index 0000000..51f747e
+ add_referenced_var(intptr);
+ mark_sym_for_renaming(intptr);
+ assign_intptr = gimple_build_assign(intptr, fold_convert(long_unsigned_type_node, old_fptr));
-+ gsi_insert_before(&gsi, assign_intptr, GSI_SAME_STMT);
++ gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT);
+ update_stmt(assign_intptr);
+
+ // apply logical or to temporary unsigned long and bitmask
+ kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0x8000000000000000LL);
+// kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0xffffffff80000000LL);
+ assign_intptr = gimple_build_assign(intptr, fold_build2(BIT_IOR_EXPR, long_long_unsigned_type_node, intptr, kernexec_mask));
-+ gsi_insert_before(&gsi, assign_intptr, GSI_SAME_STMT);
++ gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT);
+ update_stmt(assign_intptr);
+
+ // cast temporary unsigned long back to a temporary fptr variable
@@ -78325,7 +78704,7 @@ index 0000000..51f747e
+ add_referenced_var(new_fptr);
+ mark_sym_for_renaming(new_fptr);
+ assign_new_fptr = gimple_build_assign(new_fptr, fold_convert(TREE_TYPE(old_fptr), intptr));
-+ gsi_insert_before(&gsi, assign_new_fptr, GSI_SAME_STMT);
++ gsi_insert_before(gsi, assign_new_fptr, GSI_SAME_STMT);
+ update_stmt(assign_new_fptr);
+
+ // replace call stmt fn with the new fptr
@@ -78333,14 +78712,14 @@ index 0000000..51f747e
+ update_stmt(call_stmt);
+}
+
-+static void kernexec_instrument_fptr_or(gimple_stmt_iterator gsi)
++static void kernexec_instrument_fptr_or(gimple_stmt_iterator *gsi)
+{
+ gimple asm_or_stmt, call_stmt;
+ tree old_fptr, new_fptr, input, output;
+ VEC(tree, gc) *inputs = NULL;
+ VEC(tree, gc) *outputs = NULL;
+
-+ call_stmt = gsi_stmt(gsi);
++ call_stmt = gsi_stmt(*gsi);
+ old_fptr = gimple_call_fn(call_stmt);
+
+ // create temporary fptr variable
@@ -78357,7 +78736,7 @@ index 0000000..51f747e
+ VEC_safe_push(tree, gc, outputs, output);
+ asm_or_stmt = gimple_build_asm_vec("orq %%r10, %0\n\t", inputs, outputs, NULL, NULL);
+ gimple_asm_set_volatile(asm_or_stmt, true);
-+ gsi_insert_before(&gsi, asm_or_stmt, GSI_SAME_STMT);
++ gsi_insert_before(gsi, asm_or_stmt, GSI_SAME_STMT);
+ update_stmt(asm_or_stmt);
+
+ // replace call stmt fn with the new fptr
@@ -78371,10 +78750,11 @@ index 0000000..51f747e
+static unsigned int execute_kernexec_fptr(void)
+{
+ basic_block bb;
-+ gimple_stmt_iterator gsi;
+
+ // 1. loop through BBs and GIMPLE statements
+ FOR_EACH_BB(bb) {
++ gimple_stmt_iterator gsi;
++
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
+ // gimple match: h_1 = get_fptr (); D.2709_3 = h_1 (x_2(D));
+ tree fn;
@@ -78401,7 +78781,7 @@ index 0000000..51f747e
+ if (TREE_CODE(fn) != FUNCTION_TYPE)
+ continue;
+
-+ kernexec_instrument_fptr(gsi);
++ kernexec_instrument_fptr(&gsi);
+
+//debug_tree(gimple_call_fn(call_stmt));
+//print_gimple_stmt(stderr, call_stmt, 0, TDF_LINENO);
@@ -78483,6 +78863,12 @@ index 0000000..51f747e
+ const int argc = plugin_info->argc;
+ const struct plugin_argument * const argv = plugin_info->argv;
+ int i;
++ struct register_pass_info kernexec_reload_pass_info = {
++ .pass = &kernexec_reload_pass.pass,
++ .reference_pass_name = "ssa",
++ .ref_pass_instance_number = 0,
++ .pos_op = PASS_POS_INSERT_AFTER
++ };
+ struct register_pass_info kernexec_fptr_pass_info = {
+ .pass = &kernexec_fptr_pass.pass,
+ .reference_pass_name = "ssa",
@@ -78528,6 +78914,8 @@ index 0000000..51f747e
+ if (!kernexec_instrument_fptr || !kernexec_instrument_retaddr)
+ error(G_("no instrumentation method was selected via '-fplugin-arg-%s-method'"), plugin_name);
+
++ if (kernexec_instrument_fptr == kernexec_instrument_fptr_or)
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &kernexec_reload_pass_info);
+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &kernexec_fptr_pass_info);
+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &kernexec_retaddr_pass_info);
+
@@ -78535,10 +78923,10 @@ index 0000000..51f747e
+}
diff --git a/tools/gcc/stackleak_plugin.c b/tools/gcc/stackleak_plugin.c
new file mode 100644
-index 0000000..d44f37c
+index 0000000..8b61031
--- /dev/null
+++ b/tools/gcc/stackleak_plugin.c
-@@ -0,0 +1,291 @@
+@@ -0,0 +1,295 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -78638,7 +79026,7 @@ index 0000000..d44f37c
+ return track_frame_size >= 0;
+}
+
-+static void stackleak_check_alloca(gimple_stmt_iterator gsi)
++static void stackleak_check_alloca(gimple_stmt_iterator *gsi)
+{
+ gimple check_alloca;
+ tree fndecl, fntype, alloca_size;
@@ -78647,12 +79035,12 @@ index 0000000..d44f37c
+ fntype = build_function_type_list(void_type_node, long_unsigned_type_node, NULL_TREE);
+ fndecl = build_fn_decl(check_function, fntype);
+ DECL_ASSEMBLER_NAME(fndecl); // for LTO
-+ alloca_size = gimple_call_arg(gsi_stmt(gsi), 0);
++ alloca_size = gimple_call_arg(gsi_stmt(*gsi), 0);
+ check_alloca = gimple_build_call(fndecl, 1, alloca_size);
-+ gsi_insert_before(&gsi, check_alloca, GSI_CONTINUE_LINKING);
++ gsi_insert_before(gsi, check_alloca, GSI_SAME_STMT);
+}
+
-+static void stackleak_add_instrumentation(gimple_stmt_iterator gsi)
++static void stackleak_add_instrumentation(gimple_stmt_iterator *gsi)
+{
+ gimple track_stack;
+ tree fndecl, fntype;
@@ -78662,7 +79050,7 @@ index 0000000..d44f37c
+ fndecl = build_fn_decl(track_function, fntype);
+ DECL_ASSEMBLER_NAME(fndecl); // for LTO
+ track_stack = gimple_build_call(fndecl, 0);
-+ gsi_insert_after(&gsi, track_stack, GSI_CONTINUE_LINKING);
++ gsi_insert_after(gsi, track_stack, GSI_CONTINUE_LINKING);
+}
+
+#if BUILDING_GCC_VERSION == 4005
@@ -78705,16 +79093,17 @@ index 0000000..d44f37c
+ // 1. loop through BBs and GIMPLE statements
+ FOR_EACH_BB(bb) {
+ gimple_stmt_iterator gsi;
++
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
+ // gimple match: align 8 built-in BUILT_IN_NORMAL:BUILT_IN_ALLOCA attributes <tree_list 0xb7576450>
+ if (!is_alloca(gsi_stmt(gsi)))
+ continue;
+
+ // 2. insert stack overflow check before each __builtin_alloca call
-+ stackleak_check_alloca(gsi);
++ stackleak_check_alloca(&gsi);
+
+ // 3. insert track call after each __builtin_alloca call
-+ stackleak_add_instrumentation(gsi);
++ stackleak_add_instrumentation(&gsi);
+ if (bb == entry_bb)
+ prologue_instrumented = true;
+ }
@@ -78722,10 +79111,13 @@ index 0000000..d44f37c
+
+ // 4. insert track call at the beginning
+ if (!prologue_instrumented) {
++ gimple_stmt_iterator gsi;
++
+ bb = split_block_after_labels(ENTRY_BLOCK_PTR)->dest;
+ if (dom_info_available_p(CDI_DOMINATORS))
+ set_immediate_dominator(CDI_DOMINATORS, bb, ENTRY_BLOCK_PTR);
-+ stackleak_add_instrumentation(gsi_start_bb(bb));
++ gsi = gsi_start_bb(bb);
++ stackleak_add_instrumentation(&gsi);
+ }
+
+ return 0;
diff --git a/3.2.6/4425_grsec_enable_xtpax.patch b/3.2.7/4425_grsec_enable_xtpax.patch
index 9735ecf..9735ecf 100644
--- a/3.2.6/4425_grsec_enable_xtpax.patch
+++ b/3.2.7/4425_grsec_enable_xtpax.patch
diff --git a/3.2.6/4430_grsec-remove-localversion-grsec.patch b/3.2.7/4430_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/3.2.6/4430_grsec-remove-localversion-grsec.patch
+++ b/3.2.7/4430_grsec-remove-localversion-grsec.patch
diff --git a/3.2.6/4435_grsec-mute-warnings.patch b/3.2.7/4435_grsec-mute-warnings.patch
index e85abd6..e85abd6 100644
--- a/3.2.6/4435_grsec-mute-warnings.patch
+++ b/3.2.7/4435_grsec-mute-warnings.patch
diff --git a/3.2.6/4440_grsec-remove-protected-paths.patch b/3.2.7/4440_grsec-remove-protected-paths.patch
index 4afb3e2..4afb3e2 100644
--- a/3.2.6/4440_grsec-remove-protected-paths.patch
+++ b/3.2.7/4440_grsec-remove-protected-paths.patch
diff --git a/3.2.6/4445_grsec-pax-without-grsec.patch b/3.2.7/4445_grsec-pax-without-grsec.patch
index 9992f51..9992f51 100644
--- a/3.2.6/4445_grsec-pax-without-grsec.patch
+++ b/3.2.7/4445_grsec-pax-without-grsec.patch
diff --git a/3.2.6/4450_grsec-kconfig-default-gids.patch b/3.2.7/4450_grsec-kconfig-default-gids.patch
index 0807a4e..0807a4e 100644
--- a/3.2.6/4450_grsec-kconfig-default-gids.patch
+++ b/3.2.7/4450_grsec-kconfig-default-gids.patch
diff --git a/3.2.6/4455_grsec-kconfig-gentoo.patch b/3.2.7/4455_grsec-kconfig-gentoo.patch
index 587b7d9..587b7d9 100644
--- a/3.2.6/4455_grsec-kconfig-gentoo.patch
+++ b/3.2.7/4455_grsec-kconfig-gentoo.patch
diff --git a/3.2.6/4460-grsec-kconfig-proc-user.patch b/3.2.7/4460-grsec-kconfig-proc-user.patch
index 72b894a..72b894a 100644
--- a/3.2.6/4460-grsec-kconfig-proc-user.patch
+++ b/3.2.7/4460-grsec-kconfig-proc-user.patch
diff --git a/3.2.6/4465_selinux-avc_audit-log-curr_ip.patch b/3.2.7/4465_selinux-avc_audit-log-curr_ip.patch
index 7c9894c..7c9894c 100644
--- a/3.2.6/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/3.2.7/4465_selinux-avc_audit-log-curr_ip.patch
diff --git a/3.2.6/4470_disable-compat_vdso.patch b/3.2.7/4470_disable-compat_vdso.patch
index 4742d01..4742d01 100644
--- a/3.2.6/4470_disable-compat_vdso.patch
+++ b/3.2.7/4470_disable-compat_vdso.patch