]> git.ipfire.org Git - people/ms/ipfire-3.x.git/blobdiff - kernel/patches/grsecurity-2.9.1-3.4.6-201207281946.patch
kernel: Update to 3.4.6.
[people/ms/ipfire-3.x.git] / kernel / patches / grsecurity-2.9.1-3.4.6-201207281946.patch
similarity index 97%
rename from kernel/patches/grsecurity-2.9.1-3.4.4-201206251759.patch
rename to kernel/patches/grsecurity-2.9.1-3.4.6-201207281946.patch
index 083b3e12803ad838ffb0db370830bdabf5678210..357f472e5e140dee1b2bfe254ba925ecba0ffff2 100644 (file)
@@ -1,5 +1,5 @@
 diff --git a/Documentation/dontdiff b/Documentation/dontdiff
-index b4a898f..a0e01d0 100644
+index b4a898f..781c7ad 100644
 --- a/Documentation/dontdiff
 +++ b/Documentation/dontdiff
 @@ -2,9 +2,11 @@
@@ -22,7 +22,7 @@ index b4a898f..a0e01d0 100644
  *.grep
  *.grp
  *.gz
-@@ -48,9 +51,11 @@
+@@ -48,14 +51,17 @@
  *.tab.h
  *.tex
  *.ver
@@ -34,7 +34,14 @@ index b4a898f..a0e01d0 100644
  *_vga16.c
  *~
  \#*#
-@@ -69,6 +74,7 @@ Image
+ *.9
+-.*
++.[^g]*
++.gen*
+ .*.d
+ .mm
+ 53c700_d.h
+@@ -69,6 +75,7 @@ Image
  Module.markers
  Module.symvers
  PENDING
@@ -42,7 +49,7 @@ index b4a898f..a0e01d0 100644
  SCCS
  System.map*
  TAGS
-@@ -80,6 +86,7 @@ aic7*seq.h*
+@@ -80,6 +87,7 @@ aic7*seq.h*
  aicasm
  aicdb.h*
  altivec*.c
@@ -50,7 +57,7 @@ index b4a898f..a0e01d0 100644
  asm-offsets.h
  asm_offsets.h
  autoconf.h*
-@@ -92,19 +99,24 @@ bounds.h
+@@ -92,19 +100,24 @@ bounds.h
  bsetup
  btfixupprep
  build
@@ -75,7 +82,7 @@ index b4a898f..a0e01d0 100644
  conmakehash
  consolemap_deftbl.c*
  cpustr.h
-@@ -115,9 +127,11 @@ devlist.h*
+@@ -115,9 +128,11 @@ devlist.h*
  dnotify_test
  docproc
  dslm
@@ -87,7 +94,7 @@ index b4a898f..a0e01d0 100644
  fixdep
  flask.h
  fore200e_mkfirm
-@@ -125,12 +139,15 @@ fore200e_pca_fw.c*
+@@ -125,12 +140,15 @@ fore200e_pca_fw.c*
  gconf
  gconf.glade.h
  gen-devlist
@@ -103,7 +110,7 @@ index b4a898f..a0e01d0 100644
  hpet_example
  hugepage-mmap
  hugepage-shm
-@@ -145,7 +162,7 @@ int32.c
+@@ -145,7 +163,7 @@ int32.c
  int4.c
  int8.c
  kallsyms
@@ -112,7 +119,7 @@ index b4a898f..a0e01d0 100644
  keywords.c
  ksym.c*
  ksym.h*
-@@ -153,7 +170,7 @@ kxgettext
+@@ -153,7 +171,7 @@ kxgettext
  lkc_defs.h
  lex.c
  lex.*.c
@@ -121,7 +128,7 @@ index b4a898f..a0e01d0 100644
  logo_*.c
  logo_*_clut224.c
  logo_*_mono.c
-@@ -164,14 +181,15 @@ machtypes.h
+@@ -164,14 +182,15 @@ machtypes.h
  map
  map_hugetlb
  maui_boot.h
@@ -138,7 +145,7 @@ index b4a898f..a0e01d0 100644
  mkprep
  mkregtable
  mktables
-@@ -188,6 +206,7 @@ oui.c*
+@@ -188,6 +207,7 @@ oui.c*
  page-types
  parse.c
  parse.h
@@ -146,7 +153,7 @@ index b4a898f..a0e01d0 100644
  patches*
  pca200e.bin
  pca200e_ecd.bin2
-@@ -197,6 +216,7 @@ perf-archive
+@@ -197,6 +217,7 @@ perf-archive
  piggyback
  piggy.gzip
  piggy.S
@@ -154,7 +161,7 @@ index b4a898f..a0e01d0 100644
  pnmtologo
  ppc_defs.h*
  pss_boot.h
-@@ -207,6 +227,7 @@ r300_reg_safe.h
+@@ -207,6 +228,7 @@ r300_reg_safe.h
  r420_reg_safe.h
  r600_reg_safe.h
  recordmcount
@@ -162,7 +169,7 @@ index b4a898f..a0e01d0 100644
  relocs
  rlim_names.h
  rn50_reg_safe.h
-@@ -216,7 +237,9 @@ series
+@@ -216,7 +238,9 @@ series
  setup
  setup.bin
  setup.elf
@@ -172,7 +179,7 @@ index b4a898f..a0e01d0 100644
  sm_tbl*
  split-include
  syscalltab.h
-@@ -227,6 +250,7 @@ tftpboot.img
+@@ -227,6 +251,7 @@ tftpboot.img
  timeconst.h
  times.h*
  trix_boot.h
@@ -180,7 +187,7 @@ index b4a898f..a0e01d0 100644
  utsrelease.h*
  vdso-syms.lds
  vdso.lds
-@@ -238,13 +262,17 @@ vdso32.lds
+@@ -238,13 +263,17 @@ vdso32.lds
  vdso32.so.dbg
  vdso64.lds
  vdso64.so.dbg
@@ -198,7 +205,7 @@ index b4a898f..a0e01d0 100644
  vmlinuz
  voffset.h
  vsyscall.lds
-@@ -252,9 +280,11 @@ vsyscall_32.lds
+@@ -252,9 +281,11 @@ vsyscall_32.lds
  wanxlfw.inc
  uImage
  unifdef
@@ -229,7 +236,7 @@ index c1601e5..08557ce 100644
  
        pcd.            [PARIDE]
 diff --git a/Makefile b/Makefile
-index 058320d..817f7ad 100644
+index 5d0edcb..f69ee4c 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -255,7 +262,7 @@ index 058320d..817f7ad 100644
        $(Q)$(MAKE) $(build)=scripts/basic
        $(Q)rm -f .tmp_quiet_recordmcount
  
-@@ -564,6 +565,56 @@ else
+@@ -564,6 +565,60 @@ else
  KBUILD_CFLAGS += -O2
  endif
  
@@ -286,12 +293,16 @@ index 058320d..817f7ad 100644
 +endif
 +COLORIZE_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/colorize_plugin.so
 +ifdef CONFIG_PAX_SIZE_OVERFLOW
-+SIZE_OVERFLOW_PLUGIN := -fplugin=$(objtree)/tools/gcc/size_overflow_plugin.so -DSIZE_OVERFLOW_PLUGIN
++SIZE_OVERFLOW_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/size_overflow_plugin.so -DSIZE_OVERFLOW_PLUGIN
++endif
++ifdef CONFIG_PAX_LATENT_ENTROPY
++LATENT_ENTROPY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/latent_entropy_plugin.so -DLATENT_ENTROPY_PLUGIN
 +endif
 +GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) $(KALLOCSTAT_PLUGIN_CFLAGS)
-+GCC_PLUGINS_CFLAGS += $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS) $(COLORIZE_PLUGIN_CFLAGS) $(SIZE_OVERFLOW_PLUGIN)
++GCC_PLUGINS_CFLAGS += $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS) $(COLORIZE_PLUGIN_CFLAGS)
++GCC_PLUGINS_CFLAGS += $(SIZE_OVERFLOW_PLUGIN_CFLAGS) $(LATENT_ENTROPY_PLUGIN_CFLAGS)
 +GCC_PLUGINS_AFLAGS := $(KERNEXEC_PLUGIN_AFLAGS)
-+export PLUGINCC CONSTIFY_PLUGIN STACKLEAK_PLUGIN KERNEXEC_PLUGIN CHECKER_PLUGIN SIZE_OVERFLOW_PLUGIN
++export PLUGINCC CONSTIFY_PLUGIN
 +ifeq ($(KBUILD_EXTMOD),)
 +gcc-plugins:
 +      $(Q)$(MAKE) $(build)=tools/gcc
@@ -312,7 +323,7 @@ index 058320d..817f7ad 100644
  include $(srctree)/arch/$(SRCARCH)/Makefile
  
  ifneq ($(CONFIG_FRAME_WARN),0)
-@@ -708,7 +759,7 @@ export mod_strip_cmd
+@@ -708,7 +763,7 @@ export mod_strip_cmd
  
  
  ifeq ($(KBUILD_EXTMOD),)
@@ -321,7 +332,7 @@ index 058320d..817f7ad 100644
  
  vmlinux-dirs  := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
                     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
-@@ -932,6 +983,8 @@ vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
+@@ -932,6 +987,8 @@ vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
  
  # The actual objects are generated when descending, 
  # make sure no implicit rule kicks in
@@ -330,7 +341,7 @@ index 058320d..817f7ad 100644
  $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
  
  # Handle descending into subdirectories listed in $(vmlinux-dirs)
-@@ -941,7 +994,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
+@@ -941,7 +998,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
  # Error messages still appears in the original language
  
  PHONY += $(vmlinux-dirs)
@@ -339,7 +350,7 @@ index 058320d..817f7ad 100644
        $(Q)$(MAKE) $(build)=$@
  
  # Store (new) KERNELRELASE string in include/config/kernel.release
-@@ -985,6 +1038,7 @@ prepare0: archprepare FORCE
+@@ -985,6 +1042,7 @@ prepare0: archprepare FORCE
        $(Q)$(MAKE) $(build)=.
  
  # All the preparing..
@@ -347,7 +358,7 @@ index 058320d..817f7ad 100644
  prepare: prepare0
  
  # Generate some files
-@@ -1092,6 +1146,8 @@ all: modules
+@@ -1092,6 +1150,8 @@ all: modules
  #     using awk while concatenating to the final file.
  
  PHONY += modules
@@ -356,7 +367,7 @@ index 058320d..817f7ad 100644
  modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
        $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
        @$(kecho) '  Building modules, stage 2.';
-@@ -1107,7 +1163,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
+@@ -1107,7 +1167,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
  
  # Target to prepare building external modules
  PHONY += modules_prepare
@@ -365,7 +376,7 @@ index 058320d..817f7ad 100644
  
  # Target to install modules
  PHONY += modules_install
-@@ -1166,7 +1222,7 @@ CLEAN_FILES +=   vmlinux System.map \
+@@ -1166,7 +1226,7 @@ CLEAN_FILES +=   vmlinux System.map \
  MRPROPER_DIRS  += include/config usr/include include/generated          \
                    arch/*/include/generated
  MRPROPER_FILES += .config .config.old .version .old_version             \
@@ -374,7 +385,7 @@ index 058320d..817f7ad 100644
                  Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS
  
  # clean - Delete most, but leave enough to build external modules
-@@ -1204,6 +1260,7 @@ distclean: mrproper
+@@ -1204,6 +1264,7 @@ distclean: mrproper
                \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
                -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
                -o -name '.*.rej' \
@@ -382,7 +393,7 @@ index 058320d..817f7ad 100644
                -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
                -type f -print | xargs rm -f
  
-@@ -1364,6 +1421,8 @@ PHONY += $(module-dirs) modules
+@@ -1364,6 +1425,8 @@ PHONY += $(module-dirs) modules
  $(module-dirs): crmodverdir $(objtree)/Module.symvers
        $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
  
@@ -391,7 +402,7 @@ index 058320d..817f7ad 100644
  modules: $(module-dirs)
        @$(kecho) '  Building modules, stage 2.';
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
-@@ -1490,17 +1549,21 @@ else
+@@ -1490,17 +1553,21 @@ else
          target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
  endif
  
@@ -417,7 +428,7 @@ index 058320d..817f7ad 100644
        $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
  %.symtypes: %.c prepare scripts FORCE
        $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-@@ -1510,11 +1573,15 @@ endif
+@@ -1510,11 +1577,15 @@ endif
        $(cmd_crmodverdir)
        $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
        $(build)=$(build-dir)
@@ -6516,7 +6527,7 @@ index 301421c..e2535d1 100644
  obj-$(CONFIG_SPARC64)   += ultra.o tlb.o tsb.o gup.o
  obj-y                   += fault_$(BITS).o
 diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
-index df3155a..eb708b8 100644
+index df3155a..b6e32fa 100644
 --- a/arch/sparc/mm/fault_32.c
 +++ b/arch/sparc/mm/fault_32.c
 @@ -21,6 +21,9 @@
@@ -6529,7 +6540,7 @@ index df3155a..eb708b8 100644
  
  #include <asm/page.h>
  #include <asm/pgtable.h>
-@@ -207,6 +210,268 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
+@@ -207,6 +210,277 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
        return safe_compute_effective_address(regs, insn);
  }
  
@@ -6620,40 +6631,49 @@ index df3155a..eb708b8 100644
 +              }
 +      } while (0);
 +
-+      { /* PaX: patched PLT emulation #2 */
++      do { /* PaX: patched PLT emulation #2 */
 +              unsigned int ba;
 +
 +              err = get_user(ba, (unsigned int *)regs->pc);
 +
-+              if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
++              if (err)
++                      break;
++
++              if ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30480000U) {
 +                      unsigned int addr;
 +
-+                      addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
++                      if ((ba & 0xFFC00000U) == 0x30800000U)
++                              addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
++                      else
++                              addr = regs->pc + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
 +                      regs->pc = addr;
 +                      regs->npc = addr+4;
 +                      return 2;
 +              }
-+      }
++      } while (0);
 +
 +      do { /* PaX: patched PLT emulation #3 */
-+              unsigned int sethi, jmpl, nop;
++              unsigned int sethi, bajmpl, nop;
 +
 +              err = get_user(sethi, (unsigned int *)regs->pc);
-+              err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
++              err |= get_user(bajmpl, (unsigned int *)(regs->pc+4));
 +              err |= get_user(nop, (unsigned int *)(regs->pc+8));
 +
 +              if (err)
 +                      break;
 +
 +              if ((sethi & 0xFFC00000U) == 0x03000000U &&
-+                  (jmpl & 0xFFFFE000U) == 0x81C06000U &&
++                  ((bajmpl & 0xFFFFE000U) == 0x81C06000U || (bajmpl & 0xFFF80000U) == 0x30480000U) &&
 +                  nop == 0x01000000U)
 +              {
 +                      unsigned int addr;
 +
 +                      addr = (sethi & 0x003FFFFFU) << 10;
 +                      regs->u_regs[UREG_G1] = addr;
-+                      addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++                      if ((bajmpl & 0xFFFFE000U) == 0x81C06000U)
++                              addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++                      else
++                              addr = regs->pc + ((((bajmpl | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
 +                      regs->pc = addr;
 +                      regs->npc = addr+4;
 +                      return 2;
@@ -6798,7 +6818,7 @@ index df3155a..eb708b8 100644
  static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
                                      int text_fault)
  {
-@@ -282,6 +547,24 @@ good_area:
+@@ -282,6 +556,24 @@ good_area:
                if(!(vma->vm_flags & VM_WRITE))
                        goto bad_area;
        } else {
@@ -6824,7 +6844,7 @@ index df3155a..eb708b8 100644
                if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
                        goto bad_area;
 diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
-index 1fe0429..aee2e87 100644
+index 1fe0429..8dd5dd5 100644
 --- a/arch/sparc/mm/fault_64.c
 +++ b/arch/sparc/mm/fault_64.c
 @@ -21,6 +21,9 @@
@@ -6846,7 +6866,7 @@ index 1fe0429..aee2e87 100644
        printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
        dump_stack();
        unhandled_fault(regs->tpc, current, regs);
-@@ -272,6 +275,457 @@ static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
+@@ -272,6 +275,466 @@ static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
        show_regs(regs);
  }
  
@@ -6941,15 +6961,21 @@ index 1fe0429..aee2e87 100644
 +              }
 +      } while (0);
 +
-+      { /* PaX: patched PLT emulation #2 */
++      do { /* PaX: patched PLT emulation #2 */
 +              unsigned int ba;
 +
 +              err = get_user(ba, (unsigned int *)regs->tpc);
 +
-+              if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
++              if (err)
++                      break;
++
++              if ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30480000U) {
 +                      unsigned long addr;
 +
-+                      addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
++                      if ((ba & 0xFFC00000U) == 0x30800000U)
++                              addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
++                      else
++                              addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
 +
 +                      if (test_thread_flag(TIF_32BIT))
 +                              addr &= 0xFFFFFFFFUL;
@@ -6958,27 +6984,30 @@ index 1fe0429..aee2e87 100644
 +                      regs->tnpc = addr+4;
 +                      return 2;
 +              }
-+      }
++      } while (0);
 +
 +      do { /* PaX: patched PLT emulation #3 */
-+              unsigned int sethi, jmpl, nop;
++              unsigned int sethi, bajmpl, nop;
 +
 +              err = get_user(sethi, (unsigned int *)regs->tpc);
-+              err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
++              err |= get_user(bajmpl, (unsigned int *)(regs->tpc+4));
 +              err |= get_user(nop, (unsigned int *)(regs->tpc+8));
 +
 +              if (err)
 +                      break;
 +
 +              if ((sethi & 0xFFC00000U) == 0x03000000U &&
-+                  (jmpl & 0xFFFFE000U) == 0x81C06000U &&
++                  ((bajmpl & 0xFFFFE000U) == 0x81C06000U || (bajmpl & 0xFFF80000U) == 0x30480000U) &&
 +                  nop == 0x01000000U)
 +              {
 +                      unsigned long addr;
 +
 +                      addr = (sethi & 0x003FFFFFU) << 10;
 +                      regs->u_regs[UREG_G1] = addr;
-+                      addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++                      if ((bajmpl & 0xFFFFE000U) == 0x81C06000U)
++                              addr += (((bajmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++                      else
++                              addr = regs->tpc + ((((bajmpl | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
 +
 +                      if (test_thread_flag(TIF_32BIT))
 +                              addr &= 0xFFFFFFFFUL;
@@ -7304,7 +7333,7 @@ index 1fe0429..aee2e87 100644
  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
  {
        struct mm_struct *mm = current->mm;
-@@ -343,6 +797,29 @@ retry:
+@@ -343,6 +806,29 @@ retry:
        if (!vma)
                goto bad_area;
  
@@ -8595,7 +8624,7 @@ index 07b3a68..bd2a388 100644
        set_fs(KERNEL_DS);
        has_dumped = 1;
 diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
-index a69245b..6d145f4 100644
+index 4f5bfac..e1ef0d3 100644
 --- a/arch/x86/ia32/ia32_signal.c
 +++ b/arch/x86/ia32/ia32_signal.c
 @@ -168,7 +168,7 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
@@ -9130,7 +9159,7 @@ index 20370c6..a2eb9b0 100644
                "popl %%ebp\n\t"
                "popl %%edi\n\t"
 diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
-index 58cb6d4..ca9010d 100644
+index 58cb6d4..a4b806c 100644
 --- a/arch/x86/include/asm/atomic.h
 +++ b/arch/x86/include/asm/atomic.h
 @@ -22,7 +22,18 @@
@@ -9538,6 +9567,51 @@ index 58cb6d4..ca9010d 100644
  
  /*
   * atomic_dec_if_positive - decrement by 1 if old value positive
+@@ -293,14 +552,37 @@ static inline void atomic_or_long(unsigned long *v1, unsigned long v2)
+ #endif
+ /* These are x86-specific, used by some header files */
+-#define atomic_clear_mask(mask, addr)                         \
+-      asm volatile(LOCK_PREFIX "andl %0,%1"                   \
+-                   : : "r" (~(mask)), "m" (*(addr)) : "memory")
++static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
++{
++      asm volatile(LOCK_PREFIX "andl %1,%0"
++                   : "+m" (v->counter)
++                   : "r" (~(mask))
++                   : "memory");
++}
+-#define atomic_set_mask(mask, addr)                           \
+-      asm volatile(LOCK_PREFIX "orl %0,%1"                    \
+-                   : : "r" ((unsigned)(mask)), "m" (*(addr))  \
+-                   : "memory")
++static inline void atomic_clear_mask_unchecked(unsigned int mask, atomic_unchecked_t *v)
++{
++      asm volatile(LOCK_PREFIX "andl %1,%0"
++                   : "+m" (v->counter)
++                   : "r" (~(mask))
++                   : "memory");
++}
++
++static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
++{
++      asm volatile(LOCK_PREFIX "orl %1,%0"
++                   : "+m" (v->counter)
++                   : "r" (mask)
++                   : "memory");
++}
++
++static inline void atomic_set_mask_unchecked(unsigned int mask, atomic_unchecked_t *v)
++{
++      asm volatile(LOCK_PREFIX "orl %1,%0"
++                   : "+m" (v->counter)
++                   : "r" (mask)
++                   : "memory");
++}
+ /* Atomic operations are already serializing on x86 */
+ #define smp_mb__before_atomic_dec()   barrier()
 diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
 index 1981199..36b9dfb 100644
 --- a/arch/x86/include/asm/atomic64_32.h
@@ -10191,7 +10265,7 @@ index 99480e5..d81165b 100644
        ({                                                              \
                __typeof__ (*(ptr)) __ret = (inc);                      \
 diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
-index 340ee49..4238ced 100644
+index f91e80f..7f9bd27 100644
 --- a/arch/x86/include/asm/cpufeature.h
 +++ b/arch/x86/include/asm/cpufeature.h
 @@ -371,7 +371,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
@@ -11294,67 +11368,10 @@ index 98391db..8f6984e 100644
  
  static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
 diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h
-index effff47..bbb8295 100644
+index cb00ccc..17e9054 100644
 --- a/arch/x86/include/asm/pgtable-3level.h
 +++ b/arch/x86/include/asm/pgtable-3level.h
-@@ -31,6 +31,56 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte)
-       ptep->pte_low = pte.pte_low;
- }
-+#define  __HAVE_ARCH_READ_PMD_ATOMIC
-+/*
-+ * pte_offset_map_lock on 32bit PAE kernels was reading the pmd_t with
-+ * a "*pmdp" dereference done by gcc. Problem is, in certain places
-+ * where pte_offset_map_lock is called, concurrent page faults are
-+ * allowed, if the mmap_sem is hold for reading. An example is mincore
-+ * vs page faults vs MADV_DONTNEED. On the page fault side
-+ * pmd_populate rightfully does a set_64bit, but if we're reading the
-+ * pmd_t with a "*pmdp" on the mincore side, a SMP race can happen
-+ * because gcc will not read the 64bit of the pmd atomically. To fix
-+ * this all places running pmd_offset_map_lock() while holding the
-+ * mmap_sem in read mode, shall read the pmdp pointer using this
-+ * function to know if the pmd is null nor not, and in turn to know if
-+ * they can run pmd_offset_map_lock or pmd_trans_huge or other pmd
-+ * operations.
-+ *
-+ * Without THP if the mmap_sem is hold for reading, the
-+ * pmd can only transition from null to not null while read_pmd_atomic runs.
-+ * So there's no need of literally reading it atomically.
-+ *
-+ * With THP if the mmap_sem is hold for reading, the pmd can become
-+ * THP or null or point to a pte (and in turn become "stable") at any
-+ * time under read_pmd_atomic, so it's mandatory to read it atomically
-+ * with cmpxchg8b.
-+ */
-+#ifndef CONFIG_TRANSPARENT_HUGEPAGE
-+static inline pmd_t read_pmd_atomic(pmd_t *pmdp)
-+{
-+      pmdval_t ret;
-+      u32 *tmp = (u32 *)pmdp;
-+
-+      ret = (pmdval_t) (*tmp);
-+      if (ret) {
-+              /*
-+               * If the low part is null, we must not read the high part
-+               * or we can end up with a partial pmd.
-+               */
-+              smp_rmb();
-+              ret |= ((pmdval_t)*(tmp + 1)) << 32;
-+      }
-+
-+      return __pmd(ret);
-+}
-+#else /* CONFIG_TRANSPARENT_HUGEPAGE */
-+static inline pmd_t read_pmd_atomic(pmd_t *pmdp)
-+{
-+      return __pmd(atomic64_read((atomic64_t *)pmdp));
-+}
-+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-+
- static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
- {
-       set_64bit((unsigned long long *)(ptep), native_pte_val(pte));
-@@ -38,12 +88,16 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
+@@ -92,12 +92,16 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
  
  static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
  {
@@ -18885,7 +18902,7 @@ index 42eb330..139955c 100644
  
        return ret;
 diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
-index d840e69..98e9581 100644
+index 3034ee5..7cfbfa6 100644
 --- a/arch/x86/kernel/reboot.c
 +++ b/arch/x86/kernel/reboot.c
 @@ -35,7 +35,7 @@ void (*pm_power_off)(void);
@@ -18968,7 +18985,7 @@ index d840e69..98e9581 100644
  }
  #ifdef CONFIG_APM_MODULE
  EXPORT_SYMBOL(machine_real_restart);
-@@ -556,7 +586,7 @@ void __attribute__((weak)) mach_reboot_fixups(void)
+@@ -564,7 +594,7 @@ void __attribute__((weak)) mach_reboot_fixups(void)
   * try to force a triple fault and then cycle between hitting the keyboard
   * controller and doing that
   */
@@ -18977,7 +18994,7 @@ index d840e69..98e9581 100644
  {
        int i;
        int attempt = 0;
-@@ -680,13 +710,13 @@ void native_machine_shutdown(void)
+@@ -688,13 +718,13 @@ void native_machine_shutdown(void)
  #endif
  }
  
@@ -18993,7 +19010,7 @@ index d840e69..98e9581 100644
  {
        printk("machine restart\n");
  
-@@ -695,7 +725,7 @@ static void native_machine_restart(char *__unused)
+@@ -703,7 +733,7 @@ static void native_machine_restart(char *__unused)
        __machine_emergency_restart(0);
  }
  
@@ -19002,7 +19019,7 @@ index d840e69..98e9581 100644
  {
        /* stop other cpus and apics */
        machine_shutdown();
-@@ -706,7 +736,7 @@ static void native_machine_halt(void)
+@@ -714,7 +744,7 @@ static void native_machine_halt(void)
        stop_this_cpu(NULL);
  }
  
@@ -19011,7 +19028,7 @@ index d840e69..98e9581 100644
  {
        if (pm_power_off) {
                if (!reboot_force)
-@@ -715,6 +745,7 @@ static void native_machine_power_off(void)
+@@ -723,6 +753,7 @@ static void native_machine_power_off(void)
        }
        /* a fallback in case there is no PM info available */
        tboot_shutdown(TB_SHUTDOWN_HALT);
@@ -29525,7 +29542,7 @@ index 47ff7e4..0c7d340 100644
         .part_num = MBCS_PART_NUM,
         .mfg_num = MBCS_MFG_NUM,
 diff --git a/drivers/char/mem.c b/drivers/char/mem.c
-index d6e9d08..4493e89 100644
+index d6e9d08..0c314bf 100644
 --- a/drivers/char/mem.c
 +++ b/drivers/char/mem.c
 @@ -18,6 +18,7 @@
@@ -29587,7 +29604,7 @@ index d6e9d08..4493e89 100644
  
 -              remaining = copy_to_user(buf, ptr, sz);
 +#ifdef CONFIG_PAX_USERCOPY
-+              temp = kmalloc(sz, GFP_KERNEL);
++              temp = kmalloc(sz, GFP_KERNEL|GFP_USERCOPY);
 +              if (!temp) {
 +                      unxlate_dev_mem_ptr(p, ptr);
 +                      return -ENOMEM;
@@ -29632,7 +29649,7 @@ index d6e9d08..4493e89 100644
  
 -                      if (copy_to_user(buf, kbuf, sz))
 +#ifdef CONFIG_PAX_USERCOPY
-+                      temp = kmalloc(sz, GFP_KERNEL);
++                      temp = kmalloc(sz, GFP_KERNEL|GFP_USERCOPY);
 +                      if (!temp)
 +                              return -ENOMEM;
 +                      memcpy(temp, kbuf, sz);
@@ -29674,7 +29691,7 @@ index 9df78e2..01ba9ae 100644
  
        *ppos = i;
 diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 4ec04a7..4a092ed 100644
+index 4ec04a7..9918387 100644
 --- a/drivers/char/random.c
 +++ b/drivers/char/random.c
 @@ -261,8 +261,13 @@
@@ -29709,7 +29726,25 @@ index 4ec04a7..4a092ed 100644
  #if 0
        /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
        { 2048, 1638,   1231,   819,    411,    1 },
-@@ -913,7 +925,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+@@ -726,6 +738,17 @@ void add_disk_randomness(struct gendisk *disk)
+ }
+ #endif
++#ifdef CONFIG_PAX_LATENT_ENTROPY
++u64 latent_entropy;
++
++__init void transfer_latent_entropy(void)
++{
++      mix_pool_bytes(&input_pool, &latent_entropy, sizeof(latent_entropy));
++      mix_pool_bytes(&nonblocking_pool, &latent_entropy, sizeof(latent_entropy));
++//    printk(KERN_INFO "PAX: transferring latent entropy: %16llx\n", latent_entropy);
++}
++#endif
++
+ /*********************************************************************
+  *
+  * Entropy extraction routines
+@@ -913,7 +936,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
  
                extract_buf(r, tmp);
                i = min_t(int, nbytes, EXTRACT_SIZE);
@@ -29718,7 +29753,7 @@ index 4ec04a7..4a092ed 100644
                        ret = -EFAULT;
                        break;
                }
-@@ -1238,7 +1250,7 @@ EXPORT_SYMBOL(generate_random_uuid);
+@@ -1238,7 +1261,7 @@ EXPORT_SYMBOL(generate_random_uuid);
  #include <linux/sysctl.h>
  
  static int min_read_thresh = 8, min_write_thresh;
@@ -30449,10 +30484,10 @@ index de43194..a14c4cc 100644
        for (i = 0; i < count; i++) {
                char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
 diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
-index f57e5cf..c82f79d 100644
+index 26c67a7..8d4cbcb 100644
 --- a/drivers/gpu/drm/i915/i915_irq.c
 +++ b/drivers/gpu/drm/i915/i915_irq.c
-@@ -472,7 +472,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
+@@ -496,7 +496,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
        u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
        struct drm_i915_master_private *master_priv;
  
@@ -30461,7 +30496,7 @@ index f57e5cf..c82f79d 100644
  
        /* disable master interrupt before clearing iir  */
        de_ier = I915_READ(DEIER);
-@@ -563,7 +563,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
+@@ -579,7 +579,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
        struct drm_i915_master_private *master_priv;
        u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;
  
@@ -30470,7 +30505,7 @@ index f57e5cf..c82f79d 100644
  
        if (IS_GEN6(dev))
                bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT;
-@@ -1292,7 +1292,7 @@ static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
+@@ -1291,7 +1291,7 @@ static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
        int ret = IRQ_NONE, pipe;
        bool blc_event = false;
  
@@ -30479,7 +30514,7 @@ index f57e5cf..c82f79d 100644
  
        iir = I915_READ(IIR);
  
-@@ -1803,7 +1803,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
+@@ -1802,7 +1802,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  
@@ -30488,7 +30523,7 @@ index f57e5cf..c82f79d 100644
  
        INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
        INIT_WORK(&dev_priv->error_work, i915_error_work_func);
-@@ -1980,7 +1980,7 @@ static void i915_driver_irq_preinstall(struct drm_device * dev)
+@@ -1979,7 +1979,7 @@ static void i915_driver_irq_preinstall(struct drm_device * dev)
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int pipe;
  
@@ -30498,7 +30533,7 @@ index f57e5cf..c82f79d 100644
        INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
        INIT_WORK(&dev_priv->error_work, i915_error_work_func);
 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index d4d162f..e80037c 100644
+index d4d162f..b49a04e 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -2254,7 +2254,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb)
@@ -30519,16 +30554,19 @@ index d4d162f..e80037c 100644
  }
  
  static bool intel_crtc_driving_pch(struct drm_crtc *crtc)
-@@ -7286,7 +7286,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
+@@ -7284,9 +7284,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
+       obj = work->old_fb_obj;
  
-       atomic_clear_mask(1 << intel_crtc->plane,
-                         &obj->pending_flip.counter);
+-      atomic_clear_mask(1 << intel_crtc->plane,
+-                        &obj->pending_flip.counter);
 -      if (atomic_read(&obj->pending_flip) == 0)
++      atomic_clear_mask_unchecked(1 << intel_crtc->plane, &obj->pending_flip);
 +      if (atomic_read_unchecked(&obj->pending_flip) == 0)
                wake_up(&dev_priv->pending_flip_queue);
  
        schedule_work(&work->work);
-@@ -7582,7 +7582,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
+@@ -7582,7 +7581,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        /* Block clients from rendering to the new back buffer until
         * the flip occurs and the object is no longer visible.
         */
@@ -30537,7 +30575,7 @@ index d4d162f..e80037c 100644
  
        ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
        if (ret)
-@@ -7596,7 +7596,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
+@@ -7596,7 +7595,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        return 0;
  
  cleanup_pending:
@@ -31234,10 +31272,10 @@ index 8a8725c..afed796 100644
                        marker = list_first_entry(&queue->head,
                                                 struct vmw_marker, head);
 diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
-index 4da66b4..e948655 100644
+index 054677b..741672a 100644
 --- a/drivers/hid/hid-core.c
 +++ b/drivers/hid/hid-core.c
-@@ -2063,7 +2063,7 @@ static bool hid_ignore(struct hid_device *hdev)
+@@ -2070,7 +2070,7 @@ static bool hid_ignore(struct hid_device *hdev)
  
  int hid_add_device(struct hid_device *hdev)
  {
@@ -31246,7 +31284,7 @@ index 4da66b4..e948655 100644
        int ret;
  
        if (WARN_ON(hdev->status & HID_STAT_ADDED))
-@@ -2078,7 +2078,7 @@ int hid_add_device(struct hid_device *hdev)
+@@ -2085,7 +2085,7 @@ int hid_add_device(struct hid_device *hdev)
        /* XXX hack, any other cleaner solution after the driver core
         * is converted to allow more than 20 bytes as the device name? */
        dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
@@ -32755,10 +32793,10 @@ index b8d8611..7a4a04b 100644
  #include <linux/input.h>
  #include <linux/gameport.h>
 diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
-index fd7a0d5..a4af10c 100644
+index 42f7b25..09fcf46 100644
 --- a/drivers/input/joystick/xpad.c
 +++ b/drivers/input/joystick/xpad.c
-@@ -710,7 +710,7 @@ static void xpad_led_set(struct led_classdev *led_cdev,
+@@ -714,7 +714,7 @@ static void xpad_led_set(struct led_classdev *led_cdev,
  
  static int xpad_led_probe(struct usb_xpad *xpad)
  {
@@ -32767,7 +32805,7 @@ index fd7a0d5..a4af10c 100644
        long led_no;
        struct xpad_led *led;
        struct led_classdev *led_cdev;
-@@ -723,7 +723,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
+@@ -727,7 +727,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
        if (!led)
                return -ENOMEM;
  
@@ -32958,7 +32996,7 @@ index b5fdcb7..5b6c59f 100644
  
        printk(KERN_INFO "lguest: mapped switcher at %p\n",
 diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
-index 3980903..ce25c5e 100644
+index 39809035..ce25c5e 100644
 --- a/drivers/lguest/x86/core.c
 +++ b/drivers/lguest/x86/core.c
 @@ -59,7 +59,7 @@ static struct {
@@ -33315,7 +33353,7 @@ index e24143c..ce2f21a1 100644
  
  void dm_uevent_add(struct mapped_device *md, struct list_head *elist)
 diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 2b30ffd..bf789ce 100644
+index 2b30ffd..362b519 100644
 --- a/drivers/md/md.c
 +++ b/drivers/md/md.c
 @@ -277,10 +277,10 @@ EXPORT_SYMBOL_GPL(md_trim_bio);
@@ -33387,7 +33425,125 @@ index 2b30ffd..bf789ce 100644
  
        INIT_LIST_HEAD(&rdev->same_set);
        init_waitqueue_head(&rdev->blocked_wait);
-@@ -6738,7 +6738,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
+@@ -3744,8 +3744,8 @@ array_state_show(struct mddev *mddev, char *page)
+       return sprintf(page, "%s\n", array_states[st]);
+ }
+-static int do_md_stop(struct mddev * mddev, int ro, int is_open);
+-static int md_set_readonly(struct mddev * mddev, int is_open);
++static int do_md_stop(struct mddev * mddev, int ro, struct block_device *bdev);
++static int md_set_readonly(struct mddev * mddev, struct block_device *bdev);
+ static int do_md_run(struct mddev * mddev);
+ static int restart_array(struct mddev *mddev);
+@@ -3761,14 +3761,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
+               /* stopping an active array */
+               if (atomic_read(&mddev->openers) > 0)
+                       return -EBUSY;
+-              err = do_md_stop(mddev, 0, 0);
++              err = do_md_stop(mddev, 0, NULL);
+               break;
+       case inactive:
+               /* stopping an active array */
+               if (mddev->pers) {
+                       if (atomic_read(&mddev->openers) > 0)
+                               return -EBUSY;
+-                      err = do_md_stop(mddev, 2, 0);
++                      err = do_md_stop(mddev, 2, NULL);
+               } else
+                       err = 0; /* already inactive */
+               break;
+@@ -3776,7 +3776,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
+               break; /* not supported yet */
+       case readonly:
+               if (mddev->pers)
+-                      err = md_set_readonly(mddev, 0);
++                      err = md_set_readonly(mddev, NULL);
+               else {
+                       mddev->ro = 1;
+                       set_disk_ro(mddev->gendisk, 1);
+@@ -3786,7 +3786,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
+       case read_auto:
+               if (mddev->pers) {
+                       if (mddev->ro == 0)
+-                              err = md_set_readonly(mddev, 0);
++                              err = md_set_readonly(mddev, NULL);
+                       else if (mddev->ro == 1)
+                               err = restart_array(mddev);
+                       if (err == 0) {
+@@ -5124,15 +5124,17 @@ void md_stop(struct mddev *mddev)
+ }
+ EXPORT_SYMBOL_GPL(md_stop);
+-static int md_set_readonly(struct mddev *mddev, int is_open)
++static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
+ {
+       int err = 0;
+       mutex_lock(&mddev->open_mutex);
+-      if (atomic_read(&mddev->openers) > is_open) {
++      if (atomic_read(&mddev->openers) > !!bdev) {
+               printk("md: %s still in use.\n",mdname(mddev));
+               err = -EBUSY;
+               goto out;
+       }
++      if (bdev)
++              sync_blockdev(bdev);
+       if (mddev->pers) {
+               __md_stop_writes(mddev);
+@@ -5154,18 +5156,26 @@ out:
+  *   0 - completely stop and dis-assemble array
+  *   2 - stop but do not disassemble array
+  */
+-static int do_md_stop(struct mddev * mddev, int mode, int is_open)
++static int do_md_stop(struct mddev * mddev, int mode,
++                    struct block_device *bdev)
+ {
+       struct gendisk *disk = mddev->gendisk;
+       struct md_rdev *rdev;
+       mutex_lock(&mddev->open_mutex);
+-      if (atomic_read(&mddev->openers) > is_open ||
++      if (atomic_read(&mddev->openers) > !!bdev ||
+           mddev->sysfs_active) {
+               printk("md: %s still in use.\n",mdname(mddev));
+               mutex_unlock(&mddev->open_mutex);
+               return -EBUSY;
+       }
++      if (bdev)
++              /* It is possible IO was issued on some other
++               * open file which was closed before we took ->open_mutex.
++               * As that was not the last close __blkdev_put will not
++               * have called sync_blockdev, so we must.
++               */
++              sync_blockdev(bdev);
+       if (mddev->pers) {
+               if (mddev->ro)
+@@ -5239,7 +5249,7 @@ static void autorun_array(struct mddev *mddev)
+       err = do_md_run(mddev);
+       if (err) {
+               printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
+-              do_md_stop(mddev, 0, 0);
++              do_md_stop(mddev, 0, NULL);
+       }
+ }
+@@ -6237,11 +6247,11 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
+                       goto done_unlock;
+               case STOP_ARRAY:
+-                      err = do_md_stop(mddev, 0, 1);
++                      err = do_md_stop(mddev, 0, bdev);
+                       goto done_unlock;
+               case STOP_ARRAY_RO:
+-                      err = md_set_readonly(mddev, 1);
++                      err = md_set_readonly(mddev, bdev);
+                       goto done_unlock;
+               case BLKROSET:
+@@ -6738,7 +6748,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
  
                spin_unlock(&pers_lock);
                seq_printf(seq, "\n");
@@ -33396,7 +33552,7 @@ index 2b30ffd..bf789ce 100644
                return 0;
        }
        if (v == (void*)2) {
-@@ -6841,7 +6841,7 @@ static int md_seq_open(struct inode *inode, struct file *file)
+@@ -6841,7 +6851,7 @@ static int md_seq_open(struct inode *inode, struct file *file)
                return error;
  
        seq = file->private_data;
@@ -33405,7 +33561,7 @@ index 2b30ffd..bf789ce 100644
        return error;
  }
  
-@@ -6855,7 +6855,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
+@@ -6855,7 +6865,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
        /* always allow read */
        mask = POLLIN | POLLRDNORM;
  
@@ -33414,7 +33570,7 @@ index 2b30ffd..bf789ce 100644
                mask |= POLLERR | POLLPRI;
        return mask;
  }
-@@ -6899,7 +6899,7 @@ static int is_mddev_idle(struct mddev *mddev, int init)
+@@ -6899,7 +6909,7 @@ static int is_mddev_idle(struct mddev *mddev, int init)
                struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
                curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
                              (int)part_stat_read(&disk->part0, sectors[1]) -
@@ -33453,10 +33609,10 @@ index 1c2063c..9639970 100644
  
  struct md_personality
 diff --git a/drivers/md/persistent-data/dm-space-map-checker.c b/drivers/md/persistent-data/dm-space-map-checker.c
-index 50ed53b..4f29d7d 100644
+index fc90c11..c8cd9a9 100644
 --- a/drivers/md/persistent-data/dm-space-map-checker.c
 +++ b/drivers/md/persistent-data/dm-space-map-checker.c
-@@ -159,7 +159,7 @@ static void ca_destroy(struct count_array *ca)
+@@ -167,7 +167,7 @@ static int ca_commit(struct count_array *old, struct count_array *new)
  /*----------------------------------------------------------------*/
  
  struct sm_checker {
@@ -33466,7 +33622,7 @@ index 50ed53b..4f29d7d 100644
        struct count_array old_counts;
        struct count_array counts;
 diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c
-index fc469ba..2d91555 100644
+index 3d0ed53..35dc592 100644
 --- a/drivers/md/persistent-data/dm-space-map-disk.c
 +++ b/drivers/md/persistent-data/dm-space-map-disk.c
 @@ -23,7 +23,7 @@
@@ -33504,7 +33660,7 @@ index 1cbfc6b..56e1dbb 100644
  /*----------------------------------------------------------------*/
  
 diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
-index d7e9577..faa512f2 100644
+index d1f74ab..d1b24fd 100644
 --- a/drivers/md/raid1.c
 +++ b/drivers/md/raid1.c
 @@ -1688,7 +1688,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
@@ -33526,7 +33682,7 @@ index d7e9577..faa512f2 100644
                                               "md/raid1:%s: read error corrected "
                                               "(%d sectors at %llu on %s)\n",
 diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
-index d037adb..ed17dc9 100644
+index a954c95..6e7a21c 100644
 --- a/drivers/md/raid10.c
 +++ b/drivers/md/raid10.c
 @@ -1684,7 +1684,7 @@ static void end_sync_read(struct bio *bio, int error)
@@ -33589,10 +33745,10 @@ index d037adb..ed17dc9 100644
  
                        rdev_dec_pending(rdev, mddev);
 diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
-index f351422..85c01bb 100644
+index 73a5800..2b0e3b1 100644
 --- a/drivers/md/raid5.c
 +++ b/drivers/md/raid5.c
-@@ -1686,18 +1686,18 @@ static void raid5_end_read_request(struct bio * bi, int error)
+@@ -1694,18 +1694,18 @@ static void raid5_end_read_request(struct bio * bi, int error)
                                (unsigned long long)(sh->sector
                                                     + rdev->data_offset),
                                bdevname(rdev->bdev, b));
@@ -33615,7 +33771,7 @@ index f351422..85c01bb 100644
                if (test_bit(R5_ReadRepl, &sh->dev[i].flags))
                        printk_ratelimited(
                                KERN_WARNING
-@@ -1726,7 +1726,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
+@@ -1734,7 +1734,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
                                (unsigned long long)(sh->sector
                                                     + rdev->data_offset),
                                bdn);
@@ -33651,7 +33807,7 @@ index a7d876f..8c21b61 100644
        struct dvb_demux *demux;
        void *priv;
 diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
-index 00a6732..70a682e 100644
+index 39eab73..60033e7 100644
 --- a/drivers/media/dvb/dvb-core/dvbdev.c
 +++ b/drivers/media/dvb/dvb-core/dvbdev.c
 @@ -192,7 +192,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
@@ -33750,6 +33906,33 @@ index 9cde353..8c6a1c3 100644
        struct i2c_client               i2c_client;
        u32                             i2c_rc;
  
+diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c
+index 7930ca5..235bf7d 100644
+--- a/drivers/media/video/cx25821/cx25821-core.c
++++ b/drivers/media/video/cx25821/cx25821-core.c
+@@ -912,9 +912,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
+       list_add_tail(&dev->devlist, &cx25821_devlist);
+       mutex_unlock(&cx25821_devlist_mutex);
+-      strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
+-      strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
+-
+       if (dev->pci->device != 0x8210) {
+               pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
+                       __func__, dev->pci->device);
+diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h
+index b9aa801..029f293 100644
+--- a/drivers/media/video/cx25821/cx25821.h
++++ b/drivers/media/video/cx25821/cx25821.h
+@@ -187,7 +187,7 @@ enum port {
+ };
+ struct cx25821_board {
+-      char *name;
++      const char *name;
+       enum port porta;
+       enum port portb;
+       enum port portc;
 diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
 index 04bf662..e0ac026 100644
 --- a/drivers/media/video/cx88/cx88-alsa.c
@@ -34561,7 +34744,7 @@ index d783f4f..97fa1b0 100644
        {"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"},
        {"D-Link DFE-580TX 4 port Server Adapter"},
 diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
-index 528a886..e6a98a3 100644
+index 1bbf6b3..430dcd0 100644
 --- a/drivers/net/ethernet/emulex/benet/be_main.c
 +++ b/drivers/net/ethernet/emulex/benet/be_main.c
 @@ -403,7 +403,7 @@ static void accumulate_16bit_val(u32 *acc, u16 val)
@@ -34847,6 +35030,36 @@ index 8636e83..ab9bbc3 100644
        struct ixgbe_mbx_stats stats;
        u32 timeout;
        u32 usec_delay;
+diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+index 307611a..d8e4562 100644
+--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+@@ -969,8 +969,6 @@ static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data)
+       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+       for (i = 0; i < q_vector->txr_count; i++) {
+               tx_ring = &(adapter->tx_ring[r_idx]);
+-              tx_ring->total_bytes = 0;
+-              tx_ring->total_packets = 0;
+               ixgbevf_clean_tx_irq(adapter, tx_ring);
+               r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+                                     r_idx + 1);
+@@ -994,16 +992,6 @@ static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data)
+       struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbevf_ring  *rx_ring;
+       int r_idx;
+-      int i;
+-
+-      r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+-      for (i = 0; i < q_vector->rxr_count; i++) {
+-              rx_ring = &(adapter->rx_ring[r_idx]);
+-              rx_ring->total_bytes = 0;
+-              rx_ring->total_packets = 0;
+-              r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+-                                    r_idx + 1);
+-      }
+       if (!q_vector->rxr_count)
+               return IRQ_HANDLED;
 diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h
 index 25c951d..cc7cf33 100644
 --- a/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -34924,7 +35137,7 @@ index 4a518a3..936b334 100644
  #define VXGE_HW_VIRTUAL_PATH_HANDLE(vpath)                            \
                ((struct __vxge_hw_vpath_handle *)(vpath)->vpath_handles.next)
 diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
-index ce6b44d..74f10c2 100644
+index 161e045..0bb5b86 100644
 --- a/drivers/net/ethernet/realtek/r8169.c
 +++ b/drivers/net/ethernet/realtek/r8169.c
 @@ -708,17 +708,17 @@ struct rtl8169_private {
@@ -34977,10 +35190,10 @@ index c07cfe9..81cbf7e 100644
  
  /* To mask all all interrupts.*/
 diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-index 48d56da..a27e46c 100644
+index 9bdfaba..3d8f8d4 100644
 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -1584,7 +1584,7 @@ static const struct file_operations stmmac_rings_status_fops = {
+@@ -1587,7 +1587,7 @@ static const struct file_operations stmmac_rings_status_fops = {
        .open = stmmac_sysfs_ring_open,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -34989,7 +35202,7 @@ index 48d56da..a27e46c 100644
  };
  
  static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
-@@ -1656,7 +1656,7 @@ static const struct file_operations stmmac_dma_cap_fops = {
+@@ -1659,7 +1659,7 @@ static const struct file_operations stmmac_dma_cap_fops = {
        .open = stmmac_sysfs_dma_cap_open,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -35033,19 +35246,6 @@ index d6be64b..5d97e3b 100644
  
        /* Ignore return since this msg is optional. */
        rndis_filter_send_request(dev, request);
-diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
-index cb8fd50..003ec38 100644
---- a/drivers/net/macvtap.c
-+++ b/drivers/net/macvtap.c
-@@ -528,6 +528,8 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
-               }
-               base = (unsigned long)from->iov_base + offset1;
-               size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
-+              if (i + size >= MAX_SKB_FRAGS)
-+                      return -EFAULT;
-               num_pages = get_user_pages_fast(base, size, 0, &page[i]);
-               if ((num_pages != size) ||
-                   (num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags))
 diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
 index 21d7151..8034208 100644
 --- a/drivers/net/ppp/ppp_generic.c
@@ -35246,7 +35446,7 @@ index 2d2a688..35f2372 100644
                                    hso_start_serial_device(serial_table[i], GFP_NOIO);
                                hso_kick_transmit(dev2ser(serial_table[i]));
 diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
-index c54b7d37..af1f359 100644
+index 420d69b..74f90a2 100644
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
 @@ -119,6 +119,7 @@ struct ath_ops {
@@ -36534,7 +36734,7 @@ index aceffad..c35c08d 100644
        fc_frame_free(fp);
  }
 diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
-index 441d88a..689ad71 100644
+index d109cc3..09f4e7d 100644
 --- a/drivers/scsi/libsas/sas_ata.c
 +++ b/drivers/scsi/libsas/sas_ata.c
 @@ -529,7 +529,7 @@ static struct ata_port_operations sas_sata_ops = {
@@ -37385,6 +37585,51 @@ index 0d4aa82..f7832d4 100644
  extern void tmem_register_hostops(struct tmem_hostops *m);
  
  /* core tmem accessor functions */
+diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
+index 30a6770..fa323f8 100644
+--- a/drivers/target/target_core_cdb.c
++++ b/drivers/target/target_core_cdb.c
+@@ -1107,7 +1107,7 @@ int target_emulate_write_same(struct se_task *task)
+       if (num_blocks != 0)
+               range = num_blocks;
+       else
+-              range = (dev->transport->get_blocks(dev) - lba);
++              range = (dev->transport->get_blocks(dev) - lba) + 1;
+       pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n",
+                (unsigned long long)lba, (unsigned long long)range);
+diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
+index c3148b1..89d10e6 100644
+--- a/drivers/target/target_core_pr.c
++++ b/drivers/target/target_core_pr.c
+@@ -2038,7 +2038,7 @@ static int __core_scsi3_write_aptpl_to_file(
+       if (IS_ERR(file) || !file || !file->f_dentry) {
+               pr_err("filp_open(%s) for APTPL metadata"
+                       " failed\n", path);
+-              return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT);
++              return IS_ERR(file) ? PTR_ERR(file) : -ENOENT;
+       }
+       iov[0].iov_base = &buf[0];
+@@ -3826,7 +3826,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
+                       " SPC-2 reservation is held, returning"
+                       " RESERVATION_CONFLICT\n");
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+-              ret = EINVAL;
++              ret = -EINVAL;
+               goto out;
+       }
+@@ -3836,7 +3836,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
+        */
+       if (!cmd->se_sess) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto out;
+       }
+       if (cmd->data_length < 24) {
 diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
 index f015839..b15dfc4 100644
 --- a/drivers/target/target_core_tmr.c
@@ -37441,6 +37686,19 @@ index 443704f..92d3517 100644
            cmd->t_task_list_num)
                cmd->transport_state |= CMD_T_SENT;
  
+diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
+index a375f25..da90f64 100644
+--- a/drivers/target/tcm_fc/tfc_cmd.c
++++ b/drivers/target/tcm_fc/tfc_cmd.c
+@@ -240,6 +240,8 @@ u32 ft_get_task_tag(struct se_cmd *se_cmd)
+ {
+       struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
++      if (cmd->aborted)
++              return ~0;
+       return fc_seq_exch(cmd->seq)->rxid;
+ }
 diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
 index 3436436..772237b 100644
 --- a/drivers/tty/hvc/hvcs.c
@@ -41631,7 +41889,7 @@ index d146e18..12d1bd1 100644
                                fd_offset + ex.a_text);
                if (error != N_DATADDR(ex)) {
 diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
-index 16f7354..185d8dc 100644
+index 16f7354..7cc1e24 100644
 --- a/fs/binfmt_elf.c
 +++ b/fs/binfmt_elf.c
 @@ -32,6 +32,7 @@
@@ -41762,17 +42020,16 @@ index 16f7354..185d8dc 100644
                                error = -ENOMEM;
                                goto out_close;
                        }
-@@ -525,6 +549,351 @@ out:
+@@ -525,6 +549,311 @@ out:
        return error;
  }
  
-+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_XATTR_PAX_FLAGS)
++#ifdef CONFIG_PAX_PT_PAX_FLAGS
++#ifdef CONFIG_PAX_SOFTMODE
 +static unsigned long pax_parse_pt_pax_softmode(const struct elf_phdr * const elf_phdata)
 +{
 +      unsigned long pax_flags = 0UL;
 +
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+
 +#ifdef CONFIG_PAX_PAGEEXEC
 +      if (elf_phdata->p_flags & PF_PAGEEXEC)
 +              pax_flags |= MF_PAX_PAGEEXEC;
@@ -41783,15 +42040,6 @@ index 16f7354..185d8dc 100644
 +              pax_flags |= MF_PAX_SEGMEXEC;
 +#endif
 +
-+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
-+      if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
-+              if ((__supported_pte_mask & _PAGE_NX))
-+                      pax_flags &= ~MF_PAX_SEGMEXEC;
-+              else
-+                      pax_flags &= ~MF_PAX_PAGEEXEC;
-+      }
-+#endif
-+
 +#ifdef CONFIG_PAX_EMUTRAMP
 +      if (elf_phdata->p_flags & PF_EMUTRAMP)
 +              pax_flags |= MF_PAX_EMUTRAMP;
@@ -41807,17 +42055,14 @@ index 16f7354..185d8dc 100644
 +              pax_flags |= MF_PAX_RANDMMAP;
 +#endif
 +
-+#endif
-+
 +      return pax_flags;
 +}
++#endif
 +
 +static unsigned long pax_parse_pt_pax_hardmode(const struct elf_phdr * const elf_phdata)
 +{
 +      unsigned long pax_flags = 0UL;
 +
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+
 +#ifdef CONFIG_PAX_PAGEEXEC
 +      if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
 +              pax_flags |= MF_PAX_PAGEEXEC;
@@ -41828,15 +42073,6 @@ index 16f7354..185d8dc 100644
 +              pax_flags |= MF_PAX_SEGMEXEC;
 +#endif
 +
-+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
-+      if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
-+              if ((__supported_pte_mask & _PAGE_NX))
-+                      pax_flags &= ~MF_PAX_SEGMEXEC;
-+              else
-+                      pax_flags &= ~MF_PAX_PAGEEXEC;
-+      }
-+#endif
-+
 +#ifdef CONFIG_PAX_EMUTRAMP
 +      if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
 +              pax_flags |= MF_PAX_EMUTRAMP;
@@ -41852,11 +42088,79 @@ index 16f7354..185d8dc 100644
 +              pax_flags |= MF_PAX_RANDMMAP;
 +#endif
 +
++      return pax_flags;
++}
++#endif
++
++#ifdef CONFIG_PAX_XATTR_PAX_FLAGS
++#ifdef CONFIG_PAX_SOFTMODE
++static unsigned long pax_parse_xattr_pax_softmode(unsigned long pax_flags_softmode)
++{
++      unsigned long pax_flags = 0UL;
++
++#ifdef CONFIG_PAX_PAGEEXEC
++      if (pax_flags_softmode & MF_PAX_PAGEEXEC)
++              pax_flags |= MF_PAX_PAGEEXEC;
++#endif
++
++#ifdef CONFIG_PAX_SEGMEXEC
++      if (pax_flags_softmode & MF_PAX_SEGMEXEC)
++              pax_flags |= MF_PAX_SEGMEXEC;
++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++      if (pax_flags_softmode & MF_PAX_EMUTRAMP)
++              pax_flags |= MF_PAX_EMUTRAMP;
++#endif
++
++#ifdef CONFIG_PAX_MPROTECT
++      if (pax_flags_softmode & MF_PAX_MPROTECT)
++              pax_flags |= MF_PAX_MPROTECT;
++#endif
++
++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
++      if (randomize_va_space && (pax_flags_softmode & MF_PAX_RANDMMAP))
++              pax_flags |= MF_PAX_RANDMMAP;
++#endif
++
++      return pax_flags;
++}
++#endif
++
++static unsigned long pax_parse_xattr_pax_hardmode(unsigned long pax_flags_hardmode)
++{
++      unsigned long pax_flags = 0UL;
++
++#ifdef CONFIG_PAX_PAGEEXEC
++      if (!(pax_flags_hardmode & MF_PAX_PAGEEXEC))
++              pax_flags |= MF_PAX_PAGEEXEC;
++#endif
++
++#ifdef CONFIG_PAX_SEGMEXEC
++      if (!(pax_flags_hardmode & MF_PAX_SEGMEXEC))
++              pax_flags |= MF_PAX_SEGMEXEC;
++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++      if (!(pax_flags_hardmode & MF_PAX_EMUTRAMP))
++              pax_flags |= MF_PAX_EMUTRAMP;
++#endif
++
++#ifdef CONFIG_PAX_MPROTECT
++      if (!(pax_flags_hardmode & MF_PAX_MPROTECT))
++              pax_flags |= MF_PAX_MPROTECT;
++#endif
++
++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
++      if (randomize_va_space && !(pax_flags_hardmode & MF_PAX_RANDMMAP))
++              pax_flags |= MF_PAX_RANDMMAP;
 +#endif
 +
 +      return pax_flags;
 +}
++#endif
 +
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
 +{
 +      unsigned long pax_flags = 0UL;
@@ -41873,15 +42177,6 @@ index 16f7354..185d8dc 100644
 +              pax_flags |= MF_PAX_SEGMEXEC;
 +#endif
 +
-+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
-+      if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
-+              if ((__supported_pte_mask & _PAGE_NX))
-+                      pax_flags &= ~MF_PAX_SEGMEXEC;
-+              else
-+                      pax_flags &= ~MF_PAX_PAGEEXEC;
-+      }
-+#endif
-+
 +#ifdef CONFIG_PAX_EMUTRAMP
 +      if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
 +              pax_flags |= MF_PAX_EMUTRAMP;
@@ -41903,19 +42198,17 @@ index 16f7354..185d8dc 100644
 +      pax_flags |= MF_PAX_PAGEEXEC;
 +#endif
 +
++#ifdef CONFIG_PAX_SEGMEXEC
++      pax_flags |= MF_PAX_SEGMEXEC;
++#endif
++
 +#ifdef CONFIG_PAX_MPROTECT
 +      pax_flags |= MF_PAX_MPROTECT;
 +#endif
 +
 +#ifdef CONFIG_PAX_RANDMMAP
-+      pax_flags |= MF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+      if (!(pax_flags & MF_PAX_PAGEEXEC) || !(__supported_pte_mask & _PAGE_NX)) {
-+              pax_flags &= ~MF_PAX_PAGEEXEC;
-+              pax_flags |= MF_PAX_SEGMEXEC;
-+      }
++      if (randomize_va_space)
++              pax_flags |= MF_PAX_RANDMMAP;
 +#endif
 +
 +#endif
@@ -41952,90 +42245,6 @@ index 16f7354..185d8dc 100644
 +      return ~0UL;
 +}
 +
-+#ifdef CONFIG_PAX_XATTR_PAX_FLAGS
-+static unsigned long pax_parse_xattr_pax_softmode(unsigned long pax_flags_softmode)
-+{
-+      unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+      if (pax_flags_softmode & MF_PAX_PAGEEXEC)
-+              pax_flags |= MF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+      if (pax_flags_softmode & MF_PAX_SEGMEXEC)
-+              pax_flags |= MF_PAX_SEGMEXEC;
-+#endif
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
-+      if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
-+              if ((__supported_pte_mask & _PAGE_NX))
-+                      pax_flags &= ~MF_PAX_SEGMEXEC;
-+              else
-+                      pax_flags &= ~MF_PAX_PAGEEXEC;
-+      }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+      if (pax_flags_softmode & MF_PAX_EMUTRAMP)
-+              pax_flags |= MF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+      if (pax_flags_softmode & MF_PAX_MPROTECT)
-+              pax_flags |= MF_PAX_MPROTECT;
-+#endif
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
-+      if (randomize_va_space && (pax_flags_softmode & MF_PAX_RANDMMAP))
-+              pax_flags |= MF_PAX_RANDMMAP;
-+#endif
-+
-+      return pax_flags;
-+}
-+
-+static unsigned long pax_parse_xattr_pax_hardmode(unsigned long pax_flags_hardmode)
-+{
-+      unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+      if (!(pax_flags_hardmode & MF_PAX_PAGEEXEC))
-+              pax_flags |= MF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+      if (!(pax_flags_hardmode & MF_PAX_SEGMEXEC))
-+              pax_flags |= MF_PAX_SEGMEXEC;
-+#endif
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
-+      if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
-+              if ((__supported_pte_mask & _PAGE_NX))
-+                      pax_flags &= ~MF_PAX_SEGMEXEC;
-+              else
-+                      pax_flags &= ~MF_PAX_PAGEEXEC;
-+      }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+      if (!(pax_flags_hardmode & MF_PAX_EMUTRAMP))
-+              pax_flags |= MF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+      if (!(pax_flags_hardmode & MF_PAX_MPROTECT))
-+              pax_flags |= MF_PAX_MPROTECT;
-+#endif
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
-+      if (randomize_va_space && !(pax_flags_hardmode & MF_PAX_RANDMMAP))
-+              pax_flags |= MF_PAX_RANDMMAP;
-+#endif
-+
-+      return pax_flags;
-+}
-+#endif
-+
 +static unsigned long pax_parse_xattr_pax(struct file * const file)
 +{
 +
@@ -42103,6 +42312,15 @@ index 16f7354..185d8dc 100644
 +      if (pt_pax_flags != ~0UL)
 +              pax_flags = pt_pax_flags;
 +
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
++      if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
++              if ((__supported_pte_mask & _PAGE_NX))
++                      pax_flags &= ~MF_PAX_SEGMEXEC;
++              else
++                      pax_flags &= ~MF_PAX_PAGEEXEC;
++      }
++#endif
++
 +      if (0 > pax_check_flags(&pax_flags))
 +              return -EINVAL;
 +
@@ -42114,7 +42332,7 @@ index 16f7354..185d8dc 100644
  /*
   * These are the functions used to load ELF style executables and shared
   * libraries.  There is no binary dependent code anywhere else.
-@@ -541,6 +910,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top)
+@@ -541,6 +870,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top)
  {
        unsigned int random_variable = 0;
  
@@ -42126,7 +42344,7 @@ index 16f7354..185d8dc 100644
        if ((current->flags & PF_RANDOMIZE) &&
                !(current->personality & ADDR_NO_RANDOMIZE)) {
                random_variable = get_random_int() & STACK_RND_MASK;
-@@ -559,7 +933,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -559,7 +893,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        unsigned long load_addr = 0, load_bias = 0;
        int load_addr_set = 0;
        char * elf_interpreter = NULL;
@@ -42135,7 +42353,7 @@ index 16f7354..185d8dc 100644
        struct elf_phdr *elf_ppnt, *elf_phdata;
        unsigned long elf_bss, elf_brk;
        int retval, i;
-@@ -569,11 +943,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -569,11 +903,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long reloc_func_desc __maybe_unused = 0;
        int executable_stack = EXSTACK_DEFAULT;
@@ -42148,7 +42366,7 @@ index 16f7354..185d8dc 100644
  
        loc = kmalloc(sizeof(*loc), GFP_KERNEL);
        if (!loc) {
-@@ -709,11 +1083,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -709,11 +1043,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                goto out_free_dentry;
  
        /* OK, This is the point of no return */
@@ -42173,7 +42391,7 @@ index 16f7354..185d8dc 100644
 +
 +      current->mm->def_flags = 0;
 +
-+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_XATTR_PAX_FLAGS)
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
 +      if (0 > pax_parse_pax_flags(&loc->elf_ex, elf_phdata, bprm->file)) {
 +              send_sig(SIGKILL, current, 0);
 +              goto out_free_dentry;
@@ -42231,7 +42449,7 @@ index 16f7354..185d8dc 100644
        if (elf_read_implies_exec(loc->elf_ex, executable_stack))
                current->personality |= READ_IMPLIES_EXEC;
  
-@@ -804,6 +1248,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -804,6 +1208,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
  #else
                        load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
  #endif
@@ -42252,7 +42470,7 @@ index 16f7354..185d8dc 100644
                }
  
                error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
-@@ -836,9 +1294,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -836,9 +1254,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                 * allowed task size. Note that p_filesz must always be
                 * <= p_memsz so it is only necessary to check p_memsz.
                 */
@@ -42265,7 +42483,7 @@ index 16f7354..185d8dc 100644
                        /* set_brk can never work. Avoid overflows. */
                        send_sig(SIGKILL, current, 0);
                        retval = -EINVAL;
-@@ -877,11 +1335,40 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -877,11 +1295,40 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                goto out_free_dentry;
        }
        if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
@@ -42309,7 +42527,7 @@ index 16f7354..185d8dc 100644
        if (elf_interpreter) {
                unsigned long uninitialized_var(interp_map_addr);
  
-@@ -1109,7 +1596,7 @@ static bool always_dump_vma(struct vm_area_struct *vma)
+@@ -1109,7 +1556,7 @@ static bool always_dump_vma(struct vm_area_struct *vma)
   * Decide what to dump of a segment, part, all or none.
   */
  static unsigned long vma_dump_size(struct vm_area_struct *vma,
@@ -42318,7 +42536,7 @@ index 16f7354..185d8dc 100644
  {
  #define FILTER(type)  (mm_flags & (1UL << MMF_DUMP_##type))
  
-@@ -1146,7 +1633,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
+@@ -1146,7 +1593,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
        if (vma->vm_file == NULL)
                return 0;
  
@@ -42327,7 +42545,7 @@ index 16f7354..185d8dc 100644
                goto whole;
  
        /*
-@@ -1368,9 +1855,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
+@@ -1368,9 +1815,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
  {
        elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
        int i = 0;
@@ -42339,7 +42557,7 @@ index 16f7354..185d8dc 100644
        fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
  }
  
-@@ -1892,14 +2379,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
+@@ -1892,14 +2339,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
  }
  
  static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
@@ -42356,7 +42574,7 @@ index 16f7354..185d8dc 100644
        return size;
  }
  
-@@ -1993,7 +2480,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -1993,7 +2440,7 @@ static int elf_core_dump(struct coredump_params *cprm)
  
        dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
  
@@ -42365,7 +42583,7 @@ index 16f7354..185d8dc 100644
        offset += elf_core_extra_data_size();
        e_shoff = offset;
  
-@@ -2007,10 +2494,12 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2007,10 +2454,12 @@ static int elf_core_dump(struct coredump_params *cprm)
        offset = dataoff;
  
        size += sizeof(*elf);
@@ -42378,7 +42596,7 @@ index 16f7354..185d8dc 100644
        if (size > cprm->limit
            || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
                goto end_coredump;
-@@ -2024,7 +2513,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2024,7 +2473,7 @@ static int elf_core_dump(struct coredump_params *cprm)
                phdr.p_offset = offset;
                phdr.p_vaddr = vma->vm_start;
                phdr.p_paddr = 0;
@@ -42387,7 +42605,7 @@ index 16f7354..185d8dc 100644
                phdr.p_memsz = vma->vm_end - vma->vm_start;
                offset += phdr.p_filesz;
                phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
-@@ -2035,6 +2524,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2035,6 +2484,7 @@ static int elf_core_dump(struct coredump_params *cprm)
                phdr.p_align = ELF_EXEC_PAGESIZE;
  
                size += sizeof(phdr);
@@ -42395,7 +42613,7 @@ index 16f7354..185d8dc 100644
                if (size > cprm->limit
                    || !dump_write(cprm->file, &phdr, sizeof(phdr)))
                        goto end_coredump;
-@@ -2059,7 +2549,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2059,7 +2509,7 @@ static int elf_core_dump(struct coredump_params *cprm)
                unsigned long addr;
                unsigned long end;
  
@@ -42404,7 +42622,7 @@ index 16f7354..185d8dc 100644
  
                for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
                        struct page *page;
-@@ -2068,6 +2558,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2068,6 +2518,7 @@ static int elf_core_dump(struct coredump_params *cprm)
                        page = get_dump_page(addr);
                        if (page) {
                                void *kaddr = kmap(page);
@@ -42412,7 +42630,7 @@ index 16f7354..185d8dc 100644
                                stop = ((size += PAGE_SIZE) > cprm->limit) ||
                                        !dump_write(cprm->file, kaddr,
                                                    PAGE_SIZE);
-@@ -2085,6 +2576,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2085,6 +2536,7 @@ static int elf_core_dump(struct coredump_params *cprm)
  
        if (e_phnum == PN_XNUM) {
                size += sizeof(*shdr4extnum);
@@ -42420,7 +42638,7 @@ index 16f7354..185d8dc 100644
                if (size > cprm->limit
                    || !dump_write(cprm->file, shdr4extnum,
                                   sizeof(*shdr4extnum)))
-@@ -2105,6 +2597,97 @@ out:
+@@ -2105,6 +2557,97 @@ out:
  
  #endif                /* CONFIG_ELF_CORE */
  
@@ -42555,7 +42773,7 @@ index 6b2daf9..a70dccb 100644
                        goto err;
                }
 diff --git a/fs/bio.c b/fs/bio.c
-index 84da885..2149cd9 100644
+index 84da885..bac1d48 100644
 --- a/fs/bio.c
 +++ b/fs/bio.c
 @@ -838,7 +838,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
@@ -42563,6 +42781,15 @@ index 84da885..2149cd9 100644
                 * Overflow, abort
                 */
 -              if (end < start)
++              if (end < start || end - start > INT_MAX - nr_pages)
+                       return ERR_PTR(-EINVAL);
+               nr_pages += end - start;
+@@ -972,7 +972,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
+               /*
+                * Overflow, abort
+                */
+-              if (end < start)
 +              if (end < start || end - start > INT_MAX - nr_pages)
                        return ERR_PTR(-EINVAL);
  
@@ -43457,10 +43684,10 @@ index ab35b11..b30af66 100644
                /* Free the char* */
                kfree(buf);
 diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
-index 3a06f40..f7af544 100644
+index c0038f6..47ab347 100644
 --- a/fs/ecryptfs/miscdev.c
 +++ b/fs/ecryptfs/miscdev.c
-@@ -345,7 +345,7 @@ check_list:
+@@ -355,7 +355,7 @@ check_list:
                goto out_unlock_msg_ctx;
        i = PKT_TYPE_SIZE + PKT_CTR_SIZE;
        if (msg_ctx->msg) {
@@ -43492,7 +43719,7 @@ index b2a34a1..162fa69 100644
        return rc;
  }
 diff --git a/fs/exec.c b/fs/exec.c
-index b1fd202..582240d 100644
+index 29e5f84..8bfc7cb 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -55,6 +55,15 @@
@@ -43952,7 +44179,7 @@ index b1fd202..582240d 100644
        cn->corename = kmalloc(cn->size, GFP_KERNEL);
        cn->used = 0;
  
-@@ -1821,6 +1953,228 @@ out:
+@@ -1821,6 +1953,250 @@ out:
        return ispipe;
  }
  
@@ -44097,7 +44324,7 @@ index b1fd202..582240d 100644
 +
 +#ifdef CONFIG_PAX_USERCOPY
 +/* 0: not at all, 1: fully, 2: fully inside frame, -1: partially (implies an error) */
-+int object_is_on_stack(const void *obj, unsigned long len)
++static noinline int check_stack_object(const void *obj, unsigned long len)
 +{
 +      const void * const stack = task_stack_page(current);
 +      const void * const stackend = stack + THREAD_SIZE;
@@ -44143,7 +44370,7 @@ index b1fd202..582240d 100644
 +#endif
 +}
 +
-+__noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
++static __noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
 +{
 +      if (current->signal->curr_ip)
 +              printk(KERN_ERR "PAX: From %pI4: kernel memory %s attempt detected %s %p (%s) (%lu bytes)\n",
@@ -44157,6 +44384,28 @@ index b1fd202..582240d 100644
 +}
 +#endif
 +
++void check_object_size(const void *ptr, unsigned long n, bool to)
++{
++
++#ifdef CONFIG_PAX_USERCOPY
++      const char *type;
++
++      if (!n)
++              return;
++
++      type = check_heap_object(ptr, n, to);
++      if (!type) {
++              if (check_stack_object(ptr, n) != -1)
++                      return;
++              type = "<process stack>";
++      }
++
++      pax_report_usercopy(ptr, n, to, type);
++#endif
++
++}
++EXPORT_SYMBOL(check_object_size);
++
 +#ifdef CONFIG_PAX_MEMORY_STACKLEAK
 +void pax_track_stack(void)
 +{
@@ -44181,7 +44430,7 @@ index b1fd202..582240d 100644
  static int zap_process(struct task_struct *start, int exit_code)
  {
        struct task_struct *t;
-@@ -2018,17 +2372,17 @@ static void wait_for_dump_helpers(struct file *file)
+@@ -2018,17 +2394,17 @@ static void wait_for_dump_helpers(struct file *file)
        pipe = file->f_path.dentry->d_inode->i_pipe;
  
        pipe_lock(pipe);
@@ -44204,7 +44453,7 @@ index b1fd202..582240d 100644
        pipe_unlock(pipe);
  
  }
-@@ -2089,7 +2443,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2089,7 +2465,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
        int retval = 0;
        int flag = 0;
        int ispipe;
@@ -44213,7 +44462,7 @@ index b1fd202..582240d 100644
        struct coredump_params cprm = {
                .signr = signr,
                .regs = regs,
-@@ -2104,6 +2458,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2104,6 +2480,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  
        audit_core_dumps(signr);
  
@@ -44223,7 +44472,7 @@ index b1fd202..582240d 100644
        binfmt = mm->binfmt;
        if (!binfmt || !binfmt->core_dump)
                goto fail;
-@@ -2171,7 +2528,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2171,7 +2550,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
                }
                cprm.limit = RLIM_INFINITY;
  
@@ -44232,7 +44481,7 @@ index b1fd202..582240d 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);
-@@ -2198,6 +2555,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2198,6 +2577,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
        } else {
                struct inode *inode;
  
@@ -44241,7 +44490,7 @@ index b1fd202..582240d 100644
                if (cprm.limit < binfmt->min_coredump)
                        goto fail_unlock;
  
-@@ -2241,7 +2600,7 @@ close_fail:
+@@ -2241,7 +2622,7 @@ close_fail:
                filp_close(cprm.file, NULL);
  fail_dropcount:
        if (ispipe)
@@ -44250,7 +44499,7 @@ index b1fd202..582240d 100644
  fail_unlock:
        kfree(cn.corename);
  fail_corename:
-@@ -2260,7 +2619,7 @@ fail:
+@@ -2260,7 +2641,7 @@ fail:
   */
  int dump_write(struct file *file, const void *addr, int nr)
  {
@@ -44338,6 +44587,18 @@ index 0e01e90..ae2bd5e 100644
        atomic_t s_lock_busy;
  
        /* locality groups */
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index 1365903..9727522 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -261,7 +261,6 @@ group_extend_out:
+               err = ext4_move_extents(filp, donor_filp, me.orig_start,
+                                       me.donor_start, me.len, &me.moved_len);
+               mnt_drop_write_file(filp);
+-              mnt_drop_write(filp->f_path.mnt);
+               if (copy_to_user((struct move_extent __user *)arg,
+                                &me, sizeof(me)))
 diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
 index 6b0a57e..1955a44 100644
 --- a/fs/ext4/mballoc.c
@@ -44498,10 +44759,10 @@ index 75e7c1f..1eb3e4d 100644
                        break;
                err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
 diff --git a/fs/fifo.c b/fs/fifo.c
-index b1a524d..4ee270e 100644
+index cf6f434..3d7942c 100644
 --- a/fs/fifo.c
 +++ b/fs/fifo.c
-@@ -58,10 +58,10 @@ static int fifo_open(struct inode *inode, struct file *filp)
+@@ -59,10 +59,10 @@ static int fifo_open(struct inode *inode, struct file *filp)
         */
                filp->f_op = &read_pipefifo_fops;
                pipe->r_counter++;
@@ -44530,10 +44791,10 @@ index b1a524d..4ee270e 100644
  
 -              if (!pipe->readers) {
 +              if (!atomic_read(&pipe->readers)) {
-                       wait_for_partner(inode, &pipe->r_counter);
-                       if (signal_pending(current))
+                       if (wait_for_partner(inode, &pipe->r_counter))
                                goto err_wr;
-@@ -105,11 +105,11 @@ static int fifo_open(struct inode *inode, struct file *filp)
+               }
+@@ -104,11 +104,11 @@ static int fifo_open(struct inode *inode, struct file *filp)
         */
                filp->f_op = &rdwr_pipefifo_fops;
  
@@ -44548,7 +44809,7 @@ index b1a524d..4ee270e 100644
                        wake_up_partner(inode);
                break;
  
-@@ -123,19 +123,19 @@ static int fifo_open(struct inode *inode, struct file *filp)
+@@ -122,19 +122,19 @@ static int fifo_open(struct inode *inode, struct file *filp)
        return 0;
  
  err_rd:
@@ -46208,9 +46469,36 @@ index 8392cb8..80d6193 100644
        memcpy(c->data, &cookie, 4);
        c->len=4;
 diff --git a/fs/locks.c b/fs/locks.c
-index 0d68f1f..f216b79 100644
+index 6a64f15..c3dacf2 100644
 --- a/fs/locks.c
 +++ b/fs/locks.c
+@@ -308,7 +308,7 @@ static int flock_make_lock(struct file *filp, struct file_lock **lock,
+       return 0;
+ }
+-static int assign_type(struct file_lock *fl, int type)
++static int assign_type(struct file_lock *fl, long type)
+ {
+       switch (type) {
+       case F_RDLCK:
+@@ -445,7 +445,7 @@ static const struct lock_manager_operations lease_manager_ops = {
+ /*
+  * Initialize a lease, use the default lock manager operations
+  */
+-static int lease_init(struct file *filp, int type, struct file_lock *fl)
++static int lease_init(struct file *filp, long type, struct file_lock *fl)
+  {
+       if (assign_type(fl, type) != 0)
+               return -EINVAL;
+@@ -463,7 +463,7 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl)
+ }
+ /* Allocate a file_lock initialised to this type of lease */
+-static struct file_lock *lease_alloc(struct file *filp, int type)
++static struct file_lock *lease_alloc(struct file *filp, long type)
+ {
+       struct file_lock *fl = locks_alloc_lock();
+       int error = -ENOMEM;
 @@ -2075,16 +2075,16 @@ void locks_remove_flock(struct file *filp)
                return;
  
@@ -46233,7 +46521,7 @@ index 0d68f1f..f216b79 100644
  
        lock_flocks();
 diff --git a/fs/namei.c b/fs/namei.c
-index c427919..e37fd3f 100644
+index c427919..232326c 100644
 --- a/fs/namei.c
 +++ b/fs/namei.c
 @@ -278,16 +278,32 @@ int generic_permission(struct inode *inode, int mask)
@@ -46308,7 +46596,27 @@ index c427919..e37fd3f 100644
                error = 0;
                if (s)
                        error = __vfs_follow_link(nd, s);
-@@ -1753,6 +1769,21 @@ static int path_lookupat(int dfd, const char *name,
+@@ -1355,6 +1371,9 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd)
+               if (!res)
+                       res = walk_component(nd, path, &nd->last,
+                                            nd->last_type, LOOKUP_FOLLOW);
++              if (res >= 0 && gr_handle_symlink_owner(&link, nd->inode)) {
++                      res = -EACCES;
++              }
+               put_link(nd, &link, cookie);
+       } while (res > 0);
+@@ -1746,6 +1765,9 @@ static int path_lookupat(int dfd, const char *name,
+                       err = follow_link(&link, nd, &cookie);
+                       if (!err)
+                               err = lookup_last(nd, &path);
++                      if (!err && gr_handle_symlink_owner(&link, nd->inode)) {
++                              err = -EACCES;
++                      }
+                       put_link(nd, &link, cookie);
+               }
+       }
+@@ -1753,6 +1775,21 @@ static int path_lookupat(int dfd, const char *name,
        if (!err)
                err = complete_walk(nd);
  
@@ -46330,7 +46638,7 @@ index c427919..e37fd3f 100644
        if (!err && nd->flags & LOOKUP_DIRECTORY) {
                if (!nd->inode->i_op->lookup) {
                        path_put(&nd->path);
-@@ -1780,6 +1811,15 @@ static int do_path_lookup(int dfd, const char *name,
+@@ -1780,6 +1817,15 @@ static int do_path_lookup(int dfd, const char *name,
                retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, nd);
  
        if (likely(!retval)) {
@@ -46346,7 +46654,7 @@ index c427919..e37fd3f 100644
                if (unlikely(!audit_dummy_context())) {
                        if (nd->path.dentry && nd->inode)
                                audit_inode(name, nd->path.dentry);
-@@ -2126,6 +2166,13 @@ static int may_open(struct path *path, int acc_mode, int flag)
+@@ -2126,6 +2172,13 @@ static int may_open(struct path *path, int acc_mode, int flag)
        if (flag & O_NOATIME && !inode_owner_or_capable(inode))
                return -EPERM;
  
@@ -46360,7 +46668,7 @@ index c427919..e37fd3f 100644
        return 0;
  }
  
-@@ -2187,6 +2234,16 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
+@@ -2187,6 +2240,16 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                error = complete_walk(nd);
                if (error)
                        return ERR_PTR(error);
@@ -46377,7 +46685,7 @@ index c427919..e37fd3f 100644
                audit_inode(pathname, nd->path.dentry);
                if (open_flag & O_CREAT) {
                        error = -EISDIR;
-@@ -2197,6 +2254,16 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
+@@ -2197,6 +2260,16 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                error = complete_walk(nd);
                if (error)
                        return ERR_PTR(error);
@@ -46394,7 +46702,7 @@ index c427919..e37fd3f 100644
                audit_inode(pathname, dir);
                goto ok;
        }
-@@ -2218,6 +2285,16 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
+@@ -2218,6 +2291,16 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                error = complete_walk(nd);
                if (error)
                        return ERR_PTR(error);
@@ -46411,7 +46719,7 @@ index c427919..e37fd3f 100644
  
                error = -ENOTDIR;
                if (nd->flags & LOOKUP_DIRECTORY) {
-@@ -2258,6 +2335,12 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
+@@ -2258,6 +2341,12 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        /* Negative dentry, just create the file */
        if (!dentry->d_inode) {
                umode_t mode = op->mode;
@@ -46424,7 +46732,7 @@ index c427919..e37fd3f 100644
                if (!IS_POSIXACL(dir->d_inode))
                        mode &= ~current_umask();
                /*
-@@ -2281,6 +2364,8 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
+@@ -2281,6 +2370,8 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                error = vfs_create(dir->d_inode, dentry, mode, nd);
                if (error)
                        goto exit_mutex_unlock;
@@ -46433,7 +46741,7 @@ index c427919..e37fd3f 100644
                mutex_unlock(&dir->d_inode->i_mutex);
                dput(nd->path.dentry);
                nd->path.dentry = dentry;
-@@ -2290,6 +2375,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
+@@ -2290,6 +2381,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        /*
         * It already exists.
         */
@@ -46453,7 +46761,23 @@ index c427919..e37fd3f 100644
        mutex_unlock(&dir->d_inode->i_mutex);
        audit_inode(pathname, path->dentry);
  
-@@ -2502,6 +2600,11 @@ struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path
+@@ -2407,8 +2511,14 @@ static struct file *path_openat(int dfd, const char *pathname,
+               error = follow_link(&link, nd, &cookie);
+               if (unlikely(error))
+                       filp = ERR_PTR(error);
+-              else
++              else {
+                       filp = do_last(nd, &path, op, pathname);
++                      if (!IS_ERR(filp) && gr_handle_symlink_owner(&link, nd->inode)) {
++                              if (filp)
++                                      fput(filp);
++                              filp = ERR_PTR(-EACCES);
++                      }
++              }
+               put_link(nd, &link, cookie);
+       }
+ out:
+@@ -2502,6 +2612,11 @@ struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path
        *path = nd.path;
        return dentry;
  eexist:
@@ -46465,7 +46789,7 @@ index c427919..e37fd3f 100644
        dput(dentry);
        dentry = ERR_PTR(-EEXIST);
  fail:
-@@ -2524,6 +2627,20 @@ struct dentry *user_path_create(int dfd, const char __user *pathname, struct pat
+@@ -2524,6 +2639,20 @@ struct dentry *user_path_create(int dfd, const char __user *pathname, struct pat
  }
  EXPORT_SYMBOL(user_path_create);
  
@@ -46486,7 +46810,7 @@ index c427919..e37fd3f 100644
  int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
  {
        int error = may_create(dir, dentry);
-@@ -2591,6 +2708,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
+@@ -2591,6 +2720,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_dput;
@@ -46504,7 +46828,7 @@ index c427919..e37fd3f 100644
        error = security_path_mknod(&path, dentry, mode, dev);
        if (error)
                goto out_drop_write;
-@@ -2608,6 +2736,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
+@@ -2608,6 +2748,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
        }
  out_drop_write:
        mnt_drop_write(path.mnt);
@@ -46514,7 +46838,7 @@ index c427919..e37fd3f 100644
  out_dput:
        dput(dentry);
        mutex_unlock(&path.dentry->d_inode->i_mutex);
-@@ -2661,12 +2792,21 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
+@@ -2661,12 +2804,21 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_dput;
@@ -46536,7 +46860,7 @@ index c427919..e37fd3f 100644
  out_dput:
        dput(dentry);
        mutex_unlock(&path.dentry->d_inode->i_mutex);
-@@ -2746,6 +2886,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
+@@ -2746,6 +2898,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
        char * name;
        struct dentry *dentry;
        struct nameidata nd;
@@ -46545,7 +46869,7 @@ index c427919..e37fd3f 100644
  
        error = user_path_parent(dfd, pathname, &nd, &name);
        if (error)
-@@ -2774,6 +2916,15 @@ static long do_rmdir(int dfd, const char __user *pathname)
+@@ -2774,6 +2928,15 @@ static long do_rmdir(int dfd, const char __user *pathname)
                error = -ENOENT;
                goto exit3;
        }
@@ -46561,7 +46885,7 @@ index c427919..e37fd3f 100644
        error = mnt_want_write(nd.path.mnt);
        if (error)
                goto exit3;
-@@ -2781,6 +2932,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
+@@ -2781,6 +2944,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
        if (error)
                goto exit4;
        error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
@@ -46570,7 +46894,7 @@ index c427919..e37fd3f 100644
  exit4:
        mnt_drop_write(nd.path.mnt);
  exit3:
-@@ -2843,6 +2996,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
+@@ -2843,6 +3008,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
        struct dentry *dentry;
        struct nameidata nd;
        struct inode *inode = NULL;
@@ -46579,7 +46903,7 @@ index c427919..e37fd3f 100644
  
        error = user_path_parent(dfd, pathname, &nd, &name);
        if (error)
-@@ -2865,6 +3020,16 @@ static long do_unlinkat(int dfd, const char __user *pathname)
+@@ -2865,6 +3032,16 @@ static long do_unlinkat(int dfd, const char __user *pathname)
                if (!inode)
                        goto slashes;
                ihold(inode);
@@ -46596,7 +46920,7 @@ index c427919..e37fd3f 100644
                error = mnt_want_write(nd.path.mnt);
                if (error)
                        goto exit2;
-@@ -2872,6 +3037,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
+@@ -2872,6 +3049,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
                if (error)
                        goto exit3;
                error = vfs_unlink(nd.path.dentry->d_inode, dentry);
@@ -46605,7 +46929,7 @@ index c427919..e37fd3f 100644
  exit3:
                mnt_drop_write(nd.path.mnt);
        exit2:
-@@ -2947,10 +3114,18 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
+@@ -2947,10 +3126,18 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_dput;
@@ -46624,7 +46948,7 @@ index c427919..e37fd3f 100644
  out_drop_write:
        mnt_drop_write(path.mnt);
  out_dput:
-@@ -3025,6 +3200,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
+@@ -3025,6 +3212,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
  {
        struct dentry *new_dentry;
        struct path old_path, new_path;
@@ -46632,7 +46956,7 @@ index c427919..e37fd3f 100644
        int how = 0;
        int error;
  
-@@ -3048,7 +3224,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
+@@ -3048,7 +3236,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
        if (error)
                return error;
  
@@ -46641,7 +46965,7 @@ index c427919..e37fd3f 100644
        error = PTR_ERR(new_dentry);
        if (IS_ERR(new_dentry))
                goto out;
-@@ -3059,13 +3235,30 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
+@@ -3059,13 +3247,30 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
        error = mnt_want_write(new_path.mnt);
        if (error)
                goto out_dput;
@@ -46672,7 +46996,7 @@ index c427919..e37fd3f 100644
        dput(new_dentry);
        mutex_unlock(&new_path.dentry->d_inode->i_mutex);
        path_put(&new_path);
-@@ -3299,6 +3492,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
+@@ -3299,6 +3504,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
        if (new_dentry == trap)
                goto exit5;
  
@@ -46685,7 +47009,7 @@ index c427919..e37fd3f 100644
        error = mnt_want_write(oldnd.path.mnt);
        if (error)
                goto exit5;
-@@ -3308,6 +3507,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
+@@ -3308,6 +3519,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                goto exit6;
        error = vfs_rename(old_dir->d_inode, old_dentry,
                                   new_dir->d_inode, new_dentry);
@@ -46695,7 +47019,7 @@ index c427919..e37fd3f 100644
  exit6:
        mnt_drop_write(oldnd.path.mnt);
  exit5:
-@@ -3333,6 +3535,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna
+@@ -3333,6 +3547,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna
  
  int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
  {
@@ -46704,7 +47028,7 @@ index c427919..e37fd3f 100644
        int len;
  
        len = PTR_ERR(link);
-@@ -3342,7 +3546,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c
+@@ -3342,7 +3558,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c
        len = strlen(link);
        if (len > (unsigned) buflen)
                len = buflen;
@@ -47053,7 +47377,7 @@ index 5d22872..523db20 100644
                kfree(link);
  }
 diff --git a/fs/open.c b/fs/open.c
-index 5720854..ccfe124 100644
+index 3f1108b..822d7f7 100644
 --- a/fs/open.c
 +++ b/fs/open.c
 @@ -31,6 +31,8 @@
@@ -47478,7 +47802,7 @@ index f9bd395..acb7847 100644
 +}
 +#endif
 diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 9fc77b4..04761b8 100644
+index 9fc77b4..4877d08 100644
 --- a/fs/proc/base.c
 +++ b/fs/proc/base.c
 @@ -109,6 +109,14 @@ struct pid_entry {
@@ -47496,7 +47820,19 @@ index 9fc77b4..04761b8 100644
  #define NOD(NAME, MODE, IOP, FOP, OP) {                       \
        .name = (NAME),                                 \
        .len  = sizeof(NAME) - 1,                       \
-@@ -213,6 +221,9 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
+@@ -198,11 +206,6 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
+       return result;
+ }
+-struct mm_struct *mm_for_maps(struct task_struct *task)
+-{
+-      return mm_access(task, PTRACE_MODE_READ);
+-}
+-
+ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
+ {
+       int res = 0;
+@@ -213,6 +216,9 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
        if (!mm->arg_end)
                goto out_mm;    /* Shh! No looking before we're done */
  
@@ -47506,7 +47842,7 @@ index 9fc77b4..04761b8 100644
        len = mm->arg_end - mm->arg_start;
   
        if (len > PAGE_SIZE)
-@@ -240,12 +251,28 @@ out:
+@@ -240,12 +246,28 @@ out:
        return res;
  }
  
@@ -47518,7 +47854,8 @@ index 9fc77b4..04761b8 100644
 +
  static int proc_pid_auxv(struct task_struct *task, char *buffer)
  {
-       struct mm_struct *mm = mm_for_maps(task);
+-      struct mm_struct *mm = mm_for_maps(task);
++      struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ);
        int res = PTR_ERR(mm);
        if (mm && !IS_ERR(mm)) {
                unsigned int nwords = 0;
@@ -47535,7 +47872,7 @@ index 9fc77b4..04761b8 100644
                do {
                        nwords += 2;
                } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
-@@ -259,7 +286,7 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
+@@ -259,7 +281,7 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
  }
  
  
@@ -47544,7 +47881,7 @@ index 9fc77b4..04761b8 100644
  /*
   * Provides a wchan file via kallsyms in a proper one-value-per-file format.
   * Returns the resolved symbol.  If that fails, simply return the address.
-@@ -298,7 +325,7 @@ static void unlock_trace(struct task_struct *task)
+@@ -298,7 +320,7 @@ static void unlock_trace(struct task_struct *task)
        mutex_unlock(&task->signal->cred_guard_mutex);
  }
  
@@ -47553,7 +47890,7 @@ index 9fc77b4..04761b8 100644
  
  #define MAX_STACK_TRACE_DEPTH 64
  
-@@ -489,7 +516,7 @@ static int proc_pid_limits(struct task_struct *task, char *buffer)
+@@ -489,7 +511,7 @@ static int proc_pid_limits(struct task_struct *task, char *buffer)
        return count;
  }
  
@@ -47562,7 +47899,7 @@ index 9fc77b4..04761b8 100644
  static int proc_pid_syscall(struct task_struct *task, char *buffer)
  {
        long nr;
-@@ -518,7 +545,7 @@ static int proc_pid_syscall(struct task_struct *task, char *buffer)
+@@ -518,7 +540,7 @@ static int proc_pid_syscall(struct task_struct *task, char *buffer)
  /************************************************************************/
  
  /* permission checks */
@@ -47571,7 +47908,7 @@ index 9fc77b4..04761b8 100644
  {
        struct task_struct *task;
        int allowed = 0;
-@@ -528,7 +555,10 @@ static int proc_fd_access_allowed(struct inode *inode)
+@@ -528,7 +550,10 @@ static int proc_fd_access_allowed(struct inode *inode)
         */
        task = get_proc_task(inode);
        if (task) {
@@ -47583,7 +47920,7 @@ index 9fc77b4..04761b8 100644
                put_task_struct(task);
        }
        return allowed;
-@@ -566,10 +596,35 @@ static bool has_pid_permissions(struct pid_namespace *pid,
+@@ -566,10 +591,35 @@ static bool has_pid_permissions(struct pid_namespace *pid,
                                 struct task_struct *task,
                                 int hide_pid_min)
  {
@@ -47619,7 +47956,7 @@ index 9fc77b4..04761b8 100644
        return ptrace_may_access(task, PTRACE_MODE_READ);
  }
  
-@@ -587,7 +642,11 @@ static int proc_pid_permission(struct inode *inode, int mask)
+@@ -587,7 +637,11 @@ static int proc_pid_permission(struct inode *inode, int mask)
        put_task_struct(task);
  
        if (!has_perms) {
@@ -47631,18 +47968,57 @@ index 9fc77b4..04761b8 100644
                        /*
                         * Let's make getdents(), stat(), and open()
                         * consistent with each other.  If a process
-@@ -702,6 +761,10 @@ static int mem_open(struct inode* inode, struct file* file)
-       file->f_mode |= FMODE_UNSIGNED_OFFSET;
-       file->private_data = mm;
+@@ -677,7 +731,7 @@ static const struct file_operations proc_single_file_operations = {
+       .release        = single_release,
+ };
+-static int mem_open(struct inode* inode, struct file* file)
++static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
+ {
+       struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+       struct mm_struct *mm;
+@@ -685,7 +739,12 @@ static int mem_open(struct inode* inode, struct file* file)
+       if (!task)
+               return -ESRCH;
+-      mm = mm_access(task, PTRACE_MODE_ATTACH);
++      if (gr_acl_handle_procpidmem(task)) {
++              put_task_struct(task);
++              return -EPERM;
++      }
++
++      mm = mm_access(task, mode);
+       put_task_struct(task);
+       if (IS_ERR(mm))
+@@ -698,11 +757,24 @@ static int mem_open(struct inode* inode, struct file* file)
+               mmput(mm);
+       }
  
++      file->private_data = mm;
++
 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
 +      file->f_version = current->exec_id;
 +#endif
 +
-       return 0;
++      return 0;
++}
++
++static int mem_open(struct inode *inode, struct file *file)
++{
++      int ret;
++      ret = __mem_open(inode, file, PTRACE_MODE_ATTACH);
++
+       /* OK to pass negative loff_t, we can catch out-of-range */
+       file->f_mode |= FMODE_UNSIGNED_OFFSET;
+-      file->private_data = mm;
+-      return 0;
++      return ret;
  }
  
-@@ -713,6 +776,17 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
+ static ssize_t mem_rw(struct file *file, char __user *buf,
+@@ -713,6 +785,17 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
        ssize_t copied;
        char *page;
  
@@ -47660,17 +48036,101 @@ index 9fc77b4..04761b8 100644
        if (!mm)
                return 0;
  
-@@ -813,6 +887,9 @@ static ssize_t environ_read(struct file *file, char __user *buf,
-       if (!task)
              goto out_no_task;
+@@ -801,42 +884,49 @@ static const struct file_operations proc_mem_operations = {
+       .release        = mem_release,
};
  
-+      if (gr_acl_handle_procpidmem(task))
-+              goto out;
++static int environ_open(struct inode *inode, struct file *file)
++{
++      return __mem_open(inode, file, PTRACE_MODE_READ);
++}
 +
-       ret = -ENOMEM;
+ static ssize_t environ_read(struct file *file, char __user *buf,
+                       size_t count, loff_t *ppos)
+ {
+-      struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
+       char *page;
+       unsigned long src = *ppos;
+-      int ret = -ESRCH;
+-      struct mm_struct *mm;
++      int ret = 0;
++      struct mm_struct *mm = file->private_data;
+-      if (!task)
+-              goto out_no_task;
++      if (!mm)
++              return 0;
++
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++      if (file->f_version != current->exec_id) {
++              gr_log_badprocpid("environ");
++              return 0;
++      }
++#endif
+-      ret = -ENOMEM;
        page = (char *)__get_free_page(GFP_TEMPORARY);
        if (!page)
-@@ -1433,7 +1510,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+-              goto out;
+-
+-
+-      mm = mm_for_maps(task);
+-      ret = PTR_ERR(mm);
+-      if (!mm || IS_ERR(mm))
+-              goto out_free;
++              return -ENOMEM;
+       ret = 0;
++      if (!atomic_inc_not_zero(&mm->mm_users))
++              goto free;
+       while (count > 0) {
+-              int this_len, retval, max_len;
++              size_t this_len, max_len;
++              int retval;
++
++              if (src >= (mm->env_end - mm->env_start))
++                      break;
+               this_len = mm->env_end - (mm->env_start + src);
+-              if (this_len <= 0)
+-                      break;
++              max_len = min_t(size_t, PAGE_SIZE, count);
++              this_len = min(max_len, this_len);
+-              max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+-              this_len = (this_len > max_len) ? max_len : this_len;
+-
+-              retval = access_process_vm(task, (mm->env_start + src),
++              retval = access_remote_vm(mm, (mm->env_start + src),
+                       page, this_len, 0);
+               if (retval <= 0) {
+@@ -855,19 +945,18 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+               count -= retval;
+       }
+       *ppos = src;
+-
+       mmput(mm);
+-out_free:
++
++free:
+       free_page((unsigned long) page);
+-out:
+-      put_task_struct(task);
+-out_no_task:
+       return ret;
+ }
+ static const struct file_operations proc_environ_operations = {
++      .open           = environ_open,
+       .read           = environ_read,
+       .llseek         = generic_file_llseek,
++      .release        = mem_release,
+ };
+ static ssize_t oom_adjust_read(struct file *file, char __user *buf,
+@@ -1433,7 +1522,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? */
@@ -47679,7 +48139,7 @@ index 9fc77b4..04761b8 100644
                goto out;
  
        error = PROC_I(inode)->op.proc_get_link(dentry, &nd->path);
-@@ -1472,8 +1549,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
+@@ -1472,8 +1561,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? */
@@ -47700,7 +48160,7 @@ index 9fc77b4..04761b8 100644
  
        error = PROC_I(inode)->op.proc_get_link(dentry, &path);
        if (error)
-@@ -1538,7 +1625,11 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t
+@@ -1538,7 +1637,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;
@@ -47712,7 +48172,7 @@ index 9fc77b4..04761b8 100644
                rcu_read_unlock();
        }
        security_task_to_inode(task, inode);
-@@ -1574,10 +1665,19 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+@@ -1574,10 +1677,19 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
                        return -ENOENT;
                }
                if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
@@ -47732,7 +48192,7 @@ index 9fc77b4..04761b8 100644
                }
        }
        rcu_read_unlock();
-@@ -1615,11 +1715,20 @@ int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
+@@ -1615,11 +1727,20 @@ int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
  
        if (task) {
                if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
@@ -47753,7 +48213,7 @@ index 9fc77b4..04761b8 100644
                        rcu_read_unlock();
                } else {
                        inode->i_uid = 0;
-@@ -1737,7 +1846,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
+@@ -1737,7 +1858,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
        int fd = proc_fd(inode);
  
        if (task) {
@@ -47763,7 +48223,21 @@ index 9fc77b4..04761b8 100644
                put_task_struct(task);
        }
        if (files) {
-@@ -2338,11 +2448,21 @@ static const struct file_operations proc_map_files_operations = {
+@@ -2025,11 +2147,8 @@ static int map_files_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+       if (!task)
+               goto out_notask;
+-      if (!ptrace_may_access(task, PTRACE_MODE_READ))
+-              goto out;
+-
+-      mm = get_task_mm(task);
+-      if (!mm)
++      mm = mm_access(task, PTRACE_MODE_READ);
++      if (IS_ERR_OR_NULL(mm))
+               goto out;
+       if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {
+@@ -2338,11 +2457,21 @@ static const struct file_operations proc_map_files_operations = {
   */
  static int proc_fd_permission(struct inode *inode, int mask)
  {
@@ -47787,7 +48261,7 @@ index 9fc77b4..04761b8 100644
        return rv;
  }
  
-@@ -2452,6 +2572,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
+@@ -2452,6 +2581,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
        if (!task)
                goto out_no_task;
  
@@ -47797,7 +48271,7 @@ index 9fc77b4..04761b8 100644
        /*
         * Yes, it does not scale. And it should not. Don't add
         * new entries into /proc/<tgid>/ without very good reasons.
-@@ -2496,6 +2619,9 @@ static int proc_pident_readdir(struct file *filp,
+@@ -2496,6 +2628,9 @@ static int proc_pident_readdir(struct file *filp,
        if (!task)
                goto out_no_task;
  
@@ -47807,7 +48281,7 @@ index 9fc77b4..04761b8 100644
        ret = 0;
        i = filp->f_pos;
        switch (i) {
-@@ -2766,7 +2892,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+@@ -2766,7 +2901,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)
  {
@@ -47816,7 +48290,7 @@ index 9fc77b4..04761b8 100644
        if (!IS_ERR(s))
                __putname(s);
  }
-@@ -2967,7 +3093,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2967,7 +3102,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),
@@ -47825,7 +48299,7 @@ index 9fc77b4..04761b8 100644
        INF("syscall",    S_IRUGO, proc_pid_syscall),
  #endif
        INF("cmdline",    S_IRUGO, proc_pid_cmdline),
-@@ -2992,10 +3118,10 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2992,10 +3127,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
@@ -47838,7 +48312,7 @@ index 9fc77b4..04761b8 100644
        ONE("stack",      S_IRUGO, proc_pid_stack),
  #endif
  #ifdef CONFIG_SCHEDSTATS
-@@ -3029,6 +3155,9 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -3029,6 +3164,9 @@ static const struct pid_entry tgid_base_stuff[] = {
  #ifdef CONFIG_HARDWALL
        INF("hardwall",   S_IRUGO, proc_pid_hardwall),
  #endif
@@ -47848,7 +48322,7 @@ index 9fc77b4..04761b8 100644
  };
  
  static int proc_tgid_base_readdir(struct file * filp,
-@@ -3155,7 +3284,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
+@@ -3155,7 +3293,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
        if (!inode)
                goto out;
  
@@ -47863,7 +48337,7 @@ index 9fc77b4..04761b8 100644
        inode->i_op = &proc_tgid_base_inode_operations;
        inode->i_fop = &proc_tgid_base_operations;
        inode->i_flags|=S_IMMUTABLE;
-@@ -3197,7 +3333,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
+@@ -3197,7 +3342,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
        if (!task)
                goto out;
  
@@ -47875,7 +48349,7 @@ index 9fc77b4..04761b8 100644
        put_task_struct(task);
  out:
        return result;
-@@ -3260,6 +3400,8 @@ static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldi
+@@ -3260,6 +3409,8 @@ static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldi
  static int fake_filldir(void *buf, const char *name, int namelen,
                        loff_t offset, u64 ino, unsigned d_type)
  {
@@ -47884,7 +48358,7 @@ index 9fc77b4..04761b8 100644
        return 0;
  }
  
-@@ -3326,7 +3468,7 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3326,7 +3477,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),
@@ -47893,7 +48367,7 @@ index 9fc77b4..04761b8 100644
        INF("syscall",   S_IRUGO, proc_pid_syscall),
  #endif
        INF("cmdline",   S_IRUGO, proc_pid_cmdline),
-@@ -3350,10 +3492,10 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3350,10 +3501,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
@@ -47987,10 +48461,19 @@ index 205c922..2ee4c57 100644
                if (de->size)
                        inode->i_size = de->size;
 diff --git a/fs/proc/internal.h b/fs/proc/internal.h
-index 5f79bb8..eeccee4 100644
+index 5f79bb8..e9ab85d 100644
 --- a/fs/proc/internal.h
 +++ b/fs/proc/internal.h
-@@ -54,6 +54,9 @@ extern int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
+@@ -31,8 +31,6 @@ struct vmalloc_info {
+       unsigned long   largest_chunk;
+ };
+-extern struct mm_struct *mm_for_maps(struct task_struct *);
+-
+ #ifdef CONFIG_MMU
+ #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
+ extern void get_vmalloc_info(struct vmalloc_info *vmi);
+@@ -54,6 +52,9 @@ extern int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
                                struct pid *pid, struct task_struct *task);
  extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
                                struct pid *pid, struct task_struct *task);
@@ -48259,7 +48742,7 @@ index eed44bf..abeb499 100644
  }
  
 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index 7faaf2a..096c28b 100644
+index 7faaf2a..7793015 100644
 --- a/fs/proc/task_mmu.c
 +++ b/fs/proc/task_mmu.c
 @@ -11,12 +11,19 @@
@@ -48319,6 +48802,15 @@ index 7faaf2a..096c28b 100644
  }
  
  unsigned long task_vsize(struct mm_struct *mm)
+@@ -125,7 +149,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
+       if (!priv->task)
+               return ERR_PTR(-ESRCH);
+-      mm = mm_for_maps(priv->task);
++      mm = mm_access(priv->task, PTRACE_MODE_READ);
+       if (!mm || IS_ERR(mm))
+               return mm;
+       down_read(&mm->mmap_sem);
 @@ -231,13 +255,13 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
                pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
        }
@@ -48426,6 +48918,15 @@ index 7faaf2a..096c28b 100644
                   mss.resident >> 10,
                   (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
                   mss.shared_clean  >> 10,
+@@ -919,7 +970,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
+       if (!pm.buffer)
+               goto out_task;
+-      mm = mm_for_maps(task);
++      mm = mm_access(task, PTRACE_MODE_READ);
+       ret = PTR_ERR(mm);
+       if (!mm || IS_ERR(mm))
+               goto out_free;
 @@ -1138,6 +1189,13 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
        int n;
        char buffer[50];
@@ -48458,7 +48959,7 @@ index 7faaf2a..096c28b 100644
                seq_printf(m, " heap");
        } else {
 diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
-index 74fe164..899e77b 100644
+index 74fe164..0848f95 100644
 --- a/fs/proc/task_nommu.c
 +++ b/fs/proc/task_nommu.c
 @@ -51,7 +51,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
@@ -48479,6 +48980,15 @@ index 74fe164..899e77b 100644
        } else if (mm) {
                pid_t tid = vm_is_stack(priv->task, vma, is_pid);
  
+@@ -223,7 +223,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
+       if (!priv->task)
+               return ERR_PTR(-ESRCH);
+-      mm = mm_for_maps(priv->task);
++      mm = mm_access(priv->task, PTRACE_MODE_READ);
+       if (!mm || IS_ERR(mm)) {
+               put_task_struct(priv->task);
+               priv->task = NULL;
 diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
 index d67908b..d13f6a6 100644
 --- a/fs/quota/netlink.c
@@ -48672,7 +49182,7 @@ index 17d33d0..da0bf5c 100644
                return -EINVAL;
  
 diff --git a/fs/seq_file.c b/fs/seq_file.c
-index 0cbd049..cab1127 100644
+index 0cbd049..64e705c 100644
 --- a/fs/seq_file.c
 +++ b/fs/seq_file.c
 @@ -9,6 +9,7 @@
@@ -48693,6 +49203,42 @@ index 0cbd049..cab1127 100644
  
        /*
         * Wrappers around seq_open(e.g. swaps_open) need to be
+@@ -92,7 +96,7 @@ static int traverse(struct seq_file *m, loff_t offset)
+               return 0;
+       }
+       if (!m->buf) {
+-              m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
++              m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL | GFP_USERCOPY);
+               if (!m->buf)
+                       return -ENOMEM;
+       }
+@@ -132,7 +136,7 @@ static int traverse(struct seq_file *m, loff_t offset)
+ Eoverflow:
+       m->op->stop(m, p);
+       kfree(m->buf);
+-      m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
++      m->buf = kmalloc(m->size <<= 1, GFP_KERNEL | GFP_USERCOPY);
+       return !m->buf ? -ENOMEM : -EAGAIN;
+ }
+@@ -187,7 +191,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+       /* grab buffer if we didn't have one */
+       if (!m->buf) {
+-              m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
++              m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL | GFP_USERCOPY);
+               if (!m->buf)
+                       goto Enomem;
+       }
+@@ -228,7 +232,7 @@ 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);
+-              m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
++              m->buf = kmalloc(m->size <<= 1, GFP_KERNEL | GFP_USERCOPY);
+               if (!m->buf)
+                       goto Enomem;
+               m->count = 0;
 @@ -567,7 +571,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)
@@ -48703,7 +49249,7 @@ index 0cbd049..cab1127 100644
  
        if (op) {
 diff --git a/fs/splice.c b/fs/splice.c
-index f847684..156619e 100644
+index 5cac690..f833a99 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
 @@ -194,7 +194,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
@@ -48727,7 +49273,7 @@ index f847684..156619e 100644
        }
  
        pipe_unlock(pipe);
-@@ -560,7 +560,7 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
+@@ -563,7 +563,7 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
        old_fs = get_fs();
        set_fs(get_ds());
        /* The cast to a user pointer is valid due to the set_fs() */
@@ -48736,7 +49282,7 @@ index f847684..156619e 100644
        set_fs(old_fs);
  
        return res;
-@@ -575,7 +575,7 @@ static ssize_t kernel_write(struct file *file, const char *buf, size_t count,
+@@ -578,7 +578,7 @@ static ssize_t kernel_write(struct file *file, const char *buf, size_t count,
        old_fs = get_fs();
        set_fs(get_ds());
        /* The cast to a user pointer is valid due to the set_fs() */
@@ -48745,7 +49291,7 @@ index f847684..156619e 100644
        set_fs(old_fs);
  
        return res;
-@@ -626,7 +626,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
+@@ -630,7 +630,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
                        goto err;
  
                this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset);
@@ -48754,7 +49300,7 @@ index f847684..156619e 100644
                vec[i].iov_len = this_len;
                spd.pages[i] = page;
                spd.nr_pages++;
-@@ -845,10 +845,10 @@ EXPORT_SYMBOL(splice_from_pipe_feed);
+@@ -849,10 +849,10 @@ EXPORT_SYMBOL(splice_from_pipe_feed);
  int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
  {
        while (!pipe->nrbufs) {
@@ -48767,7 +49313,7 @@ index f847684..156619e 100644
                        return 0;
  
                if (sd->flags & SPLICE_F_NONBLOCK)
-@@ -1181,7 +1181,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+@@ -1185,7 +1185,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
                 * out of the pipe right after the splice_to_pipe(). So set
                 * PIPE_READERS appropriately.
                 */
@@ -48776,7 +49322,7 @@ index f847684..156619e 100644
  
                current->splice_pipe = pipe;
        }
-@@ -1733,9 +1733,9 @@ static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
+@@ -1738,9 +1738,9 @@ static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
                        ret = -ERESTARTSYS;
                        break;
                }
@@ -48788,7 +49334,7 @@ index f847684..156619e 100644
                        if (flags & SPLICE_F_NONBLOCK) {
                                ret = -EAGAIN;
                                break;
-@@ -1767,7 +1767,7 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
+@@ -1772,7 +1772,7 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
        pipe_lock(pipe);
  
        while (pipe->nrbufs >= pipe->buffers) {
@@ -48797,7 +49343,7 @@ index f847684..156619e 100644
                        send_sig(SIGPIPE, current, 0);
                        ret = -EPIPE;
                        break;
-@@ -1780,9 +1780,9 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
+@@ -1785,9 +1785,9 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
                        ret = -ERESTARTSYS;
                        break;
                }
@@ -48809,7 +49355,7 @@ index f847684..156619e 100644
        }
  
        pipe_unlock(pipe);
-@@ -1818,14 +1818,14 @@ retry:
+@@ -1823,14 +1823,14 @@ retry:
        pipe_double_lock(ipipe, opipe);
  
        do {
@@ -48826,7 +49372,7 @@ index f847684..156619e 100644
                        break;
  
                /*
-@@ -1922,7 +1922,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
+@@ -1927,7 +1927,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
        pipe_double_lock(ipipe, opipe);
  
        do {
@@ -48835,7 +49381,7 @@ index f847684..156619e 100644
                        send_sig(SIGPIPE, current, 0);
                        if (!ret)
                                ret = -EPIPE;
-@@ -1967,7 +1967,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
+@@ -1972,7 +1972,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
         * return EAGAIN if we have the potential of some data in the
         * future, otherwise just return 0
         */
@@ -49109,10 +49655,10 @@ index 3011b87..1ab03e9 100644
                kfree(s);
 diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
 new file mode 100644
-index 0000000..2d6e3a8
+index 0000000..4d533f1
 --- /dev/null
 +++ b/grsecurity/Kconfig
-@@ -0,0 +1,915 @@
+@@ -0,0 +1,941 @@
 +#
 +# grecurity configuration
 +#
@@ -49241,6 +49787,7 @@ index 0000000..2d6e3a8
 +config GRKERNSEC_HIDESYM
 +      bool "Hide kernel symbols"
 +      default y if GRKERNSEC_CONFIG_AUTO
++      select PAX_USERCOPY_SLABS
 +      help
 +        If you say Y here, getting information on loaded modules, and
 +        displaying all kernel symbols through a syscall will be restricted
@@ -49386,6 +49933,31 @@ index 0000000..2d6e3a8
 +        able to hardlink to files they do not own.  If the sysctl option is
 +        enabled, a sysctl option with name "linking_restrictions" is created.
 +
++config GRKERNSEC_SYMLINKOWN
++      bool "Kernel-enforced SymlinksIfOwnerMatch"
++      default y if GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_SERVER
++      help
++        Apache's SymlinksIfOwnerMatch option has an inherent race condition
++        that prevents it from being used as a security feature.  As Apache
++        verifies the symlink by performing a stat() against the target of
++        the symlink before it is followed, an attacker can setup a symlink
++        to point to a same-owned file, then replace the symlink with one
++        that targets another user's file just after Apache "validates" the
++        symlink -- a classic TOCTOU race.  If you say Y here, a complete,
++        race-free replacement for Apache's "SymlinksIfOwnerMatch" option
++        will be in place for the group you specify. If the sysctl option
++        is enabled, a sysctl option with name "enforce_symlinksifowner" is
++        created.
++
++config GRKERNSEC_SYMLINKOWN_GID
++      int "GID for users with kernel-enforced SymlinksIfOwnerMatch"
++      depends on GRKERNSEC_SYMLINKOWN
++      default 1006
++      help
++        Setting this GID determines what group kernel-enforced
++        SymlinksIfOwnerMatch will be enabled for.  If the sysctl option
++        is enabled, a sysctl option with name "symlinkown_gid" is created.
++
 +config GRKERNSEC_FIFO
 +      bool "FIFO restrictions"
 +      default y if GRKERNSEC_CONFIG_AUTO
@@ -49789,7 +50361,7 @@ index 0000000..2d6e3a8
 +
 +config GRKERNSEC_TPE
 +      bool "Trusted Path Execution (TPE)"
-+      default y if GRKERNSEC_CONFIG_AUTO
++      default y if GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_SERVER
 +      help
 +        If you say Y here, you will be able to choose a gid to add to the
 +        supplementary groups of users you want to mark as "untrusted."
@@ -50074,10 +50646,10 @@ index 0000000..1b9afa9
 +endif
 diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
 new file mode 100644
-index 0000000..00b6c54
+index 0000000..7a5922f
 --- /dev/null
 +++ b/grsecurity/gracl.c
-@@ -0,0 +1,4012 @@
+@@ -0,0 +1,4016 @@
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/sched.h>
@@ -50100,6 +50672,7 @@ index 0000000..00b6c54
 +#include <linux/security.h>
 +#include <linux/grinternal.h>
 +#include <linux/pid_namespace.h>
++#include <linux/stop_machine.h>
 +#include <linux/fdtable.h>
 +#include <linux/percpu.h>
 +#include "../fs/mount.h"
@@ -52350,18 +52923,17 @@ index 0000000..00b6c54
 +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;
@@ -53170,6 +53742,15 @@ index 0000000..00b6c54
 +      return 1;
 +}
 +
++static int gr_rbac_disable(void *unused)
++{
++      pax_open_kernel();
++      gr_status &= ~GR_READY;
++      pax_close_kernel();
++
++      return 0;
++}
++
 +ssize_t
 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
 +{
@@ -53254,15 +53835,12 @@ index 0000000..00b6c54
 +      case GR_SHUTDOWN:
 +              if ((gr_status & GR_READY)
 +                  && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
-+                      pax_open_kernel();
-+                      gr_status &= ~GR_READY;
-+                      pax_close_kernel();
-+
-+                      gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
++                      stop_machine(gr_rbac_disable, NULL, NULL);
 +                      free_variables();
 +                      memset(gr_usermode, 0, sizeof (struct gr_arg));
 +                      memset(gr_system_salt, 0, GR_SALT_LEN);
 +                      memset(gr_system_sum, 0, GR_SHA_LEN);
++                      gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
 +              } else if (gr_status & GR_READY) {
 +                      gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
 +                      error = -EPERM;
@@ -53287,20 +53865,14 @@ index 0000000..00b6c54
 +                      gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
 +                      error = -EAGAIN;
 +              } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
-+                      preempt_disable();
-+
-+                      pax_open_kernel();
-+                      gr_status &= ~GR_READY;
-+                      pax_close_kernel();
-+
++                      stop_machine(gr_rbac_disable, NULL, NULL);
 +                      free_variables();
-+                      if (!(error2 = gracl_init(gr_usermode))) {
-+                              preempt_enable();
++                      error2 = gracl_init(gr_usermode);
++                      if (!error2)
 +                              gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
-+                      } else {
-+                              preempt_enable();
-+                              error = error2;
++                      else {
 +                              gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
++                              error = error2;
 +                      }
 +              } else {
 +                      gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
@@ -54032,11 +54604,15 @@ index 0000000..00b6c54
 +              return 1;
 +
 +      subj = task->acl;
++      read_lock(&gr_inode_lock);
 +      do {
 +              obj = lookup_acl_obj_label(ino, dev, subj);
-+              if (obj != NULL)
++              if (obj != NULL) {
++                      read_unlock(&gr_inode_lock);
 +                      return (obj->mode & GR_FIND) ? 1 : 0;
++              }
 +      } while ((subj = subj->parent_subject));
++      read_unlock(&gr_inode_lock);
 +      
 +      /* this is purely an optimization since we're looking for an object
 +         for the directory we're doing a readdir on
@@ -56869,10 +57445,10 @@ index 0000000..8ca18bf
 +}
 diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c
 new file mode 100644
-index 0000000..01ddde4
+index 0000000..05a6015
 --- /dev/null
 +++ b/grsecurity/grsec_init.c
-@@ -0,0 +1,277 @@
+@@ -0,0 +1,283 @@
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
 +#include <linux/mm.h>
@@ -56884,6 +57460,8 @@ index 0000000..01ddde4
 +
 +int grsec_enable_ptrace_readexec;
 +int grsec_enable_setxid;
++int grsec_enable_symlinkown;
++int grsec_symlinkown_gid;
 +int grsec_enable_brute;
 +int grsec_enable_link;
 +int grsec_enable_dmesg;
@@ -57127,6 +57705,10 @@ index 0000000..01ddde4
 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
 +      grsec_enable_chroot_sysctl = 1;
 +#endif
++#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
++      grsec_enable_symlinkown = 1;
++      grsec_symlinkown_gid = CONFIG_GRKERNSEC_SYMLINKOWN_GID;
++#endif
 +#ifdef CONFIG_GRKERNSEC_TPE
 +      grsec_enable_tpe = 1;
 +      grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
@@ -57152,16 +57734,32 @@ index 0000000..01ddde4
 +}
 diff --git a/grsecurity/grsec_link.c b/grsecurity/grsec_link.c
 new file mode 100644
-index 0000000..3efe141
+index 0000000..35a96d1
 --- /dev/null
 +++ b/grsecurity/grsec_link.c
-@@ -0,0 +1,43 @@
+@@ -0,0 +1,59 @@
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
 +#include <linux/fs.h>
 +#include <linux/file.h>
 +#include <linux/grinternal.h>
 +
++int gr_handle_symlink_owner(const struct path *link, const struct inode *target)
++{
++#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
++      const struct inode *link_inode = link->dentry->d_inode;
++
++      if (grsec_enable_symlinkown && in_group_p(grsec_symlinkown_gid) &&
++         /* ignore root-owned links, e.g. /proc/self */
++          link_inode->i_uid &&
++          link_inode->i_uid != target->i_uid) {
++              gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINKOWNER_MSG, link->dentry, link->mnt, link_inode->i_uid, target->i_uid);
++              return 1;
++      }
++#endif
++      return 0;
++}
++
 +int
 +gr_handle_follow_link(const struct inode *parent,
 +                    const struct inode *inode,
@@ -58184,10 +58782,10 @@ index 0000000..4030d57
 +}
 diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c
 new file mode 100644
-index 0000000..8316f6f
+index 0000000..f55ef0f
 --- /dev/null
 +++ b/grsecurity/grsec_sysctl.c
-@@ -0,0 +1,453 @@
+@@ -0,0 +1,469 @@
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
 +#include <linux/sysctl.h>
@@ -58235,6 +58833,22 @@ index 0000000..8316f6f
 +              .proc_handler   = &proc_dointvec,
 +      },
 +#endif
++#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
++      {
++              .procname       = "enforce_symlinksifowner",
++              .data           = &grsec_enable_symlinkown,
++              .maxlen         = sizeof(int),
++              .mode           = 0600,
++              .proc_handler   = &proc_dointvec,
++      },
++      {
++              .procname       = "symlinkown_gid",
++              .data           = &grsec_symlinkown_gid,
++              .maxlen         = sizeof(int),
++              .mode           = 0600,
++              .proc_handler   = &proc_dointvec,
++      },
++#endif
 +#ifdef CONFIG_GRKERNSEC_BRUTE
 +      {
 +              .procname       = "deter_bruteforce",
@@ -58823,7 +59437,7 @@ index f1c8ca6..b5c1cc7 100644
  #define ACPI_DRIVER_ALL_NOTIFY_EVENTS 0x1     /* system AND device events */
  
 diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h
-index b7babf0..71e4e74 100644
+index b7babf0..3ba8aee 100644
 --- a/include/asm-generic/atomic-long.h
 +++ b/include/asm-generic/atomic-long.h
 @@ -22,6 +22,12 @@
@@ -59076,7 +59690,7 @@ index b7babf0..71e4e74 100644
  static inline long atomic_long_dec_return(atomic_long_t *l)
  {
        atomic_t *v = (atomic_t *)l;
-@@ -255,4 +393,49 @@ static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
+@@ -255,4 +393,55 @@ static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
  
  #endif  /*  BITS_PER_LONG == 64  */
  
@@ -59094,6 +59708,10 @@ index b7babf0..71e4e74 100644
 +      atomic_dec_unchecked((atomic_unchecked_t *)NULL);
 +      atomic_cmpxchg_unchecked((atomic_unchecked_t *)NULL, 0, 0);
 +      (void)atomic_xchg_unchecked((atomic_unchecked_t *)NULL, 0);
++#ifdef CONFIG_X86
++      atomic_clear_mask_unchecked(0, NULL);
++      atomic_set_mask_unchecked(0, NULL);
++#endif
 +
 +      atomic_long_read_unchecked((atomic_long_unchecked_t *)NULL);
 +      atomic_long_set_unchecked((atomic_long_unchecked_t *)NULL, 0);
@@ -59115,6 +59733,8 @@ index b7babf0..71e4e74 100644
 +#define atomic_dec_unchecked(v) atomic_dec(v)
 +#define atomic_cmpxchg_unchecked(v, o, n) atomic_cmpxchg((v), (o), (n))
 +#define atomic_xchg_unchecked(v, i) atomic_xchg((v), (i))
++#define atomic_clear_mask_unchecked(mask, v) atomic_clear_mask((mask), (v))
++#define atomic_set_mask_unchecked(mask, v) atomic_set_mask((mask), (v))
 +
 +#define atomic_long_read_unchecked(v) atomic_long_read(v)
 +#define atomic_long_set_unchecked(v, i) atomic_long_set((v), (i))
@@ -59126,6 +59746,19 @@ index b7babf0..71e4e74 100644
 +#endif
 +
  #endif  /*  _ASM_GENERIC_ATOMIC_LONG_H  */
+diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
+index 1ced641..c896ee8 100644
+--- a/include/asm-generic/atomic.h
++++ b/include/asm-generic/atomic.h
+@@ -159,7 +159,7 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+  * Atomically clears the bits set in @mask from @v
+  */
+ #ifndef atomic_clear_mask
+-static inline void atomic_clear_mask(unsigned long mask, atomic_t *v)
++static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
+ {
+       unsigned long flags;
 diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h
 index b18ce4f..2ee2843 100644
 --- a/include/asm-generic/atomic64.h
@@ -59293,49 +59926,10 @@ index 810431d..0ec4804f 100644
   * (puds are folded into pgds so this doesn't get actually called,
   * but the define is needed for a generic inline function.)
 diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
-index 125c54e..e95c18e 100644
+index c7ec2cd..909d125 100644
 --- a/include/asm-generic/pgtable.h
 +++ b/include/asm-generic/pgtable.h
-@@ -446,6 +446,18 @@ static inline int pmd_write(pmd_t pmd)
- #endif /* __HAVE_ARCH_PMD_WRITE */
- #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-+#ifndef  __HAVE_ARCH_READ_PMD_ATOMIC
-+static inline pmd_t read_pmd_atomic(pmd_t *pmdp)
-+{
-+      /*
-+       * Depend on compiler for an atomic pmd read. NOTE: this is
-+       * only going to work, if the pmdval_t isn't larger than
-+       * an unsigned long.
-+       */
-+      return *pmdp;
-+}
-+#endif /* __HAVE_ARCH_READ_PMD_ATOMIC */
-+
- /*
-  * This function is meant to be used by sites walking pagetables with
-  * the mmap_sem hold in read mode to protect against MADV_DONTNEED and
-@@ -459,11 +471,17 @@ static inline int pmd_write(pmd_t pmd)
-  * undefined so behaving like if the pmd was none is safe (because it
-  * can return none anyway). The compiler level barrier() is critically
-  * important to compute the two checks atomically on the same pmdval.
-+ *
-+ * For 32bit kernels with a 64bit large pmd_t this automatically takes
-+ * care of reading the pmd atomically to avoid SMP race conditions
-+ * against pmd_populate() when the mmap_sem is hold for reading by the
-+ * caller (a special atomic read not done by "gcc" as in the generic
-+ * version above, is also needed when THP is disabled because the page
-+ * fault can populate the pmd from under us).
-  */
- static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
- {
--      /* depend on compiler for an atomic pmd read */
--      pmd_t pmdval = *pmd;
-+      pmd_t pmdval = read_pmd_atomic(pmd);
-       /*
-        * The barrier will stabilize the pmdval in a register or on
-        * the stack so that it will stop changing under the code.
-@@ -503,6 +521,14 @@ static inline int pmd_trans_unstable(pmd_t *pmd)
+@@ -531,6 +531,14 @@ static inline int pmd_trans_unstable(pmd_t *pmd)
  #endif
  }
  
@@ -59630,10 +60224,10 @@ index 42e55de..1cd0e66 100644
  extern struct cleancache_ops
        cleancache_register_ops(struct cleancache_ops *ops);
 diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
-index 2f40791..a62d196 100644
+index 2f40791..9c9e13c 100644
 --- a/include/linux/compiler-gcc4.h
 +++ b/include/linux/compiler-gcc4.h
-@@ -32,6 +32,16 @@
+@@ -32,6 +32,20 @@
  #define __linktime_error(message) __attribute__((__error__(message)))
  
  #if __GNUC_MINOR__ >= 5
@@ -59646,11 +60240,15 @@ index 2f40791..a62d196 100644
 +#ifdef SIZE_OVERFLOW_PLUGIN
 +#define __size_overflow(...) __attribute__((size_overflow(__VA_ARGS__)))
 +#endif
++
++#ifdef LATENT_ENTROPY_PLUGIN
++#define __latent_entropy __attribute__((latent_entropy))
++#endif
 +
  /*
   * Mark a position in code as unreachable.  This can be used to
   * suppress control flow warnings after asm blocks that transfer
-@@ -47,6 +57,11 @@
+@@ -47,6 +61,11 @@
  #define __noclone     __attribute__((__noclone__))
  
  #endif
@@ -59663,7 +60261,7 @@ index 2f40791..a62d196 100644
  
  #if __GNUC_MINOR__ > 0
 diff --git a/include/linux/compiler.h b/include/linux/compiler.h
-index 923d093..726c17f 100644
+index 923d093..1fef491 100644
 --- a/include/linux/compiler.h
 +++ b/include/linux/compiler.h
 @@ -5,31 +5,62 @@
@@ -59739,7 +60337,7 @@ index 923d093..726c17f 100644
  #endif
  
  #ifdef __KERNEL__
-@@ -264,6 +297,18 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+@@ -264,6 +297,22 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
  # define __attribute_const__  /* unimplemented */
  #endif
  
@@ -59754,11 +60352,15 @@ index 923d093..726c17f 100644
 +#ifndef __size_overflow
 +# define __size_overflow(...)
 +#endif
++
++#ifndef __latent_entropy
++# define __latent_entropy
++#endif
 +
  /*
   * Tell gcc if a function is cold. The compiler will assume any path
   * directly leading to the call is unlikely.
-@@ -273,6 +318,22 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+@@ -273,6 +322,22 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
  #define __cold
  #endif
  
@@ -59781,7 +60383,7 @@ index 923d093..726c17f 100644
  /* Simple shorthand for a section definition */
  #ifndef __section
  # define __section(S) __attribute__ ((__section__(#S)))
-@@ -308,6 +369,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+@@ -308,6 +373,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
   * use is to mediate communication between process-level code and irq/NMI
   * handlers, all running on the same CPU.
   */
@@ -60092,6 +60694,49 @@ index 017a7fb..33a8507 100644
        struct disk_events *ev;
  #ifdef  CONFIG_BLK_DEV_INTEGRITY
        struct blk_integrity *integrity;
+diff --git a/include/linux/gfp.h b/include/linux/gfp.h
+index 581e74b..8c34a24 100644
+--- a/include/linux/gfp.h
++++ b/include/linux/gfp.h
+@@ -38,6 +38,12 @@ struct vm_area_struct;
+ #define ___GFP_OTHER_NODE     0x800000u
+ #define ___GFP_WRITE          0x1000000u
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++#define ___GFP_USERCOPY               0x2000000u
++#else
++#define ___GFP_USERCOPY               0
++#endif
++
+ /*
+  * GFP bitmasks..
+  *
+@@ -87,6 +93,7 @@ struct vm_area_struct;
+ #define __GFP_NO_KSWAPD       ((__force gfp_t)___GFP_NO_KSWAPD)
+ #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
+ #define __GFP_WRITE   ((__force gfp_t)___GFP_WRITE)   /* Allocator intends to dirty page */
++#define __GFP_USERCOPY        ((__force gfp_t)___GFP_USERCOPY)/* Allocator intends to copy page to/from userland */
+ /*
+  * This may seem redundant, but it's a way of annotating false positives vs.
+@@ -94,7 +101,7 @@ struct vm_area_struct;
+  */
+ #define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK)
+-#define __GFP_BITS_SHIFT 25   /* Room for N __GFP_FOO bits */
++#define __GFP_BITS_SHIFT 26   /* Room for N __GFP_FOO bits */
+ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
+ /* This equals 0, but use constants in case they ever change */
+@@ -148,6 +155,8 @@ struct vm_area_struct;
+ /* 4GB DMA on some platforms */
+ #define GFP_DMA32     __GFP_DMA32
++#define GFP_USERCOPY  __GFP_USERCOPY
++
+ /* Convert GFP flags to their corresponding migrate type */
+ static inline int allocflags_to_migratetype(gfp_t gfp_flags)
+ {
 diff --git a/include/linux/gracl.h b/include/linux/gracl.h
 new file mode 100644
 index 0000000..c938b1f
@@ -60580,10 +61225,10 @@ index 0000000..b30e9bc
 +#endif
 diff --git a/include/linux/grinternal.h b/include/linux/grinternal.h
 new file mode 100644
-index 0000000..da390f1
+index 0000000..c9292f7
 --- /dev/null
 +++ b/include/linux/grinternal.h
-@@ -0,0 +1,221 @@
+@@ -0,0 +1,223 @@
 +#ifndef __GRINTERNAL_H
 +#define __GRINTERNAL_H
 +
@@ -60645,6 +61290,8 @@ index 0000000..da390f1
 +extern int grsec_enable_chroot_caps;
 +extern int grsec_enable_chroot_sysctl;
 +extern int grsec_enable_chroot_unix;
++extern int grsec_enable_symlinkown;
++extern int grsec_symlinkown_gid;
 +extern int grsec_enable_tpe;
 +extern int grsec_tpe_gid;
 +extern int grsec_enable_tpe_all;
@@ -60807,10 +61454,10 @@ index 0000000..da390f1
 +#endif
 diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h
 new file mode 100644
-index 0000000..ae576a1
+index 0000000..54f4e85
 --- /dev/null
 +++ b/include/linux/grmsg.h
-@@ -0,0 +1,109 @@
+@@ -0,0 +1,110 @@
 +#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 "
@@ -60920,12 +61567,13 @@ index 0000000..ae576a1
 +#define GR_PTRACE_READEXEC_MSG "denied ptrace of unreadable binary %.950s by "
 +#define GR_INIT_TRANSFER_MSG "persistent special role transferred privilege to init by "
 +#define GR_BADPROCPID_MSG "denied read of sensitive /proc/pid/%s entry via fd passed across exec by "
++#define GR_SYMLINKOWNER_MSG "denied following symlink %.950s since symlink owner %u does not match target owner %u, by "
 diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
 new file mode 100644
-index 0000000..acd05db
+index 0000000..38bfb04
 --- /dev/null
 +++ b/include/linux/grsecurity.h
-@@ -0,0 +1,232 @@
+@@ -0,0 +1,233 @@
 +#ifndef GR_SECURITY_H
 +#define GR_SECURITY_H
 +#include <linux/fs.h>
@@ -61110,6 +61758,7 @@ index 0000000..acd05db
 +                              const struct vfsmount *parent_mnt,
 +                              const struct dentry *old_dentry,
 +                              const struct vfsmount *old_mnt, const char *to);
++int gr_handle_symlink_owner(const struct path *link, const struct inode *target);
 +int gr_acl_handle_rename(struct dentry *new_dentry,
 +                              struct dentry *parent_dentry,
 +                              const struct vfsmount *parent_mnt,
@@ -61266,10 +61915,54 @@ index 58404b0..439ed95 100644
  };
  
 diff --git a/include/linux/init.h b/include/linux/init.h
-index 6b95109..4aca62c 100644
+index 6b95109..bcbdd68 100644
 --- a/include/linux/init.h
 +++ b/include/linux/init.h
-@@ -294,13 +294,13 @@ void __init parse_early_options(char *cmdline);
+@@ -39,9 +39,15 @@
+  * Also note, that this data cannot be "const".
+  */
++#ifdef MODULE
++#define add_latent_entropy
++#else
++#define add_latent_entropy __latent_entropy
++#endif
++
+ /* These are for everybody (although not all archs will actually
+    discard it in modules) */
+-#define __init                __section(.init.text) __cold notrace
++#define __init                __section(.init.text) __cold notrace add_latent_entropy
+ #define __initdata    __section(.init.data)
+ #define __initconst   __section(.init.rodata)
+ #define __exitdata    __section(.exit.data)
+@@ -83,7 +89,7 @@
+ #define __exit          __section(.exit.text) __exitused __cold notrace
+ /* Used for HOTPLUG */
+-#define __devinit        __section(.devinit.text) __cold notrace
++#define __devinit        __section(.devinit.text) __cold notrace add_latent_entropy
+ #define __devinitdata    __section(.devinit.data)
+ #define __devinitconst   __section(.devinit.rodata)
+ #define __devexit        __section(.devexit.text) __exitused __cold notrace
+@@ -91,7 +97,7 @@
+ #define __devexitconst   __section(.devexit.rodata)
+ /* Used for HOTPLUG_CPU */
+-#define __cpuinit        __section(.cpuinit.text) __cold notrace
++#define __cpuinit        __section(.cpuinit.text) __cold notrace add_latent_entropy
+ #define __cpuinitdata    __section(.cpuinit.data)
+ #define __cpuinitconst   __section(.cpuinit.rodata)
+ #define __cpuexit        __section(.cpuexit.text) __exitused __cold notrace
+@@ -99,7 +105,7 @@
+ #define __cpuexitconst   __section(.cpuexit.rodata)
+ /* Used for MEMORY_HOTPLUG */
+-#define __meminit        __section(.meminit.text) __cold notrace
++#define __meminit        __section(.meminit.text) __cold notrace add_latent_entropy
+ #define __meminitdata    __section(.meminit.data)
+ #define __meminitconst   __section(.meminit.rodata)
+ #define __memexit        __section(.memexit.text) __exitused __cold notrace
+@@ -294,13 +300,13 @@ void __init parse_early_options(char *cmdline);
  
  /* Each module must use one module_init(). */
  #define module_init(initfn)                                   \
@@ -61708,10 +62401,10 @@ index 74aa71b..4ae97ba 100644
  #endif /* __KERNEL__ */
  #endif /* _LINUX_MM_H */
 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
-index 3cc3062..efeaeb7 100644
+index b35752f..41075a0 100644
 --- a/include/linux/mm_types.h
 +++ b/include/linux/mm_types.h
-@@ -252,6 +252,8 @@ struct vm_area_struct {
+@@ -262,6 +262,8 @@ struct vm_area_struct {
  #ifdef CONFIG_NUMA
        struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
  #endif
@@ -61720,7 +62413,7 @@ index 3cc3062..efeaeb7 100644
  };
  
  struct core_thread {
-@@ -326,7 +328,7 @@ struct mm_struct {
+@@ -336,7 +338,7 @@ struct mm_struct {
        unsigned long def_flags;
        unsigned long nr_ptes;          /* Page table pages */
        unsigned long start_code, end_code, start_data, end_data;
@@ -61729,7 +62422,7 @@ index 3cc3062..efeaeb7 100644
        unsigned long arg_start, arg_end, env_start, env_end;
  
        unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
-@@ -388,6 +390,24 @@ struct mm_struct {
+@@ -398,6 +400,24 @@ struct mm_struct {
  #ifdef CONFIG_CPUMASK_OFFSTACK
        struct cpumask cpumask_allocation;
  #endif
@@ -61775,7 +62468,7 @@ index 1d1b1e1..2a13c78 100644
  
  #define pmdp_clear_flush_notify(__vma, __address, __pmdp)             \
 diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
-index dff7115..0e001c8 100644
+index 5f6806b..49db2b2 100644
 --- a/include/linux/mmzone.h
 +++ b/include/linux/mmzone.h
 @@ -380,7 +380,7 @@ struct zone {
@@ -62201,10 +62894,21 @@ index 85c5073..51fac8b 100644
  struct ctl_table_header;
  struct ctl_table;
 diff --git a/include/linux/random.h b/include/linux/random.h
-index 8f74538..02a1012 100644
+index 8f74538..de61694 100644
 --- a/include/linux/random.h
 +++ b/include/linux/random.h
-@@ -69,12 +69,17 @@ void srandom32(u32 seed);
+@@ -54,6 +54,10 @@ extern void add_input_randomness(unsigned int type, unsigned int code,
+                                unsigned int value);
+ extern void add_interrupt_randomness(int irq);
++#ifdef CONFIG_PAX_LATENT_ENTROPY
++extern void transfer_latent_entropy(void);
++#endif
++
+ extern void get_random_bytes(void *buf, int nbytes);
+ void generate_random_uuid(unsigned char uuid_out[16]);
+@@ -69,12 +73,17 @@ void srandom32(u32 seed);
  
  u32 prandom32(struct rnd_state *);
  
@@ -62317,7 +63021,7 @@ index fd07c45..4676b8e 100644
  static inline void anon_vma_merge(struct vm_area_struct *vma,
                                  struct vm_area_struct *next)
 diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 81a173c..85ccd8f 100644
+index 7b06169..c92adbe 100644
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
 @@ -100,6 +100,7 @@ struct bio_list;
@@ -62501,12 +63205,12 @@ index 81a173c..85ccd8f 100644
 +extern void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_insns(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_refcount_overflow(struct pt_regs *regs);
-+extern __noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type);
++extern void check_object_size(const void *ptr, unsigned long n, bool to);
 +
  /* Future-safe accessor for struct task_struct's cpus_allowed. */
  #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
  
-@@ -2138,7 +2230,9 @@ void yield(void);
+@@ -2146,7 +2238,9 @@ void yield(void);
  extern struct exec_domain     default_exec_domain;
  
  union thread_union {
@@ -62516,7 +63220,7 @@ index 81a173c..85ccd8f 100644
        unsigned long stack[THREAD_SIZE/sizeof(long)];
  };
  
-@@ -2171,6 +2265,7 @@ extern struct pid_namespace init_pid_ns;
+@@ -2179,6 +2273,7 @@ extern struct pid_namespace init_pid_ns;
   */
  
  extern struct task_struct *find_task_by_vpid(pid_t nr);
@@ -62524,7 +63228,7 @@ index 81a173c..85ccd8f 100644
  extern struct task_struct *find_task_by_pid_ns(pid_t nr,
                struct pid_namespace *ns);
  
-@@ -2314,7 +2409,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
+@@ -2322,7 +2417,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
  extern void exit_itimers(struct signal_struct *);
  extern void flush_itimer_signals(void);
  
@@ -62533,7 +63237,7 @@ index 81a173c..85ccd8f 100644
  
  extern void daemonize(const char *, ...);
  extern int allow_signal(int);
-@@ -2515,13 +2610,17 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
+@@ -2523,9 +2618,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
  
  #endif
  
@@ -62545,14 +63249,6 @@ index 81a173c..85ccd8f 100644
  
        return (obj >= stack) && (obj < (stack + THREAD_SIZE));
  }
-+#ifdef CONFIG_PAX_USERCOPY
-+extern int object_is_on_stack(const void *obj, unsigned long len);
-+#endif
-+
- extern void thread_info_cache_init(void);
- #ifdef CONFIG_DEBUG_STACK_USAGE
 diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
 index 899fbb4..1cb4138 100644
 --- a/include/linux/screen_info.h
@@ -62617,10 +63313,10 @@ index 92808b8..c28cac4 100644
  
  /* shm_mode upper byte flags */
 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index c168907..c7756db 100644
+index c1bae8d..2dbcd31 100644
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
-@@ -666,7 +666,7 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb)
+@@ -663,7 +663,7 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb)
   */
  static inline int skb_queue_empty(const struct sk_buff_head *list)
  {
@@ -62629,7 +63325,7 @@ index c168907..c7756db 100644
  }
  
  /**
-@@ -679,7 +679,7 @@ static inline int skb_queue_empty(const struct sk_buff_head *list)
+@@ -676,7 +676,7 @@ static inline int skb_queue_empty(const struct sk_buff_head *list)
  static inline bool skb_queue_is_last(const struct sk_buff_head *list,
                                     const struct sk_buff *skb)
  {
@@ -62638,7 +63334,7 @@ index c168907..c7756db 100644
  }
  
  /**
-@@ -692,7 +692,7 @@ static inline bool skb_queue_is_last(const struct sk_buff_head *list,
+@@ -689,7 +689,7 @@ static inline bool skb_queue_is_last(const struct sk_buff_head *list,
  static inline bool skb_queue_is_first(const struct sk_buff_head *list,
                                      const struct sk_buff *skb)
  {
@@ -62647,7 +63343,7 @@ index c168907..c7756db 100644
  }
  
  /**
-@@ -1587,7 +1587,7 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len)
+@@ -1584,7 +1584,7 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len)
   * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
   */
  #ifndef NET_SKB_PAD
@@ -62657,7 +63353,7 @@ index c168907..c7756db 100644
  
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
 diff --git a/include/linux/slab.h b/include/linux/slab.h
-index a595dce..c403597 100644
+index a595dce..dfab0d2 100644
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
 @@ -11,12 +11,20 @@
@@ -62672,7 +63368,7 @@ index a595dce..c403597 100644
   */
  #define SLAB_DEBUG_FREE               0x00000100UL    /* DEBUG: Perform (expensive) checks on free */
 +
-+#ifdef CONFIG_PAX_USERCOPY
++#ifdef CONFIG_PAX_USERCOPY_SLABS
 +#define SLAB_USERCOPY         0x00000200UL    /* PaX: Allow copying objs to/from userland */
 +#else
 +#define SLAB_USERCOPY         0x00000000UL
@@ -62698,15 +63394,16 @@ index a595dce..c403597 100644
  
  /*
   * struct kmem_cache related prototypes
-@@ -161,6 +172,7 @@ void * __must_check krealloc(const void *, size_t, gfp_t);
+@@ -161,6 +172,8 @@ void * __must_check krealloc(const void *, size_t, gfp_t);
  void kfree(const void *);
  void kzfree(const void *);
  size_t ksize(const void *);
-+void check_object_size(const void *ptr, unsigned long n, bool to);
++const char *check_heap_object(const void *ptr, unsigned long n, bool to);
++bool is_usercopy_object(const void *ptr);
  
  /*
   * Allocator specific definitions. These are mainly used to establish optimized
-@@ -240,6 +252,7 @@ size_t ksize(const void *);
+@@ -240,6 +253,7 @@ size_t ksize(const void *);
   * for general use, and so are not documented here. For a full list of
   * potential flags, always refer to linux/gfp.h.
   */
@@ -62714,7 +63411,7 @@ index a595dce..c403597 100644
  static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
  {
        if (size != 0 && n > ULONG_MAX / size)
-@@ -298,7 +311,7 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
+@@ -298,7 +312,7 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
   */
  #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || \
        (defined(CONFIG_SLAB) && defined(CONFIG_TRACING))
@@ -62723,7 +63420,7 @@ index a595dce..c403597 100644
  #define kmalloc_track_caller(size, flags) \
        __kmalloc_track_caller(size, flags, _RET_IP_)
  #else
-@@ -317,7 +330,7 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
+@@ -317,7 +331,7 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
   */
  #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || \
        (defined(CONFIG_SLAB) && defined(CONFIG_TRACING))
@@ -62733,7 +63430,7 @@ index a595dce..c403597 100644
        __kmalloc_node_track_caller(size, flags, node, \
                        _RET_IP_)
 diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
-index fbd1117..d4d8ef8 100644
+index fbd1117..0a3d314 100644
 --- a/include/linux/slab_def.h
 +++ b/include/linux/slab_def.h
 @@ -66,10 +66,10 @@ struct kmem_cache {
@@ -62751,7 +63448,16 @@ index fbd1117..d4d8ef8 100644
  
        /*
         * If debugging is enabled, then the allocator can add additional
-@@ -107,7 +107,7 @@ struct cache_sizes {
+@@ -103,11 +103,16 @@ struct cache_sizes {
+ #ifdef CONFIG_ZONE_DMA
+       struct kmem_cache       *cs_dmacachep;
+ #endif
++
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++      struct kmem_cache       *cs_usercopycachep;
++#endif
++
+ };
  extern struct cache_sizes malloc_sizes[];
  
  void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
@@ -62760,7 +63466,21 @@ index fbd1117..d4d8ef8 100644
  
  #ifdef CONFIG_TRACING
  extern void *kmem_cache_alloc_trace(size_t size,
-@@ -160,7 +160,7 @@ found:
+@@ -150,6 +155,13 @@ found:
+                       cachep = malloc_sizes[i].cs_dmacachep;
+               else
+ #endif
++
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++              if (flags & GFP_USERCOPY)
++                      cachep = malloc_sizes[i].cs_usercopycachep;
++              else
++#endif
++
+                       cachep = malloc_sizes[i].cs_cachep;
+               ret = kmem_cache_alloc_trace(size, cachep, flags);
+@@ -160,7 +172,7 @@ found:
  }
  
  #ifdef CONFIG_NUMA
@@ -62769,6 +63489,20 @@ index fbd1117..d4d8ef8 100644
  extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
  
  #ifdef CONFIG_TRACING
+@@ -203,6 +215,13 @@ found:
+                       cachep = malloc_sizes[i].cs_dmacachep;
+               else
+ #endif
++
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++              if (flags & GFP_USERCOPY)
++                      cachep = malloc_sizes[i].cs_usercopycachep;
++              else
++#endif
++
+                       cachep = malloc_sizes[i].cs_cachep;
+               return kmem_cache_alloc_node_trace(size, cachep, flags, node);
 diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
 index 0ec00b3..39cb7fc 100644
 --- a/include/linux/slob_def.h
@@ -63336,10 +64070,10 @@ index 6c469db..7743b8e 100644
  
  #endif
 diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
-index b94765e..053f68b 100644
+index 2040bff..f4c0733 100644
 --- a/include/net/inetpeer.h
 +++ b/include/net/inetpeer.h
-@@ -48,8 +48,8 @@ struct inet_peer {
+@@ -51,8 +51,8 @@ struct inet_peer {
         */
        union {
                struct {
@@ -63350,7 +64084,7 @@ index b94765e..053f68b 100644
                        __u32                           tcp_ts;
                        __u32                           tcp_ts_stamp;
                };
-@@ -115,11 +115,11 @@ static inline int inet_getid(struct inet_peer *p, int more)
+@@ -118,11 +118,11 @@ static inline int inet_getid(struct inet_peer *p, int more)
        more++;
        inet_peer_refcheck(p);
        do {
@@ -63378,7 +64112,7 @@ index 10422ef..662570f 100644
         fib_info_update_nh_saddr((net), &FIB_RES_NH(res)))
  #define FIB_RES_GW(res)                       (FIB_RES_NH(res).nh_gw)
 diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
-index 72522f0..6f03a2b 100644
+index 72522f0..2965e05 100644
 --- a/include/net/ip_vs.h
 +++ b/include/net/ip_vs.h
 @@ -510,7 +510,7 @@ struct ip_vs_conn {
@@ -63399,6 +64133,15 @@ index 72522f0..6f03a2b 100644
        atomic_t                weight;         /* server weight */
  
        atomic_t                refcnt;         /* reference counter */
+@@ -1356,7 +1356,7 @@ static inline void ip_vs_notrack(struct sk_buff *skb)
+       struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+       if (!ct || !nf_ct_is_untracked(ct)) {
+-              nf_reset(skb);
++              nf_conntrack_put(skb->nfct);
+               skb->nfct = &nf_ct_untracked_get()->ct_general;
+               skb->nfctinfo = IP_CT_NEW;
+               nf_conntrack_get(skb->nfct);
 diff --git a/include/net/irda/ircomm_core.h b/include/net/irda/ircomm_core.h
 index 69b610a..fe3962c 100644
 --- a/include/net/irda/ircomm_core.h
@@ -63602,10 +64345,10 @@ index 8f9dfba..610ab6c 100644
        u8                             qfull;
        enum fc_lport_state            state;
 diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
-index 6efb2e1..cdad57f 100644
+index ba96988..ecf2eb9 100644
 --- a/include/scsi/scsi_device.h
 +++ b/include/scsi/scsi_device.h
-@@ -162,9 +162,9 @@ struct scsi_device {
+@@ -163,9 +163,9 @@ struct scsi_device {
        unsigned int max_device_blocked; /* what device_blocked counts down from  */
  #define SCSI_DEFAULT_DEVICE_BLOCKED   3
  
@@ -63874,7 +64617,7 @@ index 0993a22..32ba2fe 100644
        void *pmi_pal;
        u8 *vbe_state_orig;             /*
 diff --git a/init/Kconfig b/init/Kconfig
-index 6cfd71d..73cb68d 100644
+index 6cfd71d..16006e6 100644
 --- a/init/Kconfig
 +++ b/init/Kconfig
 @@ -790,6 +790,7 @@ endif # CGROUPS
@@ -63894,6 +64637,15 @@ index 6cfd71d..73cb68d 100644
        help
          Randomizing heap placement makes heap exploits harder, but it
          also breaks ancient binaries (including anything libc5 based).
+@@ -1423,7 +1424,7 @@ config INIT_ALL_POSSIBLE
+ config STOP_MACHINE
+       bool
+       default y
+-      depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU
++      depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU || GRKERNSEC
+       help
+         Need stop_machine() primitive.
 diff --git a/init/do_mounts.c b/init/do_mounts.c
 index 42b0707..c06eef4 100644
 --- a/init/do_mounts.c
@@ -64197,7 +64949,7 @@ index 8216c30..25e8e32 100644
        next_state = Reset;
        return 0;
 diff --git a/init/main.c b/init/main.c
-index b08c5f7..09f865e 100644
+index b08c5f7..bf65a52 100644
 --- a/init/main.c
 +++ b/init/main.c
 @@ -95,6 +95,8 @@ static inline void mark_rodata_ro(void) { }
@@ -64287,7 +65039,39 @@ index b08c5f7..09f865e 100644
        }
  
        return ret;
-@@ -865,7 +911,7 @@ static int __init kernel_init(void * unused)
+@@ -747,8 +793,14 @@ static void __init do_initcall_level(int level)
+                  level, level,
+                  repair_env_string);
+-      for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
++      for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) {
+               do_one_initcall(*fn);
++
++#ifdef CONFIG_PAX_LATENT_ENTROPY
++              transfer_latent_entropy();
++#endif
++
++      }
+ }
+ static void __init do_initcalls(void)
+@@ -782,8 +834,14 @@ static void __init do_pre_smp_initcalls(void)
+ {
+       initcall_t *fn;
+-      for (fn = __initcall_start; fn < __initcall0_start; fn++)
++      for (fn = __initcall_start; fn < __initcall0_start; fn++) {
+               do_one_initcall(*fn);
++
++#ifdef CONFIG_PAX_LATENT_ENTROPY
++              transfer_latent_entropy();
++#endif
++
++      }
+ }
+ static void run_init_process(const char *init_filename)
+@@ -865,7 +923,7 @@ static int __init kernel_init(void * unused)
        do_basic_setup();
  
        /* Open the /dev/console on the rootfs, this should never fail */
@@ -64296,7 +65080,7 @@ index b08c5f7..09f865e 100644
                printk(KERN_WARNING "Warning: unable to open an initial console.\n");
  
        (void) sys_dup(0);
-@@ -878,11 +924,13 @@ static int __init kernel_init(void * unused)
+@@ -878,11 +936,13 @@ static int __init kernel_init(void * unused)
        if (!ramdisk_execute_command)
                ramdisk_execute_command = "/init";
  
@@ -65146,7 +65930,7 @@ index fd126f8..70b755b 100644
  
        /*
 diff --git a/kernel/exit.c b/kernel/exit.c
-index d8bd3b42..26bd8dc 100644
+index 9d81012..d7911f1 100644
 --- a/kernel/exit.c
 +++ b/kernel/exit.c
 @@ -59,6 +59,10 @@
@@ -65198,7 +65982,7 @@ index d8bd3b42..26bd8dc 100644
        /*
         * If we were started as result of loading a module, close all of the
         * user space pages.  We don't need them, and if we didn't close them
-@@ -900,6 +919,8 @@ void do_exit(long code)
+@@ -901,6 +920,8 @@ void do_exit(long code)
        struct task_struct *tsk = current;
        int group_dead;
  
@@ -65207,7 +65991,7 @@ index d8bd3b42..26bd8dc 100644
        profile_task_exit(tsk);
  
        WARN_ON(blk_needs_flush_plug(tsk));
-@@ -916,7 +937,6 @@ void do_exit(long code)
+@@ -917,7 +938,6 @@ void do_exit(long code)
         * mm_release()->clear_child_tid() from writing to a user-controlled
         * kernel address.
         */
@@ -65215,7 +65999,7 @@ index d8bd3b42..26bd8dc 100644
  
        ptrace_event(PTRACE_EVENT_EXIT, code);
  
-@@ -977,6 +997,9 @@ void do_exit(long code)
+@@ -978,6 +998,9 @@ void do_exit(long code)
        tsk->exit_code = code;
        taskstats_exit(tsk, group_dead);
  
@@ -65225,7 +66009,7 @@ index d8bd3b42..26bd8dc 100644
        exit_mm(tsk);
  
        if (group_dead)
-@@ -1093,7 +1116,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
+@@ -1094,7 +1117,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
   * Take down every thread in the group.  This is called by fatal signals
   * as well as by sys_exit_group (below).
   */
@@ -65235,10 +66019,30 @@ index d8bd3b42..26bd8dc 100644
  {
        struct signal_struct *sig = current->signal;
 diff --git a/kernel/fork.c b/kernel/fork.c
-index 8163333..efb4692 100644
+index 8163333..aee97f3 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -286,7 +286,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
+@@ -274,19 +274,24 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
+       }
+       err = arch_dup_task_struct(tsk, orig);
+-      if (err)
+-              goto out;
++      /*
++       * We defer looking at err, because we will need this setup
++       * for the clean up path to work correctly.
++       */
+       tsk->stack = ti;
+-
+       setup_thread_stack(tsk, orig);
++
++      if (err)
++              goto out;
++
+       clear_user_return_notifier(tsk);
+       clear_tsk_need_resched(tsk);
+       stackend = end_of_stack(tsk);
        *stackend = STACK_END_MAGIC;    /* for overflow detection */
  
  #ifdef CONFIG_CC_STACKPROTECTOR
@@ -65247,7 +66051,7 @@ index 8163333..efb4692 100644
  #endif
  
        /*
-@@ -310,13 +310,78 @@ out:
+@@ -310,13 +315,78 @@ out:
  }
  
  #ifdef CONFIG_MMU
@@ -65328,7 +66132,7 @@ index 8163333..efb4692 100644
  
        down_write(&oldmm->mmap_sem);
        flush_cache_dup_mm(oldmm);
-@@ -328,8 +393,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -328,8 +398,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
        mm->locked_vm = 0;
        mm->mmap = NULL;
        mm->mmap_cache = NULL;
@@ -65339,7 +66143,7 @@ index 8163333..efb4692 100644
        mm->map_count = 0;
        cpumask_clear(mm_cpumask(mm));
        mm->mm_rb = RB_ROOT;
-@@ -345,8 +410,6 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -345,8 +415,6 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
  
        prev = NULL;
        for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
@@ -65348,7 +66152,7 @@ index 8163333..efb4692 100644
                if (mpnt->vm_flags & VM_DONTCOPY) {
                        long pages = vma_pages(mpnt);
                        mm->total_vm -= pages;
-@@ -354,54 +417,11 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -354,54 +422,11 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
                                                                -pages);
                        continue;
                }
@@ -65407,7 +66211,7 @@ index 8163333..efb4692 100644
  
                /*
                 * Link in the new vma and copy the page table entries.
-@@ -424,6 +444,31 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -424,6 +449,31 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
                if (retval)
                        goto out;
        }
@@ -65439,7 +66243,7 @@ index 8163333..efb4692 100644
        /* a new mm has just been created */
        arch_dup_mmap(oldmm, mm);
        retval = 0;
-@@ -432,14 +477,6 @@ out:
+@@ -432,14 +482,6 @@ out:
        flush_tlb_mm(oldmm);
        up_write(&oldmm->mmap_sem);
        return retval;
@@ -65454,7 +66258,7 @@ index 8163333..efb4692 100644
  }
  
  static inline int mm_alloc_pgd(struct mm_struct *mm)
-@@ -676,8 +713,8 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
+@@ -676,8 +718,8 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
                return ERR_PTR(err);
  
        mm = get_task_mm(task);
@@ -65465,7 +66269,7 @@ index 8163333..efb4692 100644
                mmput(mm);
                mm = ERR_PTR(-EACCES);
        }
-@@ -899,13 +936,14 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
+@@ -899,13 +941,14 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
                        spin_unlock(&fs->lock);
                        return -EAGAIN;
                }
@@ -65481,7 +66285,7 @@ index 8163333..efb4692 100644
        return 0;
  }
  
-@@ -1172,6 +1210,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
+@@ -1172,6 +1215,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
  #endif
        retval = -EAGAIN;
@@ -65491,16 +66295,17 @@ index 8163333..efb4692 100644
        if (atomic_read(&p->real_cred->user->processes) >=
                        task_rlimit(p, RLIMIT_NPROC)) {
                if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
-@@ -1328,6 +1369,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
-       if (clone_flags & CLONE_THREAD)
-               p->tgid = current->tgid;
+@@ -1392,6 +1438,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
+       /* Need tasklist lock for parent etc handling! */
+       write_lock_irq(&tasklist_lock);
  
++      /* synchronizes with gr_set_acls() */
 +      gr_copy_label(p);
 +
-       p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
-       /*
-        * Clear TID on mm_release()?
-@@ -1502,6 +1545,8 @@ bad_fork_cleanup_count:
+       /* CLONE_PARENT re-uses the old parent */
+       if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
+               p->real_parent = current->real_parent;
+@@ -1502,6 +1551,8 @@ bad_fork_cleanup_count:
  bad_fork_free:
        free_task(p);
  fork_out:
@@ -65509,7 +66314,7 @@ index 8163333..efb4692 100644
        return ERR_PTR(retval);
  }
  
-@@ -1602,6 +1647,8 @@ long do_fork(unsigned long clone_flags,
+@@ -1602,6 +1653,8 @@ long do_fork(unsigned long clone_flags,
                if (clone_flags & CLONE_PARENT_SETTID)
                        put_user(nr, parent_tidptr);
  
@@ -65518,7 +66323,7 @@ index 8163333..efb4692 100644
                if (clone_flags & CLONE_VFORK) {
                        p->vfork_done = &vfork;
                        init_completion(&vfork);
-@@ -1700,7 +1747,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+@@ -1700,7 +1753,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 */
@@ -65527,7 +66332,7 @@ index 8163333..efb4692 100644
                return 0;
  
        *new_fsp = copy_fs_struct(fs);
-@@ -1789,7 +1836,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
+@@ -1789,7 +1842,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
                        fs = current->fs;
                        spin_lock(&fs->lock);
                        current->fs = new_fs;
@@ -65607,18 +66412,18 @@ index 9b22d03..6295b62 100644
                                prev->next = info->next;
                        else
 diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
-index ae34bf5..4e2f3d0 100644
+index 6db7a5e..25b6648 100644
 --- a/kernel/hrtimer.c
 +++ b/kernel/hrtimer.c
-@@ -1393,7 +1393,7 @@ void hrtimer_peek_ahead_timers(void)
+@@ -1407,7 +1407,7 @@ void hrtimer_peek_ahead_timers(void)
        local_irq_restore(flags);
  }
  
 -static void run_hrtimer_softirq(struct softirq_action *h)
 +static void run_hrtimer_softirq(void)
  {
-       hrtimer_peek_ahead_timers();
- }
+       struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
 diff --git a/kernel/jump_label.c b/kernel/jump_label.c
 index 4304919..408c4c0 100644
 --- a/kernel/jump_label.c
@@ -65655,7 +66460,7 @@ index 4304919..408c4c0 100644
  
  static int
 diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
-index 079f1d3..a407562 100644
+index 079f1d3..4e80e69 100644
 --- a/kernel/kallsyms.c
 +++ b/kernel/kallsyms.c
 @@ -11,6 +11,9 @@
@@ -65751,7 +66556,30 @@ index 079f1d3..a407562 100644
        /* Some debugging symbols have no name.  Ignore them. */
        if (!iter->name[0])
                return 0;
-@@ -540,7 +583,7 @@ static int kallsyms_open(struct inode *inode, struct file *file)
+@@ -515,11 +558,22 @@ static int s_show(struct seq_file *m, void *p)
+                */
+               type = iter->exported ? toupper(iter->type) :
+                                       tolower(iter->type);
++
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++              seq_printf(m, "%pP %c %s\t[%s]\n", (void *)iter->value,
++                         type, iter->name, iter->module_name);
++#else
+               seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value,
+                          type, iter->name, iter->module_name);
++#endif
+       } else
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++              seq_printf(m, "%pP %c %s\n", (void *)iter->value,
++                         iter->type, iter->name);
++#else
+               seq_printf(m, "%pK %c %s\n", (void *)iter->value,
+                          iter->type, iter->name);
++#endif
+       return 0;
+ }
+@@ -540,7 +594,7 @@ static int kallsyms_open(struct inode *inode, struct file *file)
        struct kallsym_iter *iter;
        int ret;
  
@@ -67852,10 +68680,10 @@ index 0984a21..939f183 100644
  #ifdef CONFIG_RT_GROUP_SCHED
        /*
 diff --git a/kernel/sched/core.c b/kernel/sched/core.c
-index 2000e06..79cf3d8 100644
+index 817bf70..9099fb4 100644
 --- a/kernel/sched/core.c
 +++ b/kernel/sched/core.c
-@@ -3907,6 +3907,8 @@ int can_nice(const struct task_struct *p, const int nice)
+@@ -4038,6 +4038,8 @@ int can_nice(const struct task_struct *p, const int nice)
        /* convert nice value [19,-20] to rlimit style value [1,40] */
        int nice_rlim = 20 - nice;
  
@@ -67864,7 +68692,7 @@ index 2000e06..79cf3d8 100644
        return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
                capable(CAP_SYS_NICE));
  }
-@@ -3940,7 +3942,8 @@ SYSCALL_DEFINE1(nice, int, increment)
+@@ -4071,7 +4073,8 @@ SYSCALL_DEFINE1(nice, int, increment)
        if (nice > 19)
                nice = 19;
  
@@ -67874,7 +68702,7 @@ index 2000e06..79cf3d8 100644
                return -EPERM;
  
        retval = security_task_setnice(current, nice);
-@@ -4097,6 +4100,7 @@ recheck:
+@@ -4228,6 +4231,7 @@ recheck:
                        unsigned long rlim_rtprio =
                                        task_rlimit(p, RLIMIT_RTPRIO);
  
@@ -68611,7 +69439,7 @@ index f113755..ec24223 100644
                        cpumask_clear_cpu(cpu, tick_get_broadcast_mask());
                        tick_broadcast_clear_oneshot(cpu);
 diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
-index d42574df..247414c 100644
+index 7c50de8..e29a94d 100644
 --- a/kernel/time/timekeeping.c
 +++ b/kernel/time/timekeeping.c
 @@ -14,6 +14,7 @@
@@ -68622,7 +69450,7 @@ index d42574df..247414c 100644
  #include <linux/syscore_ops.h>
  #include <linux/clocksource.h>
  #include <linux/jiffies.h>
-@@ -373,6 +374,8 @@ int do_settimeofday(const struct timespec *tv)
+@@ -388,6 +389,8 @@ int do_settimeofday(const struct timespec *tv)
        if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
                return -EINVAL;
  
@@ -68826,10 +69654,10 @@ index 0fa92f6..89950b2 100644
        struct ftrace_func_probe *entry;
        struct ftrace_page *pg;
 diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
-index 464a96f..bc0bd88 100644
+index 55e4d4c..8c915ec 100644
 --- a/kernel/trace/trace.c
 +++ b/kernel/trace/trace.c
-@@ -4312,10 +4312,9 @@ static const struct file_operations tracing_dyn_info_fops = {
+@@ -4316,10 +4316,9 @@ static const struct file_operations tracing_dyn_info_fops = {
  };
  #endif
  
@@ -68841,7 +69669,7 @@ index 464a96f..bc0bd88 100644
        static int once;
  
        if (d_tracer)
-@@ -4335,10 +4334,9 @@ struct dentry *tracing_init_dentry(void)
+@@ -4339,10 +4338,9 @@ struct dentry *tracing_init_dentry(void)
        return d_tracer;
  }
  
@@ -69239,7 +70067,7 @@ index 3ac50dc..240bb7e 100644
  static inline void *ptr_to_indirect(void *ptr)
  {
 diff --git a/lib/vsprintf.c b/lib/vsprintf.c
-index abbabec..362988d 100644
+index abbabec..d5eba6c 100644
 --- a/lib/vsprintf.c
 +++ b/lib/vsprintf.c
 @@ -16,6 +16,9 @@
@@ -69282,8 +70110,21 @@ index abbabec..362988d 100644
   * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
   * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
   * - 'M' For a 6-byte MAC address, it prints the address in the
-@@ -868,12 +877,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+@@ -866,14 +875,25 @@ static noinline_for_stack
+ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+             struct printf_spec spec)
  {
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++      /* 'P' = approved pointers to copy to userland,
++         as in the /proc/kallsyms case, as we make it display nothing
++         for non-root users, and the real contents for root users
++      */
++      if (ptr > TASK_SIZE && *fmt != 'P' && is_usercopy_object(buf)) {
++              ptr = NULL;
++              goto simple;
++      }
++#endif
++
        if (!ptr && *fmt != 'K') {
                /*
 -               * Print (null) with the same width as a pointer so it makes
@@ -69297,7 +70138,7 @@ index abbabec..362988d 100644
        }
  
        switch (*fmt) {
-@@ -883,6 +892,13 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+@@ -883,6 +903,13 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
                /* Fallthrough */
        case 'S':
        case 's':
@@ -69311,7 +70152,26 @@ index abbabec..362988d 100644
        case 'B':
                return symbol_string(buf, end, ptr, spec, *fmt);
        case 'R':
-@@ -1653,11 +1669,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+@@ -920,6 +947,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+                       va_end(va);
+                       return buf;
+               }
++      case 'P':
++              break;
+       case 'K':
+               /*
+                * %pK cannot be used in IRQ context because its test
+@@ -942,6 +971,9 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+               }
+               break;
+       }
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++simple:
++#endif
+       spec.flags |= SMALL;
+       if (spec.field_width == -1) {
+               spec.field_width = 2 * sizeof(void *);
+@@ -1653,11 +1685,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
        typeof(type) value;                                             \
        if (sizeof(type) == 8) {                                        \
                args = PTR_ALIGN(args, sizeof(u32));                    \
@@ -69326,7 +70186,7 @@ index abbabec..362988d 100644
        }                                                               \
        args += sizeof(type);                                           \
        value;                                                          \
-@@ -1720,7 +1736,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+@@ -1720,7 +1752,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
                case FORMAT_TYPE_STR: {
                        const char *str_arg = args;
                        args += strlen(str_arg) + 1;
@@ -69589,10 +70449,10 @@ index d53adf9..03a24bf 100644
        set_fs(old_fs);
  
 diff --git a/mm/madvise.c b/mm/madvise.c
-index 1ccbba5..79e16f9 100644
+index 55f645c..cde5320 100644
 --- a/mm/madvise.c
 +++ b/mm/madvise.c
-@@ -45,6 +45,10 @@ static long madvise_behavior(struct vm_area_struct * vma,
+@@ -46,6 +46,10 @@ static long madvise_behavior(struct vm_area_struct * vma,
        pgoff_t pgoff;
        unsigned long new_flags = vma->vm_flags;
  
@@ -69603,7 +70463,7 @@ index 1ccbba5..79e16f9 100644
        switch (behavior) {
        case MADV_NORMAL:
                new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
-@@ -116,6 +120,13 @@ success:
+@@ -117,6 +121,13 @@ success:
        /*
         * vm_flags is protected by the mmap_sem held in write mode.
         */
@@ -69617,7 +70477,7 @@ index 1ccbba5..79e16f9 100644
        vma->vm_flags = new_flags;
  
  out:
-@@ -174,6 +185,11 @@ static long madvise_dontneed(struct vm_area_struct * vma,
+@@ -175,6 +186,11 @@ static long madvise_dontneed(struct vm_area_struct * vma,
                             struct vm_area_struct ** prev,
                             unsigned long start, unsigned long end)
  {
@@ -69629,7 +70489,7 @@ index 1ccbba5..79e16f9 100644
        *prev = vma;
        if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
                return -EINVAL;
-@@ -186,6 +202,21 @@ static long madvise_dontneed(struct vm_area_struct * vma,
+@@ -187,6 +203,21 @@ static long madvise_dontneed(struct vm_area_struct * vma,
                zap_page_range(vma, start, end - start, &details);
        } else
                zap_page_range(vma, start, end - start, NULL);
@@ -69651,7 +70511,7 @@ index 1ccbba5..79e16f9 100644
        return 0;
  }
  
-@@ -384,6 +415,16 @@ SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior)
+@@ -394,6 +425,16 @@ SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior)
        if (end < start)
                goto out;
  
@@ -70474,7 +71334,7 @@ index bf5b485..e44c2cb 100644
                capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);
  
 diff --git a/mm/mlock.c b/mm/mlock.c
-index ef726e8..13e0901 100644
+index ef726e8..cd7f1ec 100644
 --- a/mm/mlock.c
 +++ b/mm/mlock.c
 @@ -13,6 +13,7 @@
@@ -70485,6 +71345,15 @@ index ef726e8..13e0901 100644
  #include <linux/sched.h>
  #include <linux/export.h>
  #include <linux/rmap.h>
+@@ -376,7 +377,7 @@ static int do_mlock(unsigned long start, size_t len, int on)
+ {
+       unsigned long nstart, end, tmp;
+       struct vm_area_struct * vma, * prev;
+-      int error;
++      int error = 0;
+       VM_BUG_ON(start & ~PAGE_MASK);
+       VM_BUG_ON(len != PAGE_ALIGN(len));
 @@ -385,6 +386,9 @@ static int do_mlock(unsigned long start, size_t len, int on)
                return -EINVAL;
        if (end == start)
@@ -72402,7 +73271,7 @@ index 5b5ad58..0f77903 100644
        struct anon_vma_chain *avc;
        struct anon_vma *anon_vma;
 diff --git a/mm/shmem.c b/mm/shmem.c
-index f99ff3e..faea8b6 100644
+index 9d65a02..7c877e7 100644
 --- a/mm/shmem.c
 +++ b/mm/shmem.c
 @@ -31,7 +31,7 @@
@@ -72423,7 +73292,7 @@ index f99ff3e..faea8b6 100644
  
  struct shmem_xattr {
        struct list_head list;  /* anchored by shmem_inode_info->xattr_list */
-@@ -2235,8 +2235,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
+@@ -2236,8 +2236,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
        int err = -ENOMEM;
  
        /* Round up to L1_CACHE_BYTES to resist false sharing */
@@ -72434,7 +73303,7 @@ index f99ff3e..faea8b6 100644
                return -ENOMEM;
  
 diff --git a/mm/slab.c b/mm/slab.c
-index e901a36..ee8fe97 100644
+index e901a36..ca479fc 100644
 --- a/mm/slab.c
 +++ b/mm/slab.c
 @@ -153,7 +153,7 @@
@@ -72488,16 +73357,36 @@ index e901a36..ee8fe97 100644
  {
        u32 offset = (obj - slab->s_mem);
        return reciprocal_divide(offset, cache->reciprocal_buffer_size);
-@@ -568,7 +568,7 @@ struct cache_names {
+@@ -563,12 +563,13 @@ EXPORT_SYMBOL(malloc_sizes);
+ struct cache_names {
+       char *name;
+       char *name_dma;
++      char *name_usercopy;
+ };
  static struct cache_names __initdata cache_names[] = {
- #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
+-#define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
++#define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)", .name_usercopy = "size-" #x "(USERCOPY)" },
  #include <linux/kmalloc_sizes.h>
 -      {NULL,}
 +      {NULL}
  #undef CACHE
  };
  
-@@ -1588,7 +1588,7 @@ void __init kmem_cache_init(void)
+@@ -756,6 +757,12 @@ static inline struct kmem_cache *__find_general_cachep(size_t size,
+       if (unlikely(gfpflags & GFP_DMA))
+               return csizep->cs_dmacachep;
+ #endif
++
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++      if (unlikely(gfpflags & GFP_USERCOPY))
++              return csizep->cs_usercopycachep;
++#endif
++
+       return csizep->cs_cachep;
+ }
+@@ -1588,7 +1595,7 @@ void __init kmem_cache_init(void)
        sizes[INDEX_AC].cs_cachep = kmem_cache_create(names[INDEX_AC].name,
                                        sizes[INDEX_AC].cs_size,
                                        ARCH_KMALLOC_MINALIGN,
@@ -72506,7 +73395,7 @@ index e901a36..ee8fe97 100644
                                        NULL);
  
        if (INDEX_AC != INDEX_L3) {
-@@ -1596,7 +1596,7 @@ void __init kmem_cache_init(void)
+@@ -1596,7 +1603,7 @@ void __init kmem_cache_init(void)
                        kmem_cache_create(names[INDEX_L3].name,
                                sizes[INDEX_L3].cs_size,
                                ARCH_KMALLOC_MINALIGN,
@@ -72515,7 +73404,7 @@ index e901a36..ee8fe97 100644
                                NULL);
        }
  
-@@ -1614,7 +1614,7 @@ void __init kmem_cache_init(void)
+@@ -1614,7 +1621,7 @@ void __init kmem_cache_init(void)
                        sizes->cs_cachep = kmem_cache_create(names->name,
                                        sizes->cs_size,
                                        ARCH_KMALLOC_MINALIGN,
@@ -72524,7 +73413,24 @@ index e901a36..ee8fe97 100644
                                        NULL);
                }
  #ifdef CONFIG_ZONE_DMA
-@@ -4390,10 +4390,10 @@ static int s_show(struct seq_file *m, void *p)
+@@ -1626,6 +1633,16 @@ void __init kmem_cache_init(void)
+                                               SLAB_PANIC,
+                                       NULL);
+ #endif
++
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++              sizes->cs_usercopycachep = kmem_cache_create(
++                                      names->name_usercopy,
++                                      sizes->cs_size,
++                                      ARCH_KMALLOC_MINALIGN,
++                                      ARCH_KMALLOC_FLAGS|SLAB_PANIC|SLAB_USERCOPY,
++                                      NULL);
++#endif
++
+               sizes++;
+               names++;
+       }
+@@ -4390,10 +4407,10 @@ static int s_show(struct seq_file *m, void *p)
        }
        /* cpu stats */
        {
@@ -72539,7 +73445,7 @@ index e901a36..ee8fe97 100644
  
                seq_printf(m, " : cpustat %6lu %6lu %6lu %6lu",
                           allochit, allocmiss, freehit, freemiss);
-@@ -4652,13 +4652,62 @@ static int __init slab_proc_init(void)
+@@ -4652,13 +4669,68 @@ static int __init slab_proc_init(void)
  {
        proc_create("slabinfo",S_IWUSR|S_IRUSR,NULL,&proc_slabinfo_operations);
  #ifdef CONFIG_DEBUG_SLAB_LEAK
@@ -72551,60 +73457,66 @@ index e901a36..ee8fe97 100644
  module_init(slab_proc_init);
  #endif
  
-+void check_object_size(const void *ptr, unsigned long n, bool to)
++bool is_usercopy_object(const void *ptr)
 +{
++      struct page *page;
++      struct kmem_cache *cachep;
++
++      if (ZERO_OR_NULL_PTR(ptr))
++              return false;
++
++      if (!virt_addr_valid(ptr))
++              return false;
++
++      page = virt_to_head_page(ptr);
++
++      if (!PageSlab(page))
++              return false;
++
++      cachep = page_get_cache(page);
++      return cachep->flags & SLAB_USERCOPY;
++}
 +
 +#ifdef CONFIG_PAX_USERCOPY
++const char *check_heap_object(const void *ptr, unsigned long n, bool to)
++{
 +      struct page *page;
-+      struct kmem_cache *cachep = NULL;
++      struct kmem_cache *cachep;
 +      struct slab *slabp;
 +      unsigned int objnr;
 +      unsigned long offset;
-+      const char *type;
-+
-+      if (!n)
-+              return;
 +
-+      type = "<null>";
 +      if (ZERO_OR_NULL_PTR(ptr))
-+              goto report;
++              return "<null>";
 +
 +      if (!virt_addr_valid(ptr))
-+              return;
++              return NULL;
 +
 +      page = virt_to_head_page(ptr);
 +
-+      type = "<process stack>";
-+      if (!PageSlab(page)) {
-+              if (object_is_on_stack(ptr, n) == -1)
-+                      goto report;
-+              return;
-+      }
++      if (!PageSlab(page))
++              return NULL;
 +
 +      cachep = page_get_cache(page);
-+      type = cachep->name;
 +      if (!(cachep->flags & SLAB_USERCOPY))
-+              goto report;
++              return cachep->name;
 +
 +      slabp = page_get_slab(page);
 +      objnr = obj_to_index(cachep, slabp, ptr);
 +      BUG_ON(objnr >= cachep->num);
 +      offset = ptr - index_to_obj(cachep, slabp, objnr) - obj_offset(cachep);
 +      if (offset <= obj_size(cachep) && n <= obj_size(cachep) - offset)
-+              return;
-+
-+report:
-+      pax_report_usercopy(ptr, n, to, type);
-+#endif
++              return NULL;
 +
++      return cachep->name;
 +}
-+EXPORT_SYMBOL(check_object_size);
++#endif
 +
  /**
   * ksize - get the actual amount of memory allocated for a given object
   * @objp: Pointer to the object
 diff --git a/mm/slob.c b/mm/slob.c
-index 8105be4..e045f96 100644
+index 8105be4..3c15e57 100644
 --- a/mm/slob.c
 +++ b/mm/slob.c
 @@ -29,7 +29,7 @@
@@ -72755,7 +73667,7 @@ index 8105be4..e045f96 100644
        return ret;
  }
  EXPORT_SYMBOL(__kmalloc_node);
-@@ -533,13 +547,92 @@ void kfree(const void *block)
+@@ -533,13 +547,83 @@ void kfree(const void *block)
        sp = slob_page(block);
        if (is_slob_page(sp)) {
                int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
@@ -72773,40 +73685,34 @@ index 8105be4..e045f96 100644
  }
  EXPORT_SYMBOL(kfree);
  
-+void check_object_size(const void *ptr, unsigned long n, bool to)
++bool is_usercopy_object(const void *ptr)
 +{
++      return false;
++}
 +
 +#ifdef CONFIG_PAX_USERCOPY
++const char *check_heap_object(const void *ptr, unsigned long n, bool to)
++{
 +      struct slob_page *sp;
 +      const slob_t *free;
 +      const void *base;
 +      unsigned long flags;
-+      const char *type;
-+
-+      if (!n)
-+              return;
 +
-+      type = "<null>";
 +      if (ZERO_OR_NULL_PTR(ptr))
-+              goto report;
++              return "<null>";
 +
 +      if (!virt_addr_valid(ptr))
-+              return;
++              return NULL;
 +
-+      type = "<process stack>";
 +      sp = slob_page(ptr);
-+      if (!PageSlab((struct page *)sp)) {
-+              if (object_is_on_stack(ptr, n) == -1)
-+                      goto report;
-+              return;
-+      }
++      if (!PageSlab((struct page *)sp))
++              return NULL;
 +
-+      type = "<slob>";
 +      if (sp->size) {
 +              base = page_address(&sp->page);
 +              if (base <= ptr && n <= sp->size - (ptr - base))
-+                      return;
-+              goto report;
++                      return NULL;
++              return "<slob>";
 +      }
 +
 +      /* some tricky double walking to find the chunk */
@@ -72837,21 +73743,18 @@ index 8105be4..e045f96 100644
 +                      break;
 +
 +              spin_unlock_irqrestore(&slob_lock, flags);
-+              return;
++              return NULL;
 +      }
 +
 +      spin_unlock_irqrestore(&slob_lock, flags);
-+report:
-+      pax_report_usercopy(ptr, n, to, type);
-+#endif
-+
++      return "<slob>";
 +}
-+EXPORT_SYMBOL(check_object_size);
++#endif
 +
  /* can't use ksize for kmem_cache_alloc memory, only kmalloc */
  size_t ksize(const void *block)
  {
-@@ -552,10 +645,10 @@ size_t ksize(const void *block)
+@@ -552,10 +636,10 @@ size_t ksize(const void *block)
        sp = slob_page(block);
        if (is_slob_page(sp)) {
                int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
@@ -72865,11 +73768,11 @@ index 8105be4..e045f96 100644
  }
  EXPORT_SYMBOL(ksize);
  
-@@ -571,8 +664,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
+@@ -571,8 +655,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
  {
        struct kmem_cache *c;
  
-+#ifdef CONFIG_PAX_USERCOPY
++#ifdef CONFIG_PAX_USERCOPY_SLABS
 +      c = __kmalloc_node_align(sizeof(struct kmem_cache),
 +              GFP_KERNEL, -1, ARCH_KMALLOC_MINALIGN);
 +#else
@@ -72879,11 +73782,11 @@ index 8105be4..e045f96 100644
  
        if (c) {
                c->name = name;
-@@ -614,17 +712,25 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
+@@ -614,17 +703,25 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
  
        lockdep_trace_alloc(flags);
  
-+#ifdef CONFIG_PAX_USERCOPY
++#ifdef CONFIG_PAX_USERCOPY_SLABS
 +      b = __kmalloc_node_align(c->size, flags, node, c->align);
 +#else
        if (c->size < PAGE_SIZE) {
@@ -72905,7 +73808,7 @@ index 8105be4..e045f96 100644
  
        if (c->ctor)
                c->ctor(b);
-@@ -636,10 +742,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
+@@ -636,10 +733,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
  
  static void __kmem_cache_free(void *b, int size)
  {
@@ -72924,13 +73827,13 @@ index 8105be4..e045f96 100644
  }
  
  static void kmem_rcu_free(struct rcu_head *head)
-@@ -652,17 +764,31 @@ static void kmem_rcu_free(struct rcu_head *head)
+@@ -652,17 +755,31 @@ static void kmem_rcu_free(struct rcu_head *head)
  
  void kmem_cache_free(struct kmem_cache *c, void *b)
  {
 +      int size = c->size;
 +
-+#ifdef CONFIG_PAX_USERCOPY
++#ifdef CONFIG_PAX_USERCOPY_SLABS
 +      if (size + c->align < PAGE_SIZE) {
 +              size += c->align;
 +              b -= c->align;
@@ -72950,7 +73853,7 @@ index 8105be4..e045f96 100644
 +              __kmem_cache_free(b, size);
        }
  
-+#ifdef CONFIG_PAX_USERCOPY
++#ifdef CONFIG_PAX_USERCOPY_SLABS
 +      trace_kfree(_RET_IP_, b);
 +#else
        trace_kmem_cache_free(_RET_IP_, b);
@@ -72960,7 +73863,7 @@ index 8105be4..e045f96 100644
  EXPORT_SYMBOL(kmem_cache_free);
  
 diff --git a/mm/slub.c b/mm/slub.c
-index 71de9b5..dd263c5 100644
+index 71de9b5..a93d4a4 100644
 --- a/mm/slub.c
 +++ b/mm/slub.c
 @@ -209,7 +209,7 @@ struct track {
@@ -73018,58 +73921,89 @@ index 71de9b5..dd263c5 100644
                list_del(&s->list);
                up_write(&slub_lock);
                if (kmem_cache_close(s)) {
-@@ -3405,6 +3406,50 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
+@@ -3223,6 +3224,10 @@ static struct kmem_cache *kmem_cache;
+ static struct kmem_cache *kmalloc_dma_caches[SLUB_PAGE_SHIFT];
+ #endif
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++static struct kmem_cache *kmalloc_usercopy_caches[SLUB_PAGE_SHIFT];
++#endif
++
+ static int __init setup_slub_min_order(char *str)
+ {
+       get_option(&str, &slub_min_order);
+@@ -3337,6 +3342,13 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
+               return kmalloc_dma_caches[index];
+ #endif
++
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++      if (flags & SLAB_USERCOPY)
++              return kmalloc_usercopy_caches[index];
++
++#endif
++
+       return kmalloc_caches[index];
+ }
+@@ -3405,6 +3417,56 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
  EXPORT_SYMBOL(__kmalloc_node);
  #endif
  
-+void check_object_size(const void *ptr, unsigned long n, bool to)
++bool is_usercopy_object(const void *ptr)
 +{
++      struct page *page;
++      struct kmem_cache *s;
++
++      if (ZERO_OR_NULL_PTR(ptr))
++              return false;
++
++      if (!virt_addr_valid(ptr))
++              return false;
++
++      page = virt_to_head_page(ptr);
++
++      if (!PageSlab(page))
++              return false;
++
++      s = page->slab;
++      return s->flags & SLAB_USERCOPY;
++}
 +
 +#ifdef CONFIG_PAX_USERCOPY
++const char *check_heap_object(const void *ptr, unsigned long n, bool to)
++{
 +      struct page *page;
-+      struct kmem_cache *s = NULL;
++      struct kmem_cache *s;
 +      unsigned long offset;
-+      const char *type;
 +
-+      if (!n)
-+              return;
-+
-+      type = "<null>";
 +      if (ZERO_OR_NULL_PTR(ptr))
-+              goto report;
++              return "<null>";
 +
 +      if (!virt_addr_valid(ptr))
-+              return;
++              return NULL;
 +
 +      page = virt_to_head_page(ptr);
 +
-+      type = "<process stack>";
-+      if (!PageSlab(page)) {
-+              if (object_is_on_stack(ptr, n) == -1)
-+                      goto report;
-+              return;
-+      }
++      if (!PageSlab(page))
++              return NULL;
 +
 +      s = page->slab;
-+      type = s->name;
 +      if (!(s->flags & SLAB_USERCOPY))
-+              goto report;
++              return s->name;
 +
 +      offset = (ptr - page_address(page)) % s->size;
 +      if (offset <= s->objsize && n <= s->objsize - offset)
-+              return;
-+
-+report:
-+      pax_report_usercopy(ptr, n, to, type);
-+#endif
++              return NULL;
 +
++      return s->name;
 +}
-+EXPORT_SYMBOL(check_object_size);
++#endif
 +
  size_t ksize(const void *object)
  {
        struct page *page;
-@@ -3679,7 +3724,7 @@ static void __init kmem_cache_bootstrap_fixup(struct kmem_cache *s)
+@@ -3679,7 +3741,7 @@ static void __init kmem_cache_bootstrap_fixup(struct kmem_cache *s)
        int node;
  
        list_add(&s->list, &slab_caches);
@@ -73078,7 +74012,7 @@ index 71de9b5..dd263c5 100644
  
        for_each_node_state(node, N_NORMAL_MEMORY) {
                struct kmem_cache_node *n = get_node(s, node);
-@@ -3799,17 +3844,17 @@ void __init kmem_cache_init(void)
+@@ -3799,17 +3861,17 @@ void __init kmem_cache_init(void)
  
        /* Caches that are not of the two-to-the-power-of size */
        if (KMALLOC_MIN_SIZE <= 32) {
@@ -73099,7 +74033,30 @@ index 71de9b5..dd263c5 100644
                caches++;
        }
  
-@@ -3877,7 +3922,7 @@ static int slab_unmergeable(struct kmem_cache *s)
+@@ -3851,6 +3913,22 @@ void __init kmem_cache_init(void)
+               }
+       }
+ #endif
++
++#ifdef CONFIG_PAX_USERCOPY_SLABS
++      for (i = 0; i < SLUB_PAGE_SHIFT; i++) {
++              struct kmem_cache *s = kmalloc_caches[i];
++
++              if (s && s->size) {
++                      char *name = kasprintf(GFP_NOWAIT,
++                               "usercopy-kmalloc-%d", s->objsize);
++
++                      BUG_ON(!name);
++                      kmalloc_usercopy_caches[i] = create_kmalloc_cache(name,
++                              s->objsize, SLAB_USERCOPY);
++              }
++      }
++#endif
++
+       printk(KERN_INFO
+               "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
+               " CPUs=%d, Nodes=%d\n",
+@@ -3877,7 +3955,7 @@ static int slab_unmergeable(struct kmem_cache *s)
        /*
         * We may have set a slab to be unmergeable during bootstrap.
         */
@@ -73108,7 +74065,7 @@ index 71de9b5..dd263c5 100644
                return 1;
  
        return 0;
-@@ -3936,7 +3981,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
+@@ -3936,7 +4014,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
        down_write(&slub_lock);
        s = find_mergeable(size, align, flags, name, ctor);
        if (s) {
@@ -73117,7 +74074,7 @@ index 71de9b5..dd263c5 100644
                /*
                 * Adjust the object sizes so that we clear
                 * the complete object on kzalloc.
-@@ -3945,7 +3990,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
+@@ -3945,7 +4023,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
                s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
  
                if (sysfs_slab_alias(s, name)) {
@@ -73126,7 +74083,7 @@ index 71de9b5..dd263c5 100644
                        goto err;
                }
                up_write(&slub_lock);
-@@ -4074,7 +4119,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
+@@ -4074,7 +4152,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
  }
  #endif
  
@@ -73135,7 +74092,7 @@ index 71de9b5..dd263c5 100644
  static int count_inuse(struct page *page)
  {
        return page->inuse;
-@@ -4461,12 +4506,12 @@ static void resiliency_test(void)
+@@ -4461,12 +4539,12 @@ static void resiliency_test(void)
        validate_slab_cache(kmalloc_caches[9]);
  }
  #else
@@ -73150,7 +74107,7 @@ index 71de9b5..dd263c5 100644
  enum slab_stat_type {
        SL_ALL,                 /* All slabs */
        SL_PARTIAL,             /* Only partially allocated slabs */
-@@ -4709,7 +4754,7 @@ SLAB_ATTR_RO(ctor);
+@@ -4709,7 +4787,7 @@ SLAB_ATTR_RO(ctor);
  
  static ssize_t aliases_show(struct kmem_cache *s, char *buf)
  {
@@ -73159,7 +74116,7 @@ index 71de9b5..dd263c5 100644
  }
  SLAB_ATTR_RO(aliases);
  
-@@ -5280,6 +5325,7 @@ static char *create_unique_id(struct kmem_cache *s)
+@@ -5280,6 +5358,7 @@ static char *create_unique_id(struct kmem_cache *s)
        return name;
  }
  
@@ -73167,7 +74124,7 @@ index 71de9b5..dd263c5 100644
  static int sysfs_slab_add(struct kmem_cache *s)
  {
        int err;
-@@ -5342,6 +5388,7 @@ static void sysfs_slab_remove(struct kmem_cache *s)
+@@ -5342,6 +5421,7 @@ static void sysfs_slab_remove(struct kmem_cache *s)
        kobject_del(&s->kobj);
        kobject_put(&s->kobj);
  }
@@ -73175,7 +74132,7 @@ index 71de9b5..dd263c5 100644
  
  /*
   * Need to buffer aliases during bootup until sysfs becomes
-@@ -5355,6 +5402,7 @@ struct saved_alias {
+@@ -5355,6 +5435,7 @@ struct saved_alias {
  
  static struct saved_alias *alias_list;
  
@@ -73183,7 +74140,7 @@ index 71de9b5..dd263c5 100644
  static int sysfs_slab_alias(struct kmem_cache *s, const char *name)
  {
        struct saved_alias *al;
-@@ -5377,6 +5425,7 @@ static int sysfs_slab_alias(struct kmem_cache *s, const char *name)
+@@ -5377,6 +5458,7 @@ static int sysfs_slab_alias(struct kmem_cache *s, const char *name)
        alias_list = al;
        return 0;
  }
@@ -73513,6 +74470,22 @@ index 1196c77..2e608e8 100644
        if (!vas || !vms)
                goto err_free2;
  
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 4607cc6..be5bc0a 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -3013,7 +3013,10 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
+                * them before going back to sleep.
+                */
+               set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold);
+-              schedule();
++
++              if (!kthread_should_stop())
++                      schedule();
++
+               set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold);
+       } else {
+               if (remaining)
 diff --git a/mm/vmstat.c b/mm/vmstat.c
 index 7db1b9b..e9f6b07 100644
 --- a/mm/vmstat.c
@@ -73862,6 +74835,21 @@ index 5fe2ff3..10968b5 100644
                        BUGPRINT("c2u Didn't work\n");
                        ret = -EFAULT;
                        break;
+diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
+index aa6f716..7bf4c21 100644
+--- a/net/caif/caif_dev.c
++++ b/net/caif/caif_dev.c
+@@ -562,9 +562,9 @@ static int __init caif_device_init(void)
+ static void __exit caif_device_exit(void)
+ {
+-      unregister_pernet_subsys(&caif_net_ops);
+       unregister_netdevice_notifier(&caif_device_notifier);
+       dev_remove_pack(&caif_packet_type);
++      unregister_pernet_subsys(&caif_net_ops);
+ }
+ module_init(caif_device_init);
 diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
 index 5cf5222..6f704ad 100644
 --- a/net/caif/cfctrl.c
@@ -74063,7 +75051,7 @@ index e4fbfd6..6a6ac94 100644
  
        return err;
 diff --git a/net/core/dev.c b/net/core/dev.c
-index 99e1d75..adf968a 100644
+index 533c586..f78a55f 100644
 --- a/net/core/dev.c
 +++ b/net/core/dev.c
 @@ -1136,9 +1136,13 @@ void dev_load(struct net *net, const char *name)
@@ -74107,7 +75095,7 @@ index 99e1d75..adf968a 100644
  
  #define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
  
-@@ -2898,7 +2902,7 @@ enqueue:
+@@ -2877,7 +2881,7 @@ enqueue:
  
        local_irq_restore(flags);
  
@@ -74116,7 +75104,7 @@ index 99e1d75..adf968a 100644
        kfree_skb(skb);
        return NET_RX_DROP;
  }
-@@ -2970,7 +2974,7 @@ int netif_rx_ni(struct sk_buff *skb)
+@@ -2949,7 +2953,7 @@ int netif_rx_ni(struct sk_buff *skb)
  }
  EXPORT_SYMBOL(netif_rx_ni);
  
@@ -74125,7 +75113,7 @@ index 99e1d75..adf968a 100644
  {
        struct softnet_data *sd = &__get_cpu_var(softnet_data);
  
-@@ -3258,7 +3262,7 @@ ncls:
+@@ -3237,7 +3241,7 @@ ncls:
        if (pt_prev) {
                ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
        } else {
@@ -74134,7 +75122,7 @@ index 99e1d75..adf968a 100644
                kfree_skb(skb);
                /* Jamal, now you will not able to escape explaining
                 * me how you were going to use this. :-)
-@@ -3818,7 +3822,7 @@ void netif_napi_del(struct napi_struct *napi)
+@@ -3797,7 +3801,7 @@ void netif_napi_del(struct napi_struct *napi)
  }
  EXPORT_SYMBOL(netif_napi_del);
  
@@ -74143,7 +75131,7 @@ index 99e1d75..adf968a 100644
  {
        struct softnet_data *sd = &__get_cpu_var(softnet_data);
        unsigned long time_limit = jiffies + 2;
-@@ -4288,8 +4292,13 @@ static int ptype_seq_show(struct seq_file *seq, void *v)
+@@ -4267,8 +4271,13 @@ static int ptype_seq_show(struct seq_file *seq, void *v)
                else
                        seq_printf(seq, "%04x", ntohs(pt->type));
  
@@ -74157,7 +75145,7 @@ index 99e1d75..adf968a 100644
        }
  
        return 0;
-@@ -5839,7 +5848,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+@@ -5818,7 +5827,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
        } else {
                netdev_stats_to_stats64(storage, &dev->stats);
        }
@@ -74282,7 +75270,7 @@ index 611c5ef..88f6d6d 100644
        {
                int new_fd;
 diff --git a/net/core/sock.c b/net/core/sock.c
-index b2e14c0..6651b32 100644
+index 0f8402e..f0b6338 100644
 --- a/net/core/sock.c
 +++ b/net/core/sock.c
 @@ -340,7 +340,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
@@ -74357,7 +75345,7 @@ index b2e14c0..6651b32 100644
                return -EFAULT;
  lenout:
        if (put_user(len, optlen))
-@@ -2128,7 +2128,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
+@@ -2131,7 +2131,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
         */
        smp_wmb();
        atomic_set(&sk->sk_refcnt, 1);
@@ -74433,6 +75421,23 @@ index 39a2d29..f39c0fe 100644
        ---help---
          Econet is a fairly old and slow networking protocol mainly used by
          Acorn computers to access file and print servers. It uses native
+diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
+index c48adc5..667c1d4 100644
+--- a/net/ipv4/cipso_ipv4.c
++++ b/net/ipv4/cipso_ipv4.c
+@@ -1725,8 +1725,10 @@ int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
+               case CIPSO_V4_TAG_LOCAL:
+                       /* This is a non-standard tag that we only allow for
+                        * local connections, so if the incoming interface is
+-                       * not the loopback device drop the packet. */
+-                      if (!(skb->dev->flags & IFF_LOOPBACK)) {
++                       * not the loopback device drop the packet. Further,
++                       * there is no legitimate reason for setting this from
++                       * userspace so reject it if skb is NULL. */
++                      if (skb == NULL || !(skb->dev->flags & IFF_LOOPBACK)) {
+                               err_offset = opt_iter;
+                               goto validate_return_locked;
+                       }
 diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
 index cbe3a68..a879b75 100644
 --- a/net/ipv4/fib_frontend.c
@@ -74504,7 +75509,7 @@ index 984ec65..97ac518 100644
                        inet_twsk_deschedule(tw, death_row);
                        while (twrefcnt) {
 diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
-index d4d61b6..b81aec8 100644
+index dfba343..c827d50 100644
 --- a/net/ipv4/inetpeer.c
 +++ b/net/ipv4/inetpeer.c
 @@ -487,8 +487,8 @@ relookup:
@@ -75410,10 +76415,10 @@ index 6b9d5a0..4dffaf1 100644
        seq_printf(m, "Max header size: %d\n", self->max_header_size);
  
 diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
-index 07d7d55..541de95 100644
+index cd6f7a9..e63fe89 100644
 --- a/net/iucv/af_iucv.c
 +++ b/net/iucv/af_iucv.c
-@@ -783,10 +783,10 @@ static int iucv_sock_autobind(struct sock *sk)
+@@ -782,10 +782,10 @@ static int iucv_sock_autobind(struct sock *sk)
  
        write_lock_bh(&iucv_sk_list.lock);
  
@@ -75692,7 +76697,7 @@ index 00bdb1d..6725a48 100644
        if ((ipvs->sync_state & IP_VS_STATE_MASTER) &&
            cp->protocol == IPPROTO_SCTP) {
 diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
-index f558998..9cdff60 100644
+index f558998..7dfb054 100644
 --- a/net/netfilter/ipvs/ip_vs_ctl.c
 +++ b/net/netfilter/ipvs/ip_vs_ctl.c
 @@ -788,7 +788,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
@@ -75704,7 +76709,30 @@ index f558998..9cdff60 100644
  
        /* bind the service */
        if (!dest->svc) {
-@@ -2028,7 +2028,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
+@@ -1521,11 +1521,12 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event,
+ {
+       struct net_device *dev = ptr;
+       struct net *net = dev_net(dev);
++      struct netns_ipvs *ipvs = net_ipvs(net);
+       struct ip_vs_service *svc;
+       struct ip_vs_dest *dest;
+       unsigned int idx;
+-      if (event != NETDEV_UNREGISTER)
++      if (event != NETDEV_UNREGISTER || !ipvs)
+               return NOTIFY_DONE;
+       IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name);
+       EnterFunction(2);
+@@ -1551,7 +1552,7 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event,
+               }
+       }
+-      list_for_each_entry(dest, &net_ipvs(net)->dest_trash, n_list) {
++      list_for_each_entry(dest, &ipvs->dest_trash, n_list) {
+               __ip_vs_dev_reset(dest, dev);
+       }
+       mutex_unlock(&__ip_vs_mutex);
+@@ -2028,7 +2029,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
                                           "      %-7s %-6d %-10d %-10d\n",
                                           &dest->addr.in6,
                                           ntohs(dest->port),
@@ -75713,7 +76741,7 @@ index f558998..9cdff60 100644
                                           atomic_read(&dest->weight),
                                           atomic_read(&dest->activeconns),
                                           atomic_read(&dest->inactconns));
-@@ -2039,7 +2039,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
+@@ -2039,7 +2040,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
                                           "%-7s %-6d %-10d %-10d\n",
                                           ntohl(dest->addr.ip),
                                           ntohs(dest->port),
@@ -75722,7 +76750,7 @@ index f558998..9cdff60 100644
                                           atomic_read(&dest->weight),
                                           atomic_read(&dest->activeconns),
                                           atomic_read(&dest->inactconns));
-@@ -2509,7 +2509,7 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get,
+@@ -2509,7 +2510,7 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get,
  
                        entry.addr = dest->addr.ip;
                        entry.port = dest->port;
@@ -75731,7 +76759,7 @@ index f558998..9cdff60 100644
                        entry.weight = atomic_read(&dest->weight);
                        entry.u_threshold = dest->u_threshold;
                        entry.l_threshold = dest->l_threshold;
-@@ -3042,7 +3042,7 @@ static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest)
+@@ -3042,7 +3043,7 @@ static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest)
        NLA_PUT_U16(skb, IPVS_DEST_ATTR_PORT, dest->port);
  
        NLA_PUT_U32(skb, IPVS_DEST_ATTR_FWD_METHOD,
@@ -76465,6 +77493,36 @@ index 7635107..4670276 100644
        _proto("Tx RESPONSE %%%u", ntohl(hdr->serial));
  
        ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 3, len);
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 80f71af..be772c0 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -736,15 +736,12 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
+       epb = &ep->base;
+-      if (hlist_unhashed(&epb->node))
+-              return;
+-
+       epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
+       head = &sctp_ep_hashtable[epb->hashent];
+       sctp_write_lock(&head->lock);
+-      __hlist_del(&epb->node);
++      hlist_del_init(&epb->node);
+       sctp_write_unlock(&head->lock);
+ }
+@@ -825,7 +822,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc)
+       head = &sctp_assoc_hashtable[epb->hashent];
+       sctp_write_lock(&head->lock);
+-      __hlist_del(&epb->node);
++      hlist_del_init(&epb->node);
+       sctp_write_unlock(&head->lock);
+ }
 diff --git a/net/sctp/proc.c b/net/sctp/proc.c
 index 1e2eee8..ce3967e 100644
 --- a/net/sctp/proc.c
@@ -76480,10 +77538,38 @@ index 1e2eee8..ce3967e 100644
                           assoc->assoc_id,
                           assoc->sndbuf_used,
 diff --git a/net/sctp/socket.c b/net/sctp/socket.c
-index 92ba71d..9a97902 100644
+index 92ba71d..9352c05 100644
 --- a/net/sctp/socket.c
 +++ b/net/sctp/socket.c
-@@ -4569,7 +4569,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
+@@ -1231,8 +1231,14 @@ out_free:
+       SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p"
+                         " kaddrs: %p err: %d\n",
+                         asoc, kaddrs, err);
+-      if (asoc)
++      if (asoc) {
++              /* sctp_primitive_ASSOCIATE may have added this association
++               * To the hash table, try to unhash it, just in case, its a noop
++               * if it wasn't hashed so we're safe
++               */
++              sctp_unhash_established(asoc);
+               sctp_association_free(asoc);
++      }
+       return err;
+ }
+@@ -1942,8 +1948,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
+       goto out_unlock;
+ out_free:
+-      if (new_asoc)
++      if (new_asoc) {
++              sctp_unhash_established(asoc);
+               sctp_association_free(asoc);
++      }
+ out_unlock:
+       sctp_release_sock(sk);
+@@ -4569,7 +4577,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
                addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
                if (space_left < addrlen)
                        return -ENOMEM;
@@ -77456,7 +78542,7 @@ index 44ddaa5..a3119bd 100644
        sprintf(alias, "dmi*");
  
 diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
-index c4e7d15..4241aef 100644
+index c4e7d15..dad16c1 100644
 --- a/scripts/mod/modpost.c
 +++ b/scripts/mod/modpost.c
 @@ -922,6 +922,7 @@ enum mismatch {
@@ -77498,12 +78584,12 @@ index c4e7d15..4241aef 100644
                free(prl_to);
                break;
 +      case DATA_TO_TEXT:
-+/*
++#if 0
 +              fprintf(stderr,
-+              "The variable %s references\n"
-+              "the %s %s%s%s\n",
-+              fromsym, to, sec2annotation(tosec), tosym, to_p);
-+*/
++              "The %s %s:%s references\n"
++              "the %s %s:%s%s\n",
++              from, fromsec, fromsym, to, tosec, tosym, to_p);
++#endif
 +              break;
        }
        fprintf(stderr, "\n");
@@ -77602,19 +78688,42 @@ index 5c11312..72742b5 100644
      write_hex_cnt = 0;
      for (i = 0; i < logo_clutsize; i++) {
 diff --git a/security/Kconfig b/security/Kconfig
-index ccc61f8..3334dd6 100644
+index ccc61f8..5e68d73 100644
 --- a/security/Kconfig
 +++ b/security/Kconfig
-@@ -4,6 +4,849 @@
+@@ -4,6 +4,875 @@
  
  menu "Security options"
  
 +menu "Grsecurity"
 +
++      config ARCH_TRACK_EXEC_LIMIT
++      bool
++
++      config PAX_KERNEXEC_PLUGIN
++      bool
++
++      config PAX_PER_CPU_PGD
++      bool
++
++      config TASK_SIZE_MAX_SHIFT
++      int
++      depends on X86_64
++      default 47 if !PAX_PER_CPU_PGD
++      default 42 if PAX_PER_CPU_PGD
++
++      config PAX_ENABLE_PAE
++      bool
++      default y if (X86_32 && (MPENTIUM4 || MK8 || MPSC || MCORE2 || MATOM))
++      
++      config PAX_USERCOPY_SLABS
++      bool
++
 +config GRKERNSEC
 +      bool "Grsecurity"
 +      select CRYPTO
 +      select CRYPTO_SHA256
++      select STOP_MACHINE
 +      help
 +        If you say Y here, you will be able to configure many features
 +        that will enhance the security of your system.  It is highly
@@ -77781,6 +78890,7 @@ index ccc61f8..3334dd6 100644
 +
 +config GRKERNSEC_TPE_GID
 +      int "GID for untrusted users"
++      depends on GRKERNSEC_CONFIG_SERVER
 +      default 1005
 +      help
 +        Setting this GID determines which group untrusted users should
@@ -77789,6 +78899,16 @@ index ccc61f8..3334dd6 100644
 +        The users will only be able to execute binaries in directories owned and
 +        writable only by the root user.
 +
++config GRKERNSEC_SYMLINKOWN_GID
++        int "GID for users with kernel-enforced SymlinksIfOwnerMatch"
++        depends on GRKERNSEC_CONFIG_SERVER
++        default 1006
++        help
++          Setting this GID determines what group kernel-enforced
++          SymlinksIfOwnerMatch will be enabled for.  If the sysctl option
++          is enabled, a sysctl option with name "symlinkown_gid" is created.
++
++
 +endmenu
 +
 +menu "Customize Configuration"
@@ -77796,25 +78916,6 @@ index ccc61f8..3334dd6 100644
 +
 +menu "PaX"
 +
-+      config ARCH_TRACK_EXEC_LIMIT
-+      bool
-+
-+      config PAX_KERNEXEC_PLUGIN
-+      bool
-+
-+      config PAX_PER_CPU_PGD
-+      bool
-+
-+      config TASK_SIZE_MAX_SHIFT
-+      int
-+      depends on X86_64
-+      default 47 if !PAX_PER_CPU_PGD
-+      default 42 if PAX_PER_CPU_PGD
-+
-+      config PAX_ENABLE_PAE
-+      bool
-+      default y if (X86_32 && (MPENTIUM4 || MK8 || MPSC || MCORE2 || MATOM))
-+      
 +config PAX
 +      bool "Enable various PaX features"
 +      default y if GRKERNSEC_CONFIG_AUTO
@@ -77852,13 +78953,12 @@ index ccc61f8..3334dd6 100644
 +        has been deprecated in favour of PT_PAX_FLAGS and XATTR_PAX_FLAGS
 +        support.
 +
-+        If you have applications not marked by the PT_PAX_FLAGS ELF program
-+        header and you cannot use XATTR_PAX_FLAGS then you MUST enable this
-+        option otherwise they will not get any protection.
-+
 +        Note that if you enable PT_PAX_FLAGS or XATTR_PAX_FLAGS marking
 +        support as well, they will override the legacy EI_PAX marks.
 +
++        If you enable none of the marking options then all applications
++        will run with PaX enabled on them by default.
++
 +config PAX_PT_PAX_FLAGS
 +      bool 'Use ELF program header marking'
 +      default y if GRKERNSEC_CONFIG_AUTO
@@ -77871,15 +78971,14 @@ index ccc61f8..3334dd6 100644
 +        integrated into the toolchain (the binutils patch is available
 +        from http://pax.grsecurity.net).
 +
-+        If you have applications not marked by the PT_PAX_FLAGS ELF program
-+        header then you MUST enable either XATTR_PAX_FLAGS or EI_PAX marking
-+        support otherwise they will not get any protection.
++        Note that if you enable the legacy EI_PAX marking support as well,
++        the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
 +
 +        If you enable both PT_PAX_FLAGS and XATTR_PAX_FLAGS support then you
 +        must make sure that the marks are the same if a binary has both marks.
 +
-+        Note that if you enable the legacy EI_PAX marking support as well,
-+        the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
++        If you enable none of the marking options then all applications
++        will run with PaX enabled on them by default.
 +
 +config PAX_XATTR_PAX_FLAGS
 +      bool 'Use filesystem extended attributes marking'
@@ -77904,15 +79003,14 @@ index ccc61f8..3334dd6 100644
 +        isofs, udf, vfat) so copying files through such filesystems will
 +        lose the extended attributes and these PaX markings.
 +
-+        If you have applications not marked by the PT_PAX_FLAGS ELF program
-+        header then you MUST enable either XATTR_PAX_FLAGS or EI_PAX marking
-+        support otherwise they will not get any protection.
++        Note that if you enable the legacy EI_PAX marking support as well,
++        the EI_PAX marks will be overridden by the XATTR_PAX_FLAGS marks.
 +
 +        If you enable both PT_PAX_FLAGS and XATTR_PAX_FLAGS support then you
 +        must make sure that the marks are the same if a binary has both marks.
 +
-+        Note that if you enable the legacy EI_PAX marking support as well,
-+        the EI_PAX marks will be overridden by the XATTR_PAX_FLAGS marks.
++        If you enable none of the marking options then all applications
++        will run with PaX enabled on them by default.
 +
 +choice
 +      prompt 'MAC system integration'
@@ -78402,6 +79500,7 @@ index ccc61f8..3334dd6 100644
 +      default y if GRKERNSEC_CONFIG_AUTO
 +      depends on X86 || PPC || SPARC || ARM
 +      depends on GRKERNSEC && (SLAB || SLUB || SLOB)
++      select PAX_USERCOPY_SLABS
 +      help
 +        By saying Y here the kernel will enforce the size of heap objects
 +        when they are copied in either direction between the kernel and
@@ -78442,6 +79541,19 @@ index ccc61f8..3334dd6 100644
 +        Homepage:
 +        http://www.grsecurity.net/~ephox/overflow_plugin/
 +
++config PAX_LATENT_ENTROPY
++      bool "Generate some entropy during boot"
++      default y if GRKERNSEC_CONFIG_AUTO
++      help
++        By saying Y here the kernel will instrument early boot code to
++        extract some entropy from both original and artificially created
++        program state.  This will help especially embedded systems where
++        there is little 'natural' source of entropy normally.  The cost
++        is some slowdown of the boot process.
++
++        Note that entropy extracted this way is not cryptographically
++        secure!
++
 +endmenu
 +
 +endmenu
@@ -78455,7 +79567,7 @@ index ccc61f8..3334dd6 100644
  config KEYS
        bool "Enable access key retention support"
        help
-@@ -169,7 +1012,7 @@ config INTEL_TXT
+@@ -169,7 +1038,7 @@ config INTEL_TXT
  config LSM_MMAP_MIN_ADDR
        int "Low address space for LSM to protect from user allocation"
        depends on SECURITY && SECURITY_SELINUX
@@ -79319,12 +80431,19 @@ index da5fa1a..113cd02 100644
        int last_frame_number;          /* stored frame number */
        int last_delay;                 /* stored delay */
  };
+diff --git a/tools/gcc/.gitignore b/tools/gcc/.gitignore
+new file mode 100644
+index 0000000..50f2f2f
+--- /dev/null
++++ b/tools/gcc/.gitignore
+@@ -0,0 +1 @@
++size_overflow_hash.h
 diff --git a/tools/gcc/Makefile b/tools/gcc/Makefile
 new file mode 100644
-index 0000000..f4f9986
+index 0000000..1d09b7e
 --- /dev/null
 +++ b/tools/gcc/Makefile
-@@ -0,0 +1,41 @@
+@@ -0,0 +1,43 @@
 +#CC := gcc
 +#PLUGIN_SOURCE_FILES := pax_plugin.c
 +#PLUGIN_OBJECT_FILES := $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES))
@@ -79346,6 +80465,7 @@ index 0000000..f4f9986
 +$(HOSTLIBS)-$(CONFIG_CHECKER_PLUGIN) += checker_plugin.so
 +$(HOSTLIBS)-y += colorize_plugin.so
 +$(HOSTLIBS)-$(CONFIG_PAX_SIZE_OVERFLOW) += size_overflow_plugin.so
++$(HOSTLIBS)-$(CONFIG_PAX_LATENT_ENTROPY) += latent_entropy_plugin.so
 +
 +always := $($(HOSTLIBS)-y)
 +
@@ -79356,6 +80476,7 @@ index 0000000..f4f9986
 +checker_plugin-objs := checker_plugin.o
 +colorize_plugin-objs := colorize_plugin.o
 +size_overflow_plugin-objs := size_overflow_plugin.o
++latent_entropy_plugin-objs := latent_entropy_plugin.o
 +
 +$(obj)/size_overflow_plugin.o: $(objtree)/$(obj)/size_overflow_hash.h
 +
@@ -79545,7 +80666,7 @@ index 0000000..d41b5af
 +}
 diff --git a/tools/gcc/colorize_plugin.c b/tools/gcc/colorize_plugin.c
 new file mode 100644
-index 0000000..7a5e311
+index 0000000..846aeb0
 --- /dev/null
 +++ b/tools/gcc/colorize_plugin.c
 @@ -0,0 +1,148 @@
@@ -79683,7 +80804,7 @@ index 0000000..7a5e311
 +      struct register_pass_info colorize_rearm_pass_info = {
 +              .pass                           = &pass_ipa_colorize_rearm.pass,
 +              .reference_pass_name            = "*free_lang_data",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_AFTER
 +      };
 +
@@ -79699,7 +80820,7 @@ index 0000000..7a5e311
 +}
 diff --git a/tools/gcc/constify_plugin.c b/tools/gcc/constify_plugin.c
 new file mode 100644
-index 0000000..89b7f56
+index 0000000..048d4ff
 --- /dev/null
 +++ b/tools/gcc/constify_plugin.c
 @@ -0,0 +1,328 @@
@@ -80005,7 +81126,7 @@ index 0000000..89b7f56
 +      struct register_pass_info local_variable_pass_info = {
 +              .pass                           = &pass_local_variable.pass,
 +              .reference_pass_name            = "*referenced_vars",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_AFTER
 +      };
 +
@@ -80133,7 +81254,7 @@ index 0000000..a0fe8b2
 +exit 0
 diff --git a/tools/gcc/kallocstat_plugin.c b/tools/gcc/kallocstat_plugin.c
 new file mode 100644
-index 0000000..a5eabce
+index 0000000..a86e422
 --- /dev/null
 +++ b/tools/gcc/kallocstat_plugin.c
 @@ -0,0 +1,167 @@
@@ -80290,7 +81411,7 @@ index 0000000..a5eabce
 +      struct register_pass_info kallocstat_pass_info = {
 +              .pass                           = &kallocstat_pass.pass,
 +              .reference_pass_name            = "ssa",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_AFTER
 +      };
 +
@@ -80306,7 +81427,7 @@ index 0000000..a5eabce
 +}
 diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
 new file mode 100644
-index 0000000..d8a8da2
+index 0000000..98011fa
 --- /dev/null
 +++ b/tools/gcc/kernexec_plugin.c
 @@ -0,0 +1,427 @@
@@ -80682,19 +81803,19 @@ index 0000000..d8a8da2
 +      struct register_pass_info kernexec_reload_pass_info = {
 +              .pass                           = &kernexec_reload_pass.pass,
 +              .reference_pass_name            = "ssa",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_AFTER
 +      };
 +      struct register_pass_info kernexec_fptr_pass_info = {
 +              .pass                           = &kernexec_fptr_pass.pass,
 +              .reference_pass_name            = "ssa",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_AFTER
 +      };
 +      struct register_pass_info kernexec_retaddr_pass_info = {
 +              .pass                           = &kernexec_retaddr_pass.pass,
 +              .reference_pass_name            = "pro_and_epilogue",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_AFTER
 +      };
 +
@@ -80737,6 +81858,307 @@ index 0000000..d8a8da2
 +
 +      return 0;
 +}
+diff --git a/tools/gcc/latent_entropy_plugin.c b/tools/gcc/latent_entropy_plugin.c
+new file mode 100644
+index 0000000..b8008f7
+--- /dev/null
++++ b/tools/gcc/latent_entropy_plugin.c
+@@ -0,0 +1,295 @@
++/*
++ * Copyright 2012 by the PaX Team <pageexec@freemail.hu>
++ * Licensed under the GPL v2
++ *
++ * Note: the choice of the license means that the compilation process is
++ *       NOT 'eligible' as defined by gcc's library exception to the GPL v3,
++ *       but for the kernel it doesn't matter since it doesn't link against
++ *       any of the gcc libraries
++ *
++ * gcc plugin to help generate a little bit of entropy from program state,
++ * used during boot in the kernel
++ *
++ * TODO:
++ * - add ipa pass to identify not explicitly marked candidate functions
++ * - mix in more program state (function arguments/return values, loop variables, etc)
++ * - more instrumentation control via attribute parameters
++ *
++ * BUGS:
++ * - LTO needs -flto-partition=none for now
++ */
++#include "gcc-plugin.h"
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tree.h"
++#include "tree-pass.h"
++#include "flags.h"
++#include "intl.h"
++#include "toplev.h"
++#include "plugin.h"
++//#include "expr.h" where are you...
++#include "diagnostic.h"
++#include "plugin-version.h"
++#include "tm.h"
++#include "function.h"
++#include "basic-block.h"
++#include "gimple.h"
++#include "rtl.h"
++#include "emit-rtl.h"
++#include "tree-flow.h"
++
++int plugin_is_GPL_compatible;
++
++static tree latent_entropy_decl;
++
++static struct plugin_info latent_entropy_plugin_info = {
++      .version        = "201207271820",
++      .help           = NULL
++};
++
++static unsigned int execute_latent_entropy(void);
++static bool gate_latent_entropy(void);
++
++static struct gimple_opt_pass latent_entropy_pass = {
++      .pass = {
++              .type                   = GIMPLE_PASS,
++              .name                   = "latent_entropy",
++              .gate                   = gate_latent_entropy,
++              .execute                = execute_latent_entropy,
++              .sub                    = NULL,
++              .next                   = NULL,
++              .static_pass_number     = 0,
++              .tv_id                  = TV_NONE,
++              .properties_required    = PROP_gimple_leh | PROP_cfg,
++              .properties_provided    = 0,
++              .properties_destroyed   = 0,
++              .todo_flags_start       = 0, //TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts,
++              .todo_flags_finish      = TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_update_ssa
++      }
++};
++
++static tree handle_latent_entropy_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
++{
++      if (TREE_CODE(*node) != FUNCTION_DECL) {
++              *no_add_attrs = true;
++              error("%qE attribute only applies to functions", name);
++      }
++      return NULL_TREE;
++}
++
++static struct attribute_spec latent_entropy_attr = {
++      .name                           = "latent_entropy",
++      .min_length                     = 0,
++      .max_length                     = 0,
++      .decl_required                  = true,
++      .type_required                  = false,
++      .function_type_required         = false,
++      .handler                        = handle_latent_entropy_attribute,
++#if BUILDING_GCC_VERSION >= 4007
++      .affects_type_identity          = false
++#endif
++};
++
++static void register_attributes(void *event_data, void *data)
++{
++      register_attribute(&latent_entropy_attr);
++}
++
++static bool gate_latent_entropy(void)
++{
++      tree latent_entropy_attr;
++
++      latent_entropy_attr = lookup_attribute("latent_entropy", DECL_ATTRIBUTES(current_function_decl));
++      return latent_entropy_attr != NULL_TREE;
++}
++
++static unsigned HOST_WIDE_INT seed;
++static unsigned HOST_WIDE_INT get_random_const(void)
++{
++      seed = (seed >> 1U) ^ (-(seed & 1ULL) & 0xD800000000000000ULL);
++      return seed;
++}
++
++static enum tree_code get_op(tree *rhs)
++{
++      static enum tree_code op;
++      unsigned HOST_WIDE_INT random_const;
++
++      random_const = get_random_const();
++
++      switch (op) {
++      case BIT_XOR_EXPR:
++              op = PLUS_EXPR;
++              break;
++
++      case PLUS_EXPR:
++              if (rhs) {
++                      op = LROTATE_EXPR;
++                      random_const &= HOST_BITS_PER_WIDE_INT - 1;
++                      break;
++              }
++
++      case LROTATE_EXPR:
++      default:
++              op = BIT_XOR_EXPR;
++              break;
++      }
++      if (rhs)
++              *rhs = build_int_cstu(unsigned_intDI_type_node, random_const);
++      return op;
++}
++
++static void perturb_local_entropy(basic_block bb, tree local_entropy)
++{
++      gimple_stmt_iterator gsi;
++      gimple assign;
++      tree addxorrol, rhs;
++      enum tree_code op;
++
++      op = get_op(&rhs);
++      addxorrol = fold_build2_loc(UNKNOWN_LOCATION, op, unsigned_intDI_type_node, local_entropy, rhs);
++      assign = gimple_build_assign(local_entropy, addxorrol);
++      find_referenced_vars_in(assign);
++//debug_bb(bb);
++      gsi = gsi_after_labels(bb);
++      gsi_insert_before(&gsi, assign, GSI_NEW_STMT);
++      update_stmt(assign);
++}
++
++static void perturb_latent_entropy(basic_block bb, tree rhs)
++{
++      gimple_stmt_iterator gsi;
++      gimple assign;
++      tree addxorrol, temp;
++
++      // 1. create temporary copy of latent_entropy
++      temp = create_tmp_var(unsigned_intDI_type_node, "temp_latent_entropy");
++      add_referenced_var(temp);
++      mark_sym_for_renaming(temp);
++
++      // 2. read...
++      assign = gimple_build_assign(temp, latent_entropy_decl);
++      find_referenced_vars_in(assign);
++      gsi = gsi_after_labels(bb);
++      gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
++      update_stmt(assign);
++
++      // 3. ...modify...
++      addxorrol = fold_build2_loc(UNKNOWN_LOCATION, get_op(NULL), unsigned_intDI_type_node, temp, rhs);
++      assign = gimple_build_assign(temp, addxorrol);
++      find_referenced_vars_in(assign);
++      gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
++      update_stmt(assign);
++
++      // 4. ...write latent_entropy
++      assign = gimple_build_assign(latent_entropy_decl, temp);
++      find_referenced_vars_in(assign);
++      gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
++      update_stmt(assign);
++}
++
++static unsigned int execute_latent_entropy(void)
++{
++      basic_block bb;
++      gimple assign;
++      gimple_stmt_iterator gsi;
++      tree local_entropy;
++
++      if (!latent_entropy_decl) {
++              struct varpool_node *node;
++
++              for (node = varpool_nodes; node; node = node->next) {
++                      tree var = node->decl;
++                      if (strcmp(IDENTIFIER_POINTER(DECL_NAME(var)), "latent_entropy"))
++                              continue;
++                      latent_entropy_decl = var;
++//                    debug_tree(var);
++                      break;
++              }
++              if (!latent_entropy_decl) {
++//                    debug_tree(current_function_decl);
++                      return 0;
++              }
++      }
++
++//fprintf(stderr, "latent_entropy: %s\n", IDENTIFIER_POINTER(DECL_NAME(current_function_decl)));
++
++      // 1. create local entropy variable
++      local_entropy = create_tmp_var(unsigned_intDI_type_node, "local_entropy");
++      add_referenced_var(local_entropy);
++      mark_sym_for_renaming(local_entropy);
++
++      // 2. initialize local entropy variable
++      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);
++      gsi = gsi_start_bb(bb);
++
++      assign = gimple_build_assign(local_entropy, build_int_cstu(unsigned_intDI_type_node, get_random_const()));
++//    gimple_set_location(assign, loc);
++      find_referenced_vars_in(assign);
++      gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
++      update_stmt(assign);
++      bb = bb->next_bb;
++
++      // 3. instrument each BB with an operation on the local entropy variable
++      while (bb != EXIT_BLOCK_PTR) {
++              perturb_local_entropy(bb, local_entropy);
++              bb = bb->next_bb;
++      };
++
++      // 4. mix local entropy into the global entropy variable
++      perturb_latent_entropy(EXIT_BLOCK_PTR->prev_bb, local_entropy);
++      return 0;
++}
++
++static void start_unit_callback(void *gcc_data, void *user_data)
++{
++#if BUILDING_GCC_VERSION >= 4007
++      seed = get_random_seed(false);
++#else
++      sscanf(get_random_seed(false), "%" HOST_WIDE_INT_PRINT "x", &seed);
++      seed *= seed;
++#endif
++
++      if (in_lto_p)
++              return;
++
++      // extern u64 latent_entropy
++      latent_entropy_decl = build_decl(UNKNOWN_LOCATION, VAR_DECL, get_identifier("latent_entropy"), unsigned_intDI_type_node);
++
++      TREE_STATIC(latent_entropy_decl) = 1;
++      TREE_PUBLIC(latent_entropy_decl) = 1;
++      TREE_USED(latent_entropy_decl) = 1;
++      TREE_THIS_VOLATILE(latent_entropy_decl) = 1;
++      DECL_EXTERNAL(latent_entropy_decl) = 1;
++      DECL_ARTIFICIAL(latent_entropy_decl) = 0;
++      DECL_INITIAL(latent_entropy_decl) = NULL;
++//    DECL_ASSEMBLER_NAME(latent_entropy_decl);
++//    varpool_finalize_decl(latent_entropy_decl);
++//    varpool_mark_needed_node(latent_entropy_decl);
++}
++
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
++{
++      const char * const plugin_name = plugin_info->base_name;
++      struct register_pass_info latent_entropy_pass_info = {
++              .pass                           = &latent_entropy_pass.pass,
++              .reference_pass_name            = "optimized",
++              .ref_pass_instance_number       = 1,
++              .pos_op                         = PASS_POS_INSERT_BEFORE
++      };
++
++      if (!plugin_default_version_check(version, &gcc_version)) {
++              error(G_("incompatible gcc/plugin versions"));
++              return 1;
++      }
++
++      register_callback(plugin_name, PLUGIN_INFO, NULL, &latent_entropy_plugin_info);
++      register_callback ("start_unit", PLUGIN_START_UNIT, &start_unit_callback, NULL);
++      register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &latent_entropy_pass_info);
++      register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
++
++      return 0;
++}
 diff --git a/tools/gcc/size_overflow_hash.data b/tools/gcc/size_overflow_hash.data
 new file mode 100644
 index 0000000..daaa86c
@@ -84441,7 +85863,7 @@ index 0000000..cc96254
 +}
 diff --git a/tools/gcc/stackleak_plugin.c b/tools/gcc/stackleak_plugin.c
 new file mode 100644
-index 0000000..b87ec9d
+index 0000000..38d2014
 --- /dev/null
 +++ b/tools/gcc/stackleak_plugin.c
 @@ -0,0 +1,313 @@
@@ -84714,13 +86136,13 @@ index 0000000..b87ec9d
 +              .pass                           = &stackleak_tree_instrument_pass.pass,
 +//            .reference_pass_name            = "tree_profile",
 +              .reference_pass_name            = "optimized",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_BEFORE
 +      };
 +      struct register_pass_info stackleak_final_pass_info = {
 +              .pass                           = &stackleak_final_rtl_opt_pass.pass,
 +              .reference_pass_name            = "final",
-+              .ref_pass_instance_number       = 0,
++              .ref_pass_instance_number       = 1,
 +              .pos_op                         = PASS_POS_INSERT_BEFORE
 +      };
 +