aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2010-09-21 08:05:47 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2010-09-23 07:33:08 +0000
commit7c8d35f2905e71cf4ba9a32d114e977f6cd5cb8e (patch)
tree27c69f4124334359fc97c358bc0ca80b54940e3b
parentdc3b31374eb4d07c868009154c9eb55e6d4c3869 (diff)
downloadaports-7c8d35f2905e71cf4ba9a32d114e977f6cd5cb8e.tar.bz2
aports-7c8d35f2905e71cf4ba9a32d114e977f6cd5cb8e.tar.xz
main/linux-grsec: upgrade to grsecurity-2.2.0-2.6.32.21-201009201707
(cherry picked from commit 57badfc9c28f37a6d7c99a0627e93151509c800e)
-rw-r--r--main/linux-grsec/APKBUILD6
-rw-r--r--main/linux-grsec/grsecurity-2.2.0-2.6.32.21-201009201707.patch (renamed from main/linux-grsec/grsecurity-2.2.0-2.6.32.21-201009162222.patch)1294
2 files changed, 963 insertions, 337 deletions
diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD
index fa82881362..ece603c862 100644
--- a/main/linux-grsec/APKBUILD
+++ b/main/linux-grsec/APKBUILD
@@ -4,7 +4,7 @@ _flavor=grsec
pkgname=linux-${_flavor}
pkgver=2.6.32.21
_kernver=2.6.32
-pkgrel=5
+pkgrel=6
pkgdesc="Linux kernel with grsecurity"
url=http://grsecurity.net
depends="mkinitfs linux-firmware"
@@ -14,7 +14,7 @@ _config=${config:-kernelconfig.${CARCH:-x86}}
install=
source="ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-$_kernver.tar.bz2
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/patch-$pkgver.bz2
- grsecurity-2.2.0-2.6.32.21-201009162222.patch
+ grsecurity-2.2.0-2.6.32.21-201009201707.patch
0001-grsec-revert-conflicting-flow-cache-changes.patch
0002-gre-fix-hard-header-destination-address-checking.patch
0003-ip_gre-include-route-header_len-in-max_headroom-calc.patch
@@ -151,7 +151,7 @@ firmware() {
md5sums="260551284ac224c3a43c4adac7df4879 linux-2.6.32.tar.bz2
29aa10a231882a6e52908642b572326f patch-2.6.32.21.bz2
-b5d2449d17fb6a4d0433264b6a4de5f7 grsecurity-2.2.0-2.6.32.21-201009162222.patch
+a9512a62a10f22fa6a065dadcd538203 grsecurity-2.2.0-2.6.32.21-201009201707.patch
1d247140abec49b96250aec9aa59b324 0001-grsec-revert-conflicting-flow-cache-changes.patch
437317f88ec13ace8d39c31983a41696 0002-gre-fix-hard-header-destination-address-checking.patch
151b29a161178ed39d62a08f21f3484d 0003-ip_gre-include-route-header_len-in-max_headroom-calc.patch
diff --git a/main/linux-grsec/grsecurity-2.2.0-2.6.32.21-201009162222.patch b/main/linux-grsec/grsecurity-2.2.0-2.6.32.21-201009201707.patch
index 4ed5e67282..6b08644fe9 100644
--- a/main/linux-grsec/grsecurity-2.2.0-2.6.32.21-201009162222.patch
+++ b/main/linux-grsec/grsecurity-2.2.0-2.6.32.21-201009201707.patch
@@ -50,7 +50,16 @@ diff -urNp linux-2.6.32.21/arch/alpha/kernel/module.c linux-2.6.32.21/arch/alpha
for (i = 0; i < n; i++) {
diff -urNp linux-2.6.32.21/arch/alpha/kernel/osf_sys.c linux-2.6.32.21/arch/alpha/kernel/osf_sys.c
--- linux-2.6.32.21/arch/alpha/kernel/osf_sys.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/alpha/kernel/osf_sys.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/alpha/kernel/osf_sys.c 2010-09-17 18:34:04.000000000 -0400
+@@ -1169,7 +1169,7 @@ arch_get_unmapped_area_1(unsigned long a
+ /* At this point: (!vma || addr < vma->vm_end). */
+ if (limit - len < addr)
+ return -ENOMEM;
+- if (!vma || addr + len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ return addr;
+ addr = vma->vm_end;
+ vma = vma->vm_next;
@@ -1205,6 +1205,10 @@ arch_get_unmapped_area(struct file *filp
merely specific addresses, but regions of memory -- perhaps
this feature should be incorporated into all ports? */
@@ -446,7 +455,7 @@ diff -urNp linux-2.6.32.21/arch/arm/mm/fault.c linux-2.6.32.21/arch/arm/mm/fault
*
diff -urNp linux-2.6.32.21/arch/arm/mm/mmap.c linux-2.6.32.21/arch/arm/mm/mmap.c
--- linux-2.6.32.21/arch/arm/mm/mmap.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/arm/mm/mmap.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/arm/mm/mmap.c 2010-09-17 18:34:04.000000000 -0400
@@ -63,6 +63,10 @@ arch_get_unmapped_area(struct file *filp
if (len > TASK_SIZE)
return -ENOMEM;
@@ -458,7 +467,13 @@ diff -urNp linux-2.6.32.21/arch/arm/mm/mmap.c linux-2.6.32.21/arch/arm/mm/mmap.c
if (addr) {
if (do_align)
addr = COLOUR_ALIGN(addr, pgoff);
-@@ -75,10 +79,10 @@ arch_get_unmapped_area(struct file *filp
+@@ -70,15 +74,14 @@ arch_get_unmapped_area(struct file *filp
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
return addr;
}
if (len > mm->cached_hole_size) {
@@ -472,7 +487,7 @@ diff -urNp linux-2.6.32.21/arch/arm/mm/mmap.c linux-2.6.32.21/arch/arm/mm/mmap.c
}
full_search:
-@@ -94,8 +98,8 @@ full_search:
+@@ -94,14 +97,14 @@ full_search:
* Start a new search - just in case we missed
* some holes.
*/
@@ -483,6 +498,13 @@ diff -urNp linux-2.6.32.21/arch/arm/mm/mmap.c linux-2.6.32.21/arch/arm/mm/mmap.c
mm->cached_hole_size = 0;
goto full_search;
}
+ return -ENOMEM;
+ }
+- if (!vma || addr + len <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr, len)) {
+ /*
+ * Remember the place where we stopped the search:
+ */
diff -urNp linux-2.6.32.21/arch/arm/plat-s3c/pm.c linux-2.6.32.21/arch/arm/plat-s3c/pm.c
--- linux-2.6.32.21/arch/arm/plat-s3c/pm.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/arch/arm/plat-s3c/pm.c 2010-09-04 15:54:51.000000000 -0400
@@ -618,6 +640,37 @@ diff -urNp linux-2.6.32.21/arch/frv/include/asm/kmap_types.h linux-2.6.32.21/arc
KM_TYPE_NR
};
+diff -urNp linux-2.6.32.21/arch/frv/mm/elf-fdpic.c linux-2.6.32.21/arch/frv/mm/elf-fdpic.c
+--- linux-2.6.32.21/arch/frv/mm/elf-fdpic.c 2010-08-13 16:24:37.000000000 -0400
++++ linux-2.6.32.21/arch/frv/mm/elf-fdpic.c 2010-09-17 18:34:04.000000000 -0400
+@@ -73,8 +73,7 @@ unsigned long arch_get_unmapped_area(str
+ if (addr) {
+ addr = PAGE_ALIGN(addr);
+ vma = find_vma(current->mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
+ goto success;
+ }
+
+@@ -89,7 +88,7 @@ unsigned long arch_get_unmapped_area(str
+ for (; vma; vma = vma->vm_next) {
+ if (addr > limit)
+ break;
+- if (addr + len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ goto success;
+ addr = vma->vm_end;
+ }
+@@ -104,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
+ for (; vma; vma = vma->vm_next) {
+ if (addr > limit)
+ break;
+- if (addr + len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ goto success;
+ addr = vma->vm_end;
+ }
diff -urNp linux-2.6.32.21/arch/ia64/hp/common/hwsw_iommu.c linux-2.6.32.21/arch/ia64/hp/common/hwsw_iommu.c
--- linux-2.6.32.21/arch/ia64/hp/common/hwsw_iommu.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/arch/ia64/hp/common/hwsw_iommu.c 2010-09-04 15:54:51.000000000 -0400
@@ -1023,7 +1076,7 @@ diff -urNp linux-2.6.32.21/arch/ia64/kernel/pci-swiotlb.c linux-2.6.32.21/arch/i
.map_page = swiotlb_map_page,
diff -urNp linux-2.6.32.21/arch/ia64/kernel/sys_ia64.c linux-2.6.32.21/arch/ia64/kernel/sys_ia64.c
--- linux-2.6.32.21/arch/ia64/kernel/sys_ia64.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/ia64/kernel/sys_ia64.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/ia64/kernel/sys_ia64.c 2010-09-17 18:34:04.000000000 -0400
@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
if (REGION_NUMBER(addr) == RGN_HPAGE)
addr = 0;
@@ -1038,7 +1091,7 @@ diff -urNp linux-2.6.32.21/arch/ia64/kernel/sys_ia64.c linux-2.6.32.21/arch/ia64
if (!addr)
addr = mm->free_area_cache;
-@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
+@@ -61,14 +68,14 @@ arch_get_unmapped_area (struct file *fil
for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
/* At this point: (!vma || addr < vma->vm_end). */
if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
@@ -1050,6 +1103,12 @@ diff -urNp linux-2.6.32.21/arch/ia64/kernel/sys_ia64.c linux-2.6.32.21/arch/ia64
goto full_search;
}
return -ENOMEM;
+ }
+- if (!vma || addr + len <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr, len)) {
+ /* Remember the address where we stopped this search: */
+ mm->free_area_cache = addr + len;
+ return addr;
diff -urNp linux-2.6.32.21/arch/ia64/kernel/topology.c linux-2.6.32.21/arch/ia64/kernel/topology.c
--- linux-2.6.32.21/arch/ia64/kernel/topology.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/arch/ia64/kernel/topology.c 2010-09-04 15:54:51.000000000 -0400
@@ -1126,6 +1185,18 @@ diff -urNp linux-2.6.32.21/arch/ia64/mm/fault.c linux-2.6.32.21/arch/ia64/mm/fau
survive:
/*
* If for any reason at all we couldn't handle the fault, make
+diff -urNp linux-2.6.32.21/arch/ia64/mm/hugetlbpage.c linux-2.6.32.21/arch/ia64/mm/hugetlbpage.c
+--- linux-2.6.32.21/arch/ia64/mm/hugetlbpage.c 2010-08-13 16:24:37.000000000 -0400
++++ linux-2.6.32.21/arch/ia64/mm/hugetlbpage.c 2010-09-17 18:34:04.000000000 -0400
+@@ -172,7 +172,7 @@ unsigned long hugetlb_get_unmapped_area(
+ /* At this point: (!vmm || addr < vmm->vm_end). */
+ if (REGION_OFFSET(addr) + len > RGN_MAP_LIMIT)
+ return -ENOMEM;
+- if (!vmm || (addr + len) <= vmm->vm_start)
++ if (check_heap_stack_gap(vmm, addr, len))
+ return addr;
+ addr = ALIGN(vmm->vm_end, HPAGE_SIZE);
+ }
diff -urNp linux-2.6.32.21/arch/ia64/mm/init.c linux-2.6.32.21/arch/ia64/mm/init.c
--- linux-2.6.32.21/arch/ia64/mm/init.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/arch/ia64/mm/init.c 2010-09-04 15:54:51.000000000 -0400
@@ -1312,8 +1383,8 @@ diff -urNp linux-2.6.32.21/arch/mips/kernel/process.c linux-2.6.32.21/arch/mips/
-}
diff -urNp linux-2.6.32.21/arch/mips/kernel/syscall.c linux-2.6.32.21/arch/mips/kernel/syscall.c
--- linux-2.6.32.21/arch/mips/kernel/syscall.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/mips/kernel/syscall.c 2010-09-04 15:54:51.000000000 -0400
-@@ -102,6 +102,11 @@ unsigned long arch_get_unmapped_area(str
++++ linux-2.6.32.21/arch/mips/kernel/syscall.c 2010-09-17 18:34:04.000000000 -0400
+@@ -102,17 +102,21 @@ unsigned long arch_get_unmapped_area(str
do_color_align = 0;
if (filp || (flags & MAP_SHARED))
do_color_align = 1;
@@ -1325,8 +1396,12 @@ diff -urNp linux-2.6.32.21/arch/mips/kernel/syscall.c linux-2.6.32.21/arch/mips/
if (addr) {
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
-@@ -112,7 +117,7 @@ unsigned long arch_get_unmapped_area(str
- (!vmm || addr + len <= vmm->vm_start))
+ else
+ addr = PAGE_ALIGN(addr);
+ vmm = find_vma(current->mm, addr);
+- if (task_size - len >= addr &&
+- (!vmm || addr + len <= vmm->vm_start))
++ if (task_size - len >= addr && check_heap_stack_gap(vmm, addr, len))
return addr;
}
- addr = TASK_UNMAPPED_BASE;
@@ -1334,6 +1409,15 @@ diff -urNp linux-2.6.32.21/arch/mips/kernel/syscall.c linux-2.6.32.21/arch/mips/
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
else
+@@ -122,7 +126,7 @@ unsigned long arch_get_unmapped_area(str
+ /* At this point: (!vmm || addr < vmm->vm_end). */
+ if (task_size - len < addr)
+ return -ENOMEM;
+- if (!vmm || addr + len <= vmm->vm_start)
++ if (check_heap_stack_gap(vmm, addr, len))
+ return addr;
+ addr = vmm->vm_end;
+ if (do_color_align)
diff -urNp linux-2.6.32.21/arch/mips/mm/fault.c linux-2.6.32.21/arch/mips/mm/fault.c
--- linux-2.6.32.21/arch/mips/mm/fault.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/arch/mips/mm/fault.c 2010-09-04 15:54:51.000000000 -0400
@@ -1516,7 +1600,25 @@ diff -urNp linux-2.6.32.21/arch/parisc/kernel/module.c linux-2.6.32.21/arch/pari
me->arch.unwind_section, table, end, gp);
diff -urNp linux-2.6.32.21/arch/parisc/kernel/sys_parisc.c linux-2.6.32.21/arch/parisc/kernel/sys_parisc.c
--- linux-2.6.32.21/arch/parisc/kernel/sys_parisc.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/parisc/kernel/sys_parisc.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/parisc/kernel/sys_parisc.c 2010-09-17 18:34:04.000000000 -0400
+@@ -43,7 +43,7 @@ static unsigned long get_unshared_area(u
+ /* At this point: (!vma || addr < vma->vm_end). */
+ if (TASK_SIZE - len < addr)
+ return -ENOMEM;
+- if (!vma || addr + len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ return addr;
+ addr = vma->vm_end;
+ }
+@@ -79,7 +79,7 @@ static unsigned long get_shared_area(str
+ /* At this point: (!vma || addr < vma->vm_end). */
+ if (TASK_SIZE - len < addr)
+ return -ENOMEM;
+- if (!vma || addr + len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ return addr;
+ addr = DCACHE_ALIGN(vma->vm_end - offset) + offset;
+ if (addr < vma->vm_end) /* handle wraparound */
@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
if (flags & MAP_FIXED)
return addr;
@@ -2671,8 +2773,38 @@ diff -urNp linux-2.6.32.21/arch/powerpc/mm/mmap_64.c linux-2.6.32.21/arch/powerp
}
diff -urNp linux-2.6.32.21/arch/powerpc/mm/slice.c linux-2.6.32.21/arch/powerpc/mm/slice.c
--- linux-2.6.32.21/arch/powerpc/mm/slice.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/powerpc/mm/slice.c 2010-09-04 15:54:51.000000000 -0400
-@@ -426,6 +426,11 @@ unsigned long slice_get_unmapped_area(un
++++ linux-2.6.32.21/arch/powerpc/mm/slice.c 2010-09-17 18:34:04.000000000 -0400
+@@ -98,10 +98,9 @@ static int slice_area_is_free(struct mm_
+ if ((mm->task_size - len) < addr)
+ return 0;
+ vma = find_vma(mm, addr);
+- return (!vma || (addr + len) <= vma->vm_start);
++ return check_heap_stack_gap(vma, addr, len);
+ }
+
+-static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)
+ {
+ return !slice_area_is_free(mm, slice << SLICE_LOW_SHIFT,
+ 1ul << SLICE_LOW_SHIFT);
+@@ -256,7 +255,7 @@ full_search:
+ addr = _ALIGN_UP(addr + 1, 1ul << SLICE_HIGH_SHIFT);
+ continue;
+ }
+- if (!vma || addr + len <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr, len)) {
+ /*
+ * Remember the place where we stopped the search:
+ */
+@@ -336,7 +335,7 @@ static unsigned long slice_find_area_top
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
+- if (!vma || (addr + len) <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr, len)) {
+ /* remember the address as a hint for next time */
+ if (use_cache)
+ mm->free_area_cache = addr;
+@@ -426,6 +425,11 @@ unsigned long slice_get_unmapped_area(un
if (fixed && addr > (mm->task_size - len))
return -EINVAL;
@@ -3115,6 +3247,56 @@ diff -urNp linux-2.6.32.21/arch/sh/kernel/kgdb.c linux-2.6.32.21/arch/sh/kernel/
/* Breakpoint instruction: trapa #0x3c */
#ifdef CONFIG_CPU_LITTLE_ENDIAN
.gdb_bpt_instr = { 0x3c, 0xc3 },
+diff -urNp linux-2.6.32.21/arch/sh/mm/mmap.c linux-2.6.32.21/arch/sh/mm/mmap.c
+--- linux-2.6.32.21/arch/sh/mm/mmap.c 2010-08-13 16:24:37.000000000 -0400
++++ linux-2.6.32.21/arch/sh/mm/mmap.c 2010-09-17 18:34:04.000000000 -0400
+@@ -74,8 +74,7 @@ unsigned long arch_get_unmapped_area(str
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
+ return addr;
+ }
+
+@@ -106,7 +105,7 @@ full_search:
+ }
+ return -ENOMEM;
+ }
+- if (likely(!vma || addr + len <= vma->vm_start)) {
++ if (likely(check_heap_stack_gap(vma, addr, len))) {
+ /*
+ * Remember the place where we stopped the search:
+ */
+@@ -157,8 +156,7 @@ arch_get_unmapped_area_topdown(struct fi
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
+ return addr;
+ }
+
+@@ -179,7 +177,7 @@ arch_get_unmapped_area_topdown(struct fi
+ /* make sure it can fit in the remaining address space */
+ if (likely(addr > len)) {
+ vma = find_vma(mm, addr-len);
+- if (!vma || addr <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr - len, len)) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr-len);
+ }
+@@ -199,7 +197,7 @@ arch_get_unmapped_area_topdown(struct fi
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
+- if (likely(!vma || addr+len <= vma->vm_start)) {
++ if (likely(check_heap_stack_gap(vma, addr, len))) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr);
+ }
diff -urNp linux-2.6.32.21/arch/sparc/include/asm/atomic_64.h linux-2.6.32.21/arch/sparc/include/asm/atomic_64.h
--- linux-2.6.32.21/arch/sparc/include/asm/atomic_64.h 2010-08-29 21:08:20.000000000 -0400
+++ linux-2.6.32.21/arch/sparc/include/asm/atomic_64.h 2010-09-15 02:34:10.000000000 -0400
@@ -3669,7 +3851,7 @@ diff -urNp linux-2.6.32.21/arch/sparc/kernel/pci_sun4v.c linux-2.6.32.21/arch/sp
.map_page = dma_4v_map_page,
diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_32.c linux-2.6.32.21/arch/sparc/kernel/sys_sparc_32.c
--- linux-2.6.32.21/arch/sparc/kernel/sys_sparc_32.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/sparc/kernel/sys_sparc_32.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/sparc/kernel/sys_sparc_32.c 2010-09-17 18:34:04.000000000 -0400
@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
if (ARCH_SUN4C && len > 0x20000000)
return -ENOMEM;
@@ -3679,9 +3861,18 @@ diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_32.c linux-2.6.32.21/arch
if (flags & MAP_SHARED)
addr = COLOUR_ALIGN(addr);
+@@ -72,7 +72,7 @@ unsigned long arch_get_unmapped_area(str
+ }
+ if (TASK_SIZE - PAGE_SIZE - len < addr)
+ return -ENOMEM;
+- if (!vmm || addr + len <= vmm->vm_start)
++ if (check_heap_stack_gap(vmm, addr, len))
+ return addr;
+ addr = vmm->vm_end;
+ if (flags & MAP_SHARED)
diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c
--- linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c 2010-09-17 18:34:04.000000000 -0400
@@ -125,7 +125,7 @@ unsigned long arch_get_unmapped_area(str
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
@@ -3702,7 +3893,14 @@ diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c linux-2.6.32.21/arch
if (addr) {
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
-@@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
+@@ -147,15 +151,14 @@ unsigned long arch_get_unmapped_area(str
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+- if (task_size - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
+ return addr;
}
if (len > mm->cached_hole_size) {
@@ -3714,7 +3912,7 @@ diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c linux-2.6.32.21/arch
mm->cached_hole_size = 0;
}
-@@ -175,8 +179,8 @@ full_search:
+@@ -175,14 +178,14 @@ full_search:
vma = find_vma(mm, VA_EXCLUDE_END);
}
if (unlikely(task_size < addr)) {
@@ -3725,7 +3923,14 @@ diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c linux-2.6.32.21/arch
mm->cached_hole_size = 0;
goto full_search;
}
-@@ -216,7 +220,7 @@ arch_get_unmapped_area_topdown(struct fi
+ return -ENOMEM;
+ }
+- if (likely(!vma || addr + len <= vma->vm_start)) {
++ if (likely(check_heap_stack_gap(vma, addr, len))) {
+ /*
+ * Remember the place where we stopped the search:
+ */
+@@ -216,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
@@ -3734,7 +3939,35 @@ diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c linux-2.6.32.21/arch
((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
return -EINVAL;
return addr;
-@@ -384,6 +388,12 @@ void arch_pick_mmap_layout(struct mm_str
+@@ -237,8 +240,7 @@ arch_get_unmapped_area_topdown(struct fi
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+- if (task_size - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
+ return addr;
+ }
+
+@@ -259,7 +261,7 @@ arch_get_unmapped_area_topdown(struct fi
+ /* make sure it can fit in the remaining address space */
+ if (likely(addr > len)) {
+ vma = find_vma(mm, addr-len);
+- if (!vma || addr <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr - len, len)) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr-len);
+ }
+@@ -279,7 +281,7 @@ arch_get_unmapped_area_topdown(struct fi
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
+- if (likely(!vma || addr+len <= vma->vm_start)) {
++ if (likely(check_heap_stack_gap(vma, addr, len))) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr);
+ }
+@@ -384,6 +386,12 @@ void arch_pick_mmap_layout(struct mm_str
current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
sysctl_legacy_va_layout) {
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
@@ -3747,7 +3980,7 @@ diff -urNp linux-2.6.32.21/arch/sparc/kernel/sys_sparc_64.c linux-2.6.32.21/arch
mm->get_unmapped_area = arch_get_unmapped_area;
mm->unmap_area = arch_unmap_area;
} else {
-@@ -398,6 +408,12 @@ void arch_pick_mmap_layout(struct mm_str
+@@ -398,6 +406,12 @@ void arch_pick_mmap_layout(struct mm_str
gap = (task_size / 6 * 5);
mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
@@ -4033,8 +4266,8 @@ diff -urNp linux-2.6.32.21/arch/sparc/lib/atomic_64.S linux-2.6.32.21/arch/sparc
bne,pn %xcc, 2f
diff -urNp linux-2.6.32.21/arch/sparc/lib/ksyms.c linux-2.6.32.21/arch/sparc/lib/ksyms.c
--- linux-2.6.32.21/arch/sparc/lib/ksyms.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/sparc/lib/ksyms.c 2010-09-04 15:54:51.000000000 -0400
-@@ -144,12 +144,15 @@ EXPORT_SYMBOL(__downgrade_write);
++++ linux-2.6.32.21/arch/sparc/lib/ksyms.c 2010-09-17 17:45:39.000000000 -0400
+@@ -144,12 +144,17 @@ EXPORT_SYMBOL(__downgrade_write);
/* Atomic counter implementation. */
EXPORT_SYMBOL(atomic_add);
@@ -4044,7 +4277,9 @@ diff -urNp linux-2.6.32.21/arch/sparc/lib/ksyms.c linux-2.6.32.21/arch/sparc/lib
+EXPORT_SYMBOL(atomic_sub_unchecked);
EXPORT_SYMBOL(atomic_sub_ret);
EXPORT_SYMBOL(atomic64_add);
++EXPORT_SYMBOL(atomic64_add_unchecked);
EXPORT_SYMBOL(atomic64_add_ret);
++EXPORT_SYMBOL(atomic64_add_ret_unchecked);
EXPORT_SYMBOL(atomic64_sub);
+EXPORT_SYMBOL(atomic64_sub_unchecked);
EXPORT_SYMBOL(atomic64_sub_ret);
@@ -4969,6 +5204,46 @@ diff -urNp linux-2.6.32.21/arch/sparc/mm/fault_64.c linux-2.6.32.21/arch/sparc/m
/* Pure DTLB misses do not tell us whether the fault causing
* load/store/atomic was a write or not, it only says that there
* was no match. So in such a case we (carefully) read the
+diff -urNp linux-2.6.32.21/arch/sparc/mm/hugetlbpage.c linux-2.6.32.21/arch/sparc/mm/hugetlbpage.c
+--- linux-2.6.32.21/arch/sparc/mm/hugetlbpage.c 2010-08-13 16:24:37.000000000 -0400
++++ linux-2.6.32.21/arch/sparc/mm/hugetlbpage.c 2010-09-17 18:34:04.000000000 -0400
+@@ -69,7 +69,7 @@ full_search:
+ }
+ return -ENOMEM;
+ }
+- if (likely(!vma || addr + len <= vma->vm_start)) {
++ if (likely(check_heap_stack_gap(vma, addr, len))) {
+ /*
+ * Remember the place where we stopped the search:
+ */
+@@ -108,7 +108,7 @@ hugetlb_get_unmapped_area_topdown(struct
+ /* make sure it can fit in the remaining address space */
+ if (likely(addr > len)) {
+ vma = find_vma(mm, addr-len);
+- if (!vma || addr <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr - len, len)) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr-len);
+ }
+@@ -126,7 +126,7 @@ hugetlb_get_unmapped_area_topdown(struct
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
+- if (likely(!vma || addr+len <= vma->vm_start)) {
++ if (likely(check_heap_stack_gap(vma, addr, len))) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr);
+ }
+@@ -183,8 +183,7 @@ hugetlb_get_unmapped_area(struct file *f
+ if (addr) {
+ addr = ALIGN(addr, HPAGE_SIZE);
+ vma = find_vma(mm, addr);
+- if (task_size - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
+ return addr;
+ }
+ if (mm->get_unmapped_area == arch_get_unmapped_area)
diff -urNp linux-2.6.32.21/arch/sparc/mm/init_32.c linux-2.6.32.21/arch/sparc/mm/init_32.c
--- linux-2.6.32.21/arch/sparc/mm/init_32.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/arch/sparc/mm/init_32.c 2010-09-04 15:54:51.000000000 -0400
@@ -6145,7 +6420,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_32.h linux-2.6.32.21/arch
extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch/x86/include/asm/atomic_64.h
--- linux-2.6.32.21/arch/x86/include/asm/atomic_64.h 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/include/asm/atomic_64.h 2010-09-15 02:36:22.000000000 -0400
++++ linux-2.6.32.21/arch/x86/include/asm/atomic_64.h 2010-09-17 20:46:00.000000000 -0400
@@ -24,6 +24,17 @@ static inline int atomic_read(const atom
}
@@ -6426,15 +6701,18 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "+r" (i), "+m" (v->counter)
: : "memory");
return i + __i;
-@@ -185,6 +370,7 @@ static inline int atomic_sub_return(int
+@@ -185,6 +370,10 @@ static inline int atomic_sub_return(int
}
#define atomic_inc_return(v) (atomic_add_return(1, v))
-+#define atomic_inc_return_unchecked(v) (atomic_add_return_unchecked(1, v))
++static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++ return atomic_add_return(1, v);
++}
#define atomic_dec_return(v) (atomic_sub_return(1, v))
/* The 64-bit atomic type */
-@@ -204,6 +390,18 @@ static inline long atomic64_read(const a
+@@ -204,6 +393,18 @@ static inline long atomic64_read(const a
}
/**
@@ -6453,7 +6731,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
* atomic64_set - set atomic64 variable
* @v: pointer to type atomic64_t
* @i: required value
-@@ -216,6 +414,18 @@ static inline void atomic64_set(atomic64
+@@ -216,6 +417,18 @@ static inline void atomic64_set(atomic64
}
/**
@@ -6472,7 +6750,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
* atomic64_add - add integer to atomic64 variable
* @i: integer value to add
* @v: pointer to type atomic64_t
-@@ -224,6 +434,28 @@ static inline void atomic64_set(atomic64
+@@ -224,6 +437,28 @@ static inline void atomic64_set(atomic64
*/
static inline void atomic64_add(long i, atomic64_t *v)
{
@@ -6501,7 +6779,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
asm volatile(LOCK_PREFIX "addq %1,%0"
: "=m" (v->counter)
: "er" (i), "m" (v->counter));
-@@ -238,7 +470,15 @@ static inline void atomic64_add(long i,
+@@ -238,7 +473,15 @@ static inline void atomic64_add(long i,
*/
static inline void atomic64_sub(long i, atomic64_t *v)
{
@@ -6518,7 +6796,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "=m" (v->counter)
: "er" (i), "m" (v->counter));
}
-@@ -256,7 +496,16 @@ static inline int atomic64_sub_and_test(
+@@ -256,7 +499,16 @@ static inline int atomic64_sub_and_test(
{
unsigned char c;
@@ -6536,7 +6814,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "=m" (v->counter), "=qm" (c)
: "er" (i), "m" (v->counter) : "memory");
return c;
-@@ -270,6 +519,31 @@ static inline int atomic64_sub_and_test(
+@@ -270,6 +522,31 @@ static inline int atomic64_sub_and_test(
*/
static inline void atomic64_inc(atomic64_t *v)
{
@@ -6568,7 +6846,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
asm volatile(LOCK_PREFIX "incq %0"
: "=m" (v->counter)
: "m" (v->counter));
-@@ -283,7 +557,32 @@ static inline void atomic64_inc(atomic64
+@@ -283,7 +560,32 @@ static inline void atomic64_inc(atomic64
*/
static inline void atomic64_dec(atomic64_t *v)
{
@@ -6602,7 +6880,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "=m" (v->counter)
: "m" (v->counter));
}
-@@ -300,7 +599,20 @@ static inline int atomic64_dec_and_test(
+@@ -300,7 +602,20 @@ static inline int atomic64_dec_and_test(
{
unsigned char c;
@@ -6624,7 +6902,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "=m" (v->counter), "=qm" (c)
: "m" (v->counter) : "memory");
return c != 0;
-@@ -318,7 +630,20 @@ static inline int atomic64_inc_and_test(
+@@ -318,7 +633,20 @@ static inline int atomic64_inc_and_test(
{
unsigned char c;
@@ -6646,7 +6924,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "=m" (v->counter), "=qm" (c)
: "m" (v->counter) : "memory");
return c != 0;
-@@ -337,7 +662,16 @@ static inline int atomic64_add_negative(
+@@ -337,7 +665,16 @@ static inline int atomic64_add_negative(
{
unsigned char c;
@@ -6664,7 +6942,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "=m" (v->counter), "=qm" (c)
: "er" (i), "m" (v->counter) : "memory");
return c;
-@@ -353,7 +687,31 @@ static inline int atomic64_add_negative(
+@@ -353,7 +690,31 @@ static inline int atomic64_add_negative(
static inline long atomic64_add_return(long i, atomic64_t *v)
{
long __i = i;
@@ -6697,7 +6975,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
: "+r" (i), "+m" (v->counter)
: : "memory");
return i + __i;
-@@ -365,6 +723,10 @@ static inline long atomic64_sub_return(l
+@@ -365,6 +726,10 @@ static inline long atomic64_sub_return(l
}
#define atomic64_inc_return(v) (atomic64_add_return(1, (v)))
@@ -6708,7 +6986,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
#define atomic64_dec_return(v) (atomic64_sub_return(1, (v)))
static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
-@@ -398,17 +760,29 @@ static inline long atomic_xchg(atomic_t
+@@ -398,17 +763,29 @@ static inline long atomic_xchg(atomic_t
*/
static inline int atomic_add_unless(atomic_t *v, int a, int u)
{
@@ -6742,7 +7020,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/atomic_64.h linux-2.6.32.21/arch
}
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-@@ -424,17 +798,29 @@ static inline int atomic_add_unless(atom
+@@ -424,17 +801,29 @@ static inline int atomic_add_unless(atom
*/
static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
{
@@ -9393,7 +9671,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess_64.h linux-2.6.32.21/arc
#endif /* _ASM_X86_UACCESS_64_H */
diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x86/include/asm/uaccess.h
--- linux-2.6.32.21/arch/x86/include/asm/uaccess.h 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/include/asm/uaccess.h 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/x86/include/asm/uaccess.h 2010-09-16 23:14:31.000000000 -0400
@@ -8,12 +8,15 @@
#include <linux/thread_info.h>
#include <linux/prefetch.h>
@@ -9458,22 +9736,9 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
/*
* The exception table consists of pairs of addresses: the first is the
-@@ -179,17 +213,34 @@ extern int __get_user_bad(void);
- __ret_gu; \
- })
-
-+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
-+#define __put_user_x(size, x, ptr, __ret_pu) \
-+ ({ \
-+ int __dummy; \
-+ asm volatile("call __put_user_" #size : "=a" (__ret_pu), "=c" (__dummy) \
-+ : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx"); \
-+ })
-+#else
- #define __put_user_x(size, x, ptr, __ret_pu) \
+@@ -183,13 +217,21 @@ extern int __get_user_bad(void);
asm volatile("call __put_user_" #size : "=a" (__ret_pu) \
: "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
-+#endif
-
+#ifdef CONFIG_X86_32
@@ -9496,7 +9761,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
".section .fixup,\"ax\"\n" \
"4: movl %3,%0\n" \
" jmp 3b\n" \
-@@ -197,15 +248,18 @@ extern int __get_user_bad(void);
+@@ -197,15 +239,18 @@ extern int __get_user_bad(void);
_ASM_EXTABLE(1b, 4b) \
_ASM_EXTABLE(2b, 4b) \
: "=r" (err) \
@@ -9519,7 +9784,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
#define __put_user_x8(x, ptr, __ret_pu) \
asm volatile("call __put_user_8" : "=a" (__ret_pu) \
-@@ -374,16 +428,18 @@ do { \
+@@ -374,16 +419,18 @@ do { \
} while (0)
#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
@@ -9541,7 +9806,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
#define __get_user_size_ex(x, ptr, size) \
do { \
-@@ -407,10 +463,12 @@ do { \
+@@ -407,10 +454,12 @@ do { \
} while (0)
#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
@@ -9556,7 +9821,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
#define __put_user_nocheck(x, ptr, size) \
({ \
-@@ -424,13 +482,24 @@ do { \
+@@ -424,13 +473,24 @@ do { \
int __gu_err; \
unsigned long __gu_val; \
__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
@@ -9583,7 +9848,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
/*
* Tell gcc we read from memory instead of writing: this is because
-@@ -438,21 +507,26 @@ struct __large_struct { unsigned long bu
+@@ -438,21 +498,26 @@ struct __large_struct { unsigned long bu
* aliasing issues.
*/
#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
@@ -9614,7 +9879,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
/*
* uaccess_try and catch
-@@ -530,7 +604,7 @@ struct __large_struct { unsigned long bu
+@@ -530,7 +595,7 @@ struct __large_struct { unsigned long bu
#define get_user_ex(x, ptr) do { \
unsigned long __gue_val; \
__get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr)))); \
@@ -9623,7 +9888,7 @@ diff -urNp linux-2.6.32.21/arch/x86/include/asm/uaccess.h linux-2.6.32.21/arch/x
} while (0)
#ifdef CONFIG_X86_WP_WORKS_OK
-@@ -567,6 +641,7 @@ extern struct movsl_mask {
+@@ -567,6 +632,7 @@ extern struct movsl_mask {
#define ARCH_HAS_NOCACHE_UACCESS 1
@@ -13721,7 +13986,26 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/signal.c linux-2.6.32.21/arch/x86/ker
if (current_thread_info()->status & TS_RESTORE_SIGMASK)
diff -urNp linux-2.6.32.21/arch/x86/kernel/smpboot.c linux-2.6.32.21/arch/x86/kernel/smpboot.c
--- linux-2.6.32.21/arch/x86/kernel/smpboot.c 2010-08-29 21:08:20.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/kernel/smpboot.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/x86/kernel/smpboot.c 2010-09-17 17:44:35.000000000 -0400
+@@ -95,14 +95,14 @@ static DEFINE_PER_CPU(struct task_struct
+ */
+ static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
+
+-void cpu_hotplug_driver_lock()
++void cpu_hotplug_driver_lock(void)
+ {
+- mutex_lock(&x86_cpu_hotplug_driver_mutex);
++ mutex_lock(&x86_cpu_hotplug_driver_mutex);
+ }
+
+-void cpu_hotplug_driver_unlock()
++void cpu_hotplug_driver_unlock(void)
+ {
+- mutex_unlock(&x86_cpu_hotplug_driver_mutex);
++ mutex_unlock(&x86_cpu_hotplug_driver_mutex);
+ }
+
+ ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; }
@@ -748,7 +748,11 @@ do_rest:
(unsigned long)task_stack_page(c_idle.idle) -
KERNEL_STACK_OFFSET + THREAD_SIZE;
@@ -13792,7 +14076,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/syscall_table_32.S linux-2.6.32.21/ar
.long sys_exit
diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c
--- linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c 2010-09-17 18:34:04.000000000 -0400
@@ -24,6 +24,21 @@
#include <asm/syscalls.h>
@@ -13815,7 +14099,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux/i386 didn't use to be able to handle more than
-@@ -58,6 +73,205 @@ out:
+@@ -58,6 +73,208 @@ out:
return err;
}
@@ -13844,10 +14128,11 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
+
+ if (addr) {
+ addr = PAGE_ALIGN(addr);
-+ vma = find_vma(mm, addr);
-+ if (pax_task_size - len >= addr &&
-+ (!vma || addr + len <= vma->vm_start))
-+ return addr;
++ if (pax_task_size - len >= addr) {
++ vma = find_vma(mm, addr);
++ if (check_heap_stack_gap(vma, addr, len))
++ return addr;
++ }
+ }
+ if (len > mm->cached_hole_size) {
+ start_addr = addr = mm->free_area_cache;
@@ -13887,13 +14172,8 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
+ }
+ return -ENOMEM;
+ }
-+ if (!vma || addr + len <= vma->vm_start) {
-+ /*
-+ * Remember the place where we stopped the search:
-+ */
-+ mm->free_area_cache = addr + len;
-+ return addr;
-+ }
++ if (check_heap_stack_gap(vma, addr, len))
++ break;
+ if (addr + mm->cached_hole_size < vma->vm_start)
+ mm->cached_hole_size = vma->vm_start - addr;
+ addr = vma->vm_end;
@@ -13903,6 +14183,12 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
+ goto full_search;
+ }
+ }
++
++ /*
++ * Remember the place where we stopped the search:
++ */
++ mm->free_area_cache = addr + len;
++ return addr;
+}
+
+unsigned long
@@ -13938,10 +14224,11 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
+ /* requesting a specific address */
+ if (addr) {
+ addr = PAGE_ALIGN(addr);
-+ vma = find_vma(mm, addr);
-+ if (pax_task_size - len >= addr &&
-+ (!vma || addr + len <= vma->vm_start))
-+ return addr;
++ if (pax_task_size - len >= addr) {
++ vma = find_vma(mm, addr);
++ if (check_heap_stack_gap(vma, addr, len))
++ return addr;
++ }
+ }
+
+ /* check if free_area_cache is useful for us */
@@ -13956,7 +14243,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
+ /* make sure it can fit in the remaining address space */
+ if (addr > len) {
+ vma = find_vma(mm, addr-len);
-+ if (!vma || addr <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr - len, len))
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr-len);
+ }
@@ -13973,7 +14260,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
-+ if (!vma || addr+len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr);
+
@@ -14021,7 +14308,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
struct sel_arg_struct {
unsigned long n;
-@@ -93,7 +307,7 @@ asmlinkage int sys_ipc(uint call, int fi
+@@ -93,7 +310,7 @@ asmlinkage int sys_ipc(uint call, int fi
return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL);
case SEMTIMEDOP:
return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
@@ -14030,7 +14317,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
case SEMGET:
return sys_semget(first, second, third);
-@@ -140,7 +354,7 @@ asmlinkage int sys_ipc(uint call, int fi
+@@ -140,7 +357,7 @@ asmlinkage int sys_ipc(uint call, int fi
ret = do_shmat(first, (char __user *) ptr, second, &raddr);
if (ret)
return ret;
@@ -14041,7 +14328,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_i386_32.c linux-2.6.32.21/arch/x8
if (!segment_eq(get_fs(), get_ds()))
diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c
--- linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c 2010-09-17 18:34:04.000000000 -0400
@@ -32,8 +32,8 @@ out:
return error;
}
@@ -14062,7 +14349,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c linux-2.6.32.21/arch/x86
*end = TASK_SIZE;
}
}
-@@ -69,11 +69,15 @@ arch_get_unmapped_area(struct file *filp
+@@ -69,16 +69,19 @@ arch_get_unmapped_area(struct file *filp
if (flags & MAP_FIXED)
return addr;
@@ -14079,7 +14366,22 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c linux-2.6.32.21/arch/x86
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
-@@ -128,7 +132,7 @@ arch_get_unmapped_area_topdown(struct fi
+- if (end - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (end - len >= addr && check_heap_stack_gap(vma, addr, len))
+ return addr;
+ }
+ if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
+@@ -106,7 +109,7 @@ full_search:
+ }
+ return -ENOMEM;
+ }
+- if (!vma || addr + len <= vma->vm_start) {
++ if (check_heap_stack_gap(vma, addr, len)) {
+ /*
+ * Remember the place where we stopped the search:
+ */
+@@ -128,7 +131,7 @@ arch_get_unmapped_area_topdown(struct fi
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
@@ -14088,7 +14390,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c linux-2.6.32.21/arch/x86
/* requested length too big for entire address space */
if (len > TASK_SIZE)
-@@ -141,6 +145,10 @@ arch_get_unmapped_area_topdown(struct fi
+@@ -141,12 +144,15 @@ arch_get_unmapped_area_topdown(struct fi
if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
goto bottomup;
@@ -14099,7 +14401,32 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/sys_x86_64.c linux-2.6.32.21/arch/x86
/* requesting a specific address */
if (addr) {
addr = PAGE_ALIGN(addr);
-@@ -198,13 +206,21 @@ bottomup:
+ vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
+ return addr;
+ }
+
+@@ -162,7 +168,7 @@ arch_get_unmapped_area_topdown(struct fi
+ /* make sure it can fit in the remaining address space */
+ if (addr > len) {
+ vma = find_vma(mm, addr-len);
+- if (!vma || addr <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr - len, len))
+ /* remember the address as a hint for next time */
+ return mm->free_area_cache = addr-len;
+ }
+@@ -179,7 +185,7 @@ arch_get_unmapped_area_topdown(struct fi
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
+- if (!vma || addr+len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ /* remember the address as a hint for next time */
+ return mm->free_area_cache = addr;
+
+@@ -198,13 +204,21 @@ bottomup:
* can happen with large stack limits and large mmap()
* allocations.
*/
@@ -14599,22 +14926,13 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmi_32.c linux-2.6.32.21/arch/x86/ker
local_irq_save(flags);
diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S
--- linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S 2010-09-04 15:54:51.000000000 -0400
-@@ -26,6 +26,22 @@
++++ linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S 2010-09-17 17:29:28.000000000 -0400
+@@ -26,6 +26,13 @@
#include <asm/page_types.h>
#include <asm/cache.h>
#include <asm/boot.h>
+#include <asm/segment.h>
+
-+#undef PMD_SIZE
-+#undef PMD_SHIFT
-+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
-+#define PMD_SHIFT 21
-+#else
-+#define PMD_SHIFT 22
-+#endif
-+#define PMD_SIZE (1 << PMD_SHIFT)
-+
+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
+#define __KERNEL_TEXT_OFFSET (LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR)
+#else
@@ -14623,7 +14941,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
#undef i386 /* in case the preprocessor is a 32bit one */
-@@ -34,40 +50,55 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONF
+@@ -34,40 +41,55 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONF
#ifdef CONFIG_X86_32
OUTPUT_ARCH(i386)
ENTRY(phys_startup_32)
@@ -14689,7 +15007,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
HEAD_TEXT
#ifdef CONFIG_X86_32
. = ALIGN(PAGE_SIZE);
-@@ -82,28 +113,69 @@ SECTIONS
+@@ -82,28 +104,69 @@ SECTIONS
IRQENTRY_TEXT
*(.fixup)
*(.gnu.warning)
@@ -14766,7 +15084,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
PAGE_ALIGNED_DATA(PAGE_SIZE)
-@@ -166,12 +238,6 @@ SECTIONS
+@@ -166,12 +229,6 @@ SECTIONS
}
vgetcpu_mode = VVIRT(.vgetcpu_mode);
@@ -14779,7 +15097,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
.vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
*(.vsyscall_3)
}
-@@ -187,12 +253,19 @@ SECTIONS
+@@ -187,12 +244,19 @@ SECTIONS
#endif /* CONFIG_X86_64 */
/* Init code and data - will be freed after init */
@@ -14802,7 +15120,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
/*
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
* output PHDR, so the next output section - .init.text - should
-@@ -201,12 +274,27 @@ SECTIONS
+@@ -201,12 +265,27 @@ SECTIONS
PERCPU_VADDR(0, :percpu)
#endif
@@ -14818,7 +15136,8 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
+ VMLINUX_SYMBOL(_einittext) = .;
+ . = ALIGN(PAGE_SIZE);
+ } :text.init
-+
+
+- INIT_DATA_SECTION(16)
+ /*
+ * .exit.text is discard at runtime, not link time, to deal with
+ * references from .altinstructions and .eh_frame
@@ -14828,14 +15147,13 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
+ . = ALIGN(16);
+ } :text.exit
+ . = init_begin + SIZEOF(.init.text) + SIZEOF(.exit.text);
-
-- INIT_DATA_SECTION(16)
++
+ . = ALIGN(PAGE_SIZE);
+ INIT_DATA_SECTION(16) :init
.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
__x86_cpu_dev_start = .;
-@@ -232,19 +320,11 @@ SECTIONS
+@@ -232,19 +311,11 @@ SECTIONS
*(.altinstr_replacement)
}
@@ -14856,7 +15174,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
PERCPU(PAGE_SIZE)
#endif
-@@ -267,12 +347,6 @@ SECTIONS
+@@ -267,12 +338,6 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
}
@@ -14869,7 +15187,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
/* BSS */
. = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-@@ -288,6 +362,7 @@ SECTIONS
+@@ -288,6 +353,7 @@ SECTIONS
__brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */
@@ -14877,7 +15195,7 @@ diff -urNp linux-2.6.32.21/arch/x86/kernel/vmlinux.lds.S linux-2.6.32.21/arch/x8
__brk_limit = .;
}
-@@ -316,13 +391,12 @@ SECTIONS
+@@ -316,13 +382,12 @@ SECTIONS
* for the boot processor.
*/
#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
@@ -18096,7 +18414,7 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/highmem_32.c linux-2.6.32.21/arch/x86/mm/
}
diff -urNp linux-2.6.32.21/arch/x86/mm/hugetlbpage.c linux-2.6.32.21/arch/x86/mm/hugetlbpage.c
--- linux-2.6.32.21/arch/x86/mm/hugetlbpage.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/mm/hugetlbpage.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/x86/mm/hugetlbpage.c 2010-09-17 18:34:04.000000000 -0400
@@ -267,13 +267,18 @@ static unsigned long hugetlb_get_unmappe
struct hstate *h = hstate_file(file);
struct mm_struct *mm = current->mm;
@@ -18120,7 +18438,7 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/hugetlbpage.c linux-2.6.32.21/arch/x86/mm
}
full_search:
-@@ -281,13 +286,13 @@ full_search:
+@@ -281,26 +286,27 @@ full_search:
for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
/* At this point: (!vma || addr < vma->vm_end). */
@@ -18137,18 +18455,38 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/hugetlbpage.c linux-2.6.32.21/arch/x86/mm
mm->cached_hole_size = 0;
goto full_search;
}
-@@ -310,9 +315,8 @@ static unsigned long hugetlb_get_unmappe
+ return -ENOMEM;
+ }
+- if (!vma || addr + len <= vma->vm_start) {
+- mm->free_area_cache = addr + len;
+- return addr;
+- }
++ if (check_heap_stack_gap(vma, addr, len))
++ break;
+ if (addr + mm->cached_hole_size < vma->vm_start)
+ mm->cached_hole_size = vma->vm_start - addr;
+ addr = ALIGN(vma->vm_end, huge_page_size(h));
+ }
++
++ mm->free_area_cache = addr + len;
++ return addr;
+ }
+
+ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
+@@ -309,10 +315,9 @@ static unsigned long hugetlb_get_unmappe
+ {
struct hstate *h = hstate_file(file);
struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma, *prev_vma;
+- struct vm_area_struct *vma, *prev_vma;
- unsigned long base = mm->mmap_base, addr = addr0;
++ struct vm_area_struct *vma;
+ unsigned long base = mm->mmap_base, addr;
unsigned long largest_hole = mm->cached_hole_size;
- int first_time = 1;
/* don't allow allocations above current base */
if (mm->free_area_cache > base)
-@@ -322,7 +326,7 @@ static unsigned long hugetlb_get_unmappe
+@@ -322,7 +327,7 @@ static unsigned long hugetlb_get_unmappe
largest_hole = 0;
mm->free_area_cache = base;
}
@@ -18157,7 +18495,51 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/hugetlbpage.c linux-2.6.32.21/arch/x86/mm
/* make sure it can fit in the remaining address space */
if (mm->free_area_cache < len)
goto fail;
-@@ -364,22 +368,26 @@ try_again:
+@@ -330,33 +335,27 @@ try_again:
+ /* either no address requested or cant fit in requested address hole */
+ addr = (mm->free_area_cache - len) & huge_page_mask(h);
+ do {
++ vma = find_vma(mm, addr);
+ /*
+ * Lookup failure means no vma is above this address,
+ * i.e. return with success:
+- */
+- if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
+- return addr;
+-
+- /*
+ * new region fits between prev_vma->vm_end and
+ * vma->vm_start, use it:
+ */
+- if (addr + len <= vma->vm_start &&
+- (!prev_vma || (addr >= prev_vma->vm_end))) {
++ if (check_heap_stack_gap(vma, addr, len)) {
+ /* remember the address as a hint for next time */
+- mm->cached_hole_size = largest_hole;
+- return (mm->free_area_cache = addr);
+- } else {
+- /* pull free_area_cache down to the first hole */
+- if (mm->free_area_cache == vma->vm_end) {
+- mm->free_area_cache = vma->vm_start;
+- mm->cached_hole_size = largest_hole;
+- }
++ mm->cached_hole_size = largest_hole;
++ return (mm->free_area_cache = addr);
++ }
++ /* pull free_area_cache down to the first hole */
++ if (mm->free_area_cache == vma->vm_end) {
++ mm->free_area_cache = vma->vm_start;
++ mm->cached_hole_size = largest_hole;
+ }
+
+ /* remember the largest hole we saw so far */
+ if (addr + largest_hole < vma->vm_start)
+- largest_hole = vma->vm_start - addr;
++ largest_hole = vma->vm_start - addr;
+
+ /* try just below the current vma->vm_start */
+ addr = (vma->vm_start - len) & huge_page_mask(h);
+@@ -364,22 +363,26 @@ try_again:
fail:
/*
@@ -18195,7 +18577,7 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/hugetlbpage.c linux-2.6.32.21/arch/x86/mm
mm->cached_hole_size = ~0UL;
addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
len, pgoff, flags);
-@@ -387,6 +395,7 @@ fail:
+@@ -387,6 +390,7 @@ fail:
/*
* Restore the topdown base:
*/
@@ -18203,7 +18585,7 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/hugetlbpage.c linux-2.6.32.21/arch/x86/mm
mm->free_area_cache = base;
mm->cached_hole_size = ~0UL;
-@@ -400,10 +409,17 @@ hugetlb_get_unmapped_area(struct file *f
+@@ -400,10 +404,17 @@ hugetlb_get_unmapped_area(struct file *f
struct hstate *h = hstate_file(file);
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
@@ -18222,15 +18604,16 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/hugetlbpage.c linux-2.6.32.21/arch/x86/mm
return -ENOMEM;
if (flags & MAP_FIXED) {
-@@ -415,7 +431,7 @@ hugetlb_get_unmapped_area(struct file *f
+@@ -415,8 +426,7 @@ hugetlb_get_unmapped_area(struct file *f
if (addr) {
addr = ALIGN(addr, huge_page_size(h));
vma = find_vma(mm, addr);
- if (TASK_SIZE - len >= addr &&
-+ if (pax_task_size - len >= addr &&
- (!vma || addr + len <= vma->vm_start))
+- (!vma || addr + len <= vma->vm_start))
++ if (pax_task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
return addr;
}
+ if (mm->get_unmapped_area == arch_get_unmapped_area)
diff -urNp linux-2.6.32.21/arch/x86/mm/init_32.c linux-2.6.32.21/arch/x86/mm/init_32.c
--- linux-2.6.32.21/arch/x86/mm/init_32.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/arch/x86/mm/init_32.c 2010-09-04 15:54:51.000000000 -0400
@@ -18602,7 +18985,7 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/init_64.c linux-2.6.32.21/arch/x86/mm/ini
return "[vsyscall]";
diff -urNp linux-2.6.32.21/arch/x86/mm/init.c linux-2.6.32.21/arch/x86/mm/init.c
--- linux-2.6.32.21/arch/x86/mm/init.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/mm/init.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/x86/mm/init.c 2010-09-16 22:50:17.000000000 -0400
@@ -69,11 +69,7 @@ static void __init find_early_table_spac
* cause a hotspot and fill up ZONE_DMA. The page tables
* need roughly 0.5KB per GB.
@@ -18616,6 +18999,15 @@ diff -urNp linux-2.6.32.21/arch/x86/mm/init.c linux-2.6.32.21/arch/x86/mm/init.c
e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
tables, PAGE_SIZE);
if (e820_table_start == -1UL)
+@@ -147,7 +143,7 @@ unsigned long __init_refok init_memory_m
+ #endif
+
+ set_nx();
+- if (nx_enabled)
++ if (nx_enabled && cpu_has_nx)
+ printk(KERN_INFO "NX (Execute Disable) protection: active\n");
+
+ /* Enable PSE if available */
@@ -331,7 +327,13 @@ unsigned long __init_refok init_memory_m
*/
int devmem_is_allowed(unsigned long pagenr)
@@ -20213,7 +20605,7 @@ diff -urNp linux-2.6.32.21/arch/x86/vdso/vma.c linux-2.6.32.21/arch/x86/vdso/vma
-__setup("vdso=", vdso_setup);
diff -urNp linux-2.6.32.21/arch/x86/xen/enlighten.c linux-2.6.32.21/arch/x86/xen/enlighten.c
--- linux-2.6.32.21/arch/x86/xen/enlighten.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/arch/x86/xen/enlighten.c 2010-09-04 15:54:51.000000000 -0400
++++ linux-2.6.32.21/arch/x86/xen/enlighten.c 2010-09-17 17:30:16.000000000 -0400
@@ -71,8 +71,6 @@ EXPORT_SYMBOL_GPL(xen_start_info);
struct shared_info xen_dummy_shared_info;
@@ -20241,10 +20633,10 @@ diff -urNp linux-2.6.32.21/arch/x86/xen/enlighten.c linux-2.6.32.21/arch/x86/xen
- check_efer();
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+ if ((cpuid_eax(0x80000000) & 0xffff0000) == 0x80000000 &&
-+ (cpuid_edx(0x80000001) & (1 << (X86_FEATURE_NX & 31)))) {
++ (cpuid_edx(0x80000001) & (1U << (X86_FEATURE_NX & 31)))) {
+ unsigned l, h;
+
-+#if defined(CONFIG_X86_32)
++#ifdef CONFIG_X86_PAE
+ nx_enabled = 1;
+#endif
+ __supported_pte_mask |= _PAGE_NX;
@@ -31772,19 +32164,6 @@ diff -urNp linux-2.6.32.21/fs/ext4/balloc.c linux-2.6.32.21/fs/ext4/balloc.c
if (free_blocks >= (nblocks + dirty_blocks))
return 1;
}
-diff -urNp linux-2.6.32.21/fs/ext4/ioctl.c linux-2.6.32.21/fs/ext4/ioctl.c
---- linux-2.6.32.21/fs/ext4/ioctl.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/fs/ext4/ioctl.c 2010-09-04 15:54:52.000000000 -0400
-@@ -230,6 +230,9 @@ setversion_out:
- struct file *donor_filp;
- int err;
-
-+ /* temporary workaround for bugs in here */
-+ return -EOPNOTSUPP;
-+
- if (!(filp->f_mode & FMODE_READ) ||
- !(filp->f_mode & FMODE_WRITE))
- return -EBADF;
diff -urNp linux-2.6.32.21/fs/ext4/namei.c linux-2.6.32.21/fs/ext4/namei.c
--- linux-2.6.32.21/fs/ext4/namei.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/fs/ext4/namei.c 2010-09-04 15:54:52.000000000 -0400
@@ -34418,7 +34797,7 @@ diff -urNp linux-2.6.32.21/fs/proc/root.c linux-2.6.32.21/fs/proc/root.c
diff -urNp linux-2.6.32.21/fs/proc/task_mmu.c linux-2.6.32.21/fs/proc/task_mmu.c
--- linux-2.6.32.21/fs/proc/task_mmu.c 2010-08-29 21:08:16.000000000 -0400
-+++ linux-2.6.32.21/fs/proc/task_mmu.c 2010-09-04 15:54:52.000000000 -0400
++++ linux-2.6.32.21/fs/proc/task_mmu.c 2010-09-17 18:40:06.000000000 -0400
@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
"VmStk:\t%8lu kB\n"
"VmExe:\t%8lu kB\n"
@@ -34462,15 +34841,30 @@ diff -urNp linux-2.6.32.21/fs/proc/task_mmu.c linux-2.6.32.21/fs/proc/task_mmu.c
static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
{
struct mm_struct *mm = vma->vm_mm;
-@@ -223,13 +240,22 @@ static void show_map_vma(struct seq_file
- start += PAGE_SIZE;
+@@ -206,7 +223,6 @@ static void show_map_vma(struct seq_file
+ int flags = vma->vm_flags;
+ unsigned long ino = 0;
+ unsigned long long pgoff = 0;
+- unsigned long start;
+ dev_t dev = 0;
+ int len;
+
+@@ -217,19 +233,23 @@ static void show_map_vma(struct seq_file
+ pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
+ }
+- /* We don't show the stack guard page in /proc/maps */
+- start = vma->vm_start;
+- if (vma->vm_flags & VM_GROWSDOWN)
+- start += PAGE_SIZE;
+-
seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
+- start,
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ PAX_RAND_FLAGS(mm) ? 0UL : start,
++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
+#else
- start,
++ vma->vm_start,
vma->vm_end,
+#endif
flags & VM_READ ? 'r' : '-',
@@ -34485,7 +34879,7 @@ diff -urNp linux-2.6.32.21/fs/proc/task_mmu.c linux-2.6.32.21/fs/proc/task_mmu.c
MAJOR(dev), MINOR(dev), ino, &len);
/*
-@@ -238,16 +264,16 @@ static void show_map_vma(struct seq_file
+@@ -238,16 +258,16 @@ static void show_map_vma(struct seq_file
*/
if (file) {
pad_len_spaces(m, len);
@@ -34507,7 +34901,7 @@ diff -urNp linux-2.6.32.21/fs/proc/task_mmu.c linux-2.6.32.21/fs/proc/task_mmu.c
name = "[stack]";
}
} else {
-@@ -390,9 +416,16 @@ static int show_smap(struct seq_file *m,
+@@ -390,9 +410,16 @@ static int show_smap(struct seq_file *m,
};
memset(&mss, 0, sizeof mss);
@@ -34527,7 +34921,7 @@ diff -urNp linux-2.6.32.21/fs/proc/task_mmu.c linux-2.6.32.21/fs/proc/task_mmu.c
show_map_vma(m, vma);
-@@ -408,7 +441,11 @@ static int show_smap(struct seq_file *m,
+@@ -408,7 +435,11 @@ static int show_smap(struct seq_file *m,
"Swap: %8lu kB\n"
"KernelPageSize: %8lu kB\n"
"MMUPageSize: %8lu kB\n",
@@ -41692,8 +42086,8 @@ diff -urNp linux-2.6.32.21/grsecurity/grsec_fork.c linux-2.6.32.21/grsecurity/gr
+}
diff -urNp linux-2.6.32.21/grsecurity/grsec_init.c linux-2.6.32.21/grsecurity/grsec_init.c
--- linux-2.6.32.21/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.32.21/grsecurity/grsec_init.c 2010-09-04 15:54:52.000000000 -0400
-@@ -0,0 +1,258 @@
++++ linux-2.6.32.21/grsecurity/grsec_init.c 2010-09-17 19:24:55.000000000 -0400
+@@ -0,0 +1,266 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
@@ -41742,6 +42136,7 @@ diff -urNp linux-2.6.32.21/grsecurity/grsec_init.c linux-2.6.32.21/grsecurity/gr
+#endif
+int grsec_lastack_retries;
+int grsec_enable_tpe_all;
++int grsec_enable_tpe_invert;
+int grsec_enable_socket_all;
+int grsec_socket_all_gid;
+int grsec_enable_socket_client;
@@ -41832,6 +42227,13 @@ diff -urNp linux-2.6.32.21/grsecurity/grsec_init.c linux-2.6.32.21/grsecurity/gr
+#endif
+#endif
+
++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
++ /* for backward compatibility, tpe_invert always defaults to on if
++ enabled in the kernel
++ */
++ grsec_enable_tpe_invert = 1;
++#endif
++
+#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
+#ifndef CONFIG_GRKERNSEC_SYSCTL
+ grsec_lock = 1;
@@ -42828,8 +43230,8 @@ diff -urNp linux-2.6.32.21/grsecurity/grsec_sock.c linux-2.6.32.21/grsecurity/gr
+}
diff -urNp linux-2.6.32.21/grsecurity/grsec_sysctl.c linux-2.6.32.21/grsecurity/grsec_sysctl.c
--- linux-2.6.32.21/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.32.21/grsecurity/grsec_sysctl.c 2010-09-04 15:54:52.000000000 -0400
-@@ -0,0 +1,459 @@
++++ linux-2.6.32.21/grsecurity/grsec_sysctl.c 2010-09-17 19:22:27.000000000 -0400
+@@ -0,0 +1,469 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/sysctl.h>
@@ -43103,6 +43505,16 @@ diff -urNp linux-2.6.32.21/grsecurity/grsec_sysctl.c linux-2.6.32.21/grsecurity/
+ .proc_handler = &proc_dointvec,
+ },
+#endif
++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
++ {
++ .ctl_name = CTL_UNNUMBERED,
++ .procname = "tpe_invert",
++ .data = &grsec_enable_tpe_invert,
++ .maxlen = sizeof(int),
++ .mode = 0600,
++ .proc_handler = &proc_dointvec,
++ },
++#endif
+#ifdef CONFIG_GRKERNSEC_TPE_ALL
+ {
+ .ctl_name = CTL_UNNUMBERED,
@@ -43328,8 +43740,8 @@ diff -urNp linux-2.6.32.21/grsecurity/grsec_time.c linux-2.6.32.21/grsecurity/gr
+}
diff -urNp linux-2.6.32.21/grsecurity/grsec_tpe.c linux-2.6.32.21/grsecurity/grsec_tpe.c
--- linux-2.6.32.21/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.32.21/grsecurity/grsec_tpe.c 2010-09-04 15:54:52.000000000 -0400
-@@ -0,0 +1,38 @@
++++ linux-2.6.32.21/grsecurity/grsec_tpe.c 2010-09-17 19:28:20.000000000 -0400
+@@ -0,0 +1,39 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/file.h>
@@ -43347,7 +43759,8 @@ diff -urNp linux-2.6.32.21/grsecurity/grsec_tpe.c linux-2.6.32.21/grsecurity/grs
+
+ if (cred->uid && ((grsec_enable_tpe &&
+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
-+ !in_group_p(grsec_tpe_gid)
++ ((grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid)) ||
++ (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid)))
+#else
+ in_group_p(grsec_tpe_gid)
+#endif
@@ -43435,8 +43848,8 @@ diff -urNp linux-2.6.32.21/grsecurity/grsum.c linux-2.6.32.21/grsecurity/grsum.c
+}
diff -urNp linux-2.6.32.21/grsecurity/Kconfig linux-2.6.32.21/grsecurity/Kconfig
--- linux-2.6.32.21/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.32.21/grsecurity/Kconfig 2010-09-14 21:34:38.000000000 -0400
-@@ -0,0 +1,987 @@
++++ linux-2.6.32.21/grsecurity/Kconfig 2010-09-17 19:36:28.000000000 -0400
+@@ -0,0 +1,986 @@
+#
+# grecurity configuration
+#
@@ -43588,7 +44001,7 @@ diff -urNp linux-2.6.32.21/grsecurity/Kconfig linux-2.6.32.21/grsecurity/Kconfig
+ select PAX_PT_PAX_FLAGS
+ select PAX_HAVE_ACL_FLAGS
+ select PAX_KERNEXEC if ((PPC || X86) && (!X86_32 || X86_WP_WORKS_OK) && !XEN)
-+ select PAX_MEMORY_UDEREF if (X86_32 && !XEN)
++ select PAX_MEMORY_UDEREF if (X86 && !XEN)
+ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
+ select PAX_SEGMEXEC if (X86_32)
+ select PAX_PAGEEXEC
@@ -44197,11 +44610,14 @@ diff -urNp linux-2.6.32.21/grsecurity/Kconfig linux-2.6.32.21/grsecurity/Kconfig
+ is enabled, a sysctl option with name "tpe" is created.
+
+config GRKERNSEC_TPE_ALL
-+ bool "Partially restrict non-root users"
++ bool "Partially restrict all non-root users"
+ depends on GRKERNSEC_TPE
+ help
-+ If you say Y here, All non-root users other than the ones in the
-+ group specified in the main TPE option will only be allowed to
++ If you say Y here, all non-root users will be covered under
++ a weaker TPE restriction. This is separate from, and in addition to,
++ the main TPE options that you have selected elsewhere. Thus, if a
++ "trusted" GID is chosen, this restriction applies to even that GID.
++ Under this restriction, all non-root users will only be allowed to
+ execute files in directories they own that are not group or
+ world-writable, or in directories owned by root and writable only by
+ root. If the sysctl option is enabled, a sysctl option with name
@@ -44214,31 +44630,27 @@ diff -urNp linux-2.6.32.21/grsecurity/Kconfig linux-2.6.32.21/grsecurity/Kconfig
+ If you say Y here, the group you specify in the TPE configuration will
+ decide what group TPE restrictions will be *disabled* for. This
+ option is useful if you want TPE restrictions to be applied to most
-+ users on the system.
++ users on the system. If the sysctl option is enabled, a sysctl option
++ with name "tpe_invert" is created. Unlike other sysctl options, this
++ entry will default to on for backward-compatibility.
+
+config GRKERNSEC_TPE_GID
+ int "GID for untrusted users"
+ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
+ default 1005
+ help
-+ If you have selected the "Invert GID option" above, setting this
-+ GID determines what group TPE restrictions will be *disabled* for.
-+ If you have not selected the "Invert GID option" above, setting this
-+ GID determines what group TPE restrictions will be *enabled* for.
-+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
-+ is created.
++ Setting this GID determines what group TPE restrictions will be
++ *enabled* for. If the sysctl option is enabled, a sysctl option
++ with name "tpe_gid" is created.
+
+config GRKERNSEC_TPE_GID
+ int "GID for trusted users"
+ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
+ default 1005
+ help
-+ If you have selected the "Invert GID option" above, setting this
-+ GID determines what group TPE restrictions will be *disabled* for.
-+ If you have not selected the "Invert GID option" above, setting this
-+ GID determines what group TPE restrictions will be *enabled* for.
-+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
-+ is created.
++ Setting this GID determines what group TPE restrictions will be
++ *disabled* for. If the sysctl option is enabled, a sysctl option
++ with name "tpe_gid" is created.
+
+endmenu
+menu "Network Protections"
@@ -46216,7 +46628,7 @@ diff -urNp linux-2.6.32.21/include/linux/grdefs.h linux-2.6.32.21/include/linux/
+#endif
diff -urNp linux-2.6.32.21/include/linux/grinternal.h linux-2.6.32.21/include/linux/grinternal.h
--- linux-2.6.32.21/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.32.21/include/linux/grinternal.h 2010-09-04 15:54:52.000000000 -0400
++++ linux-2.6.32.21/include/linux/grinternal.h 2010-09-17 19:39:50.000000000 -0400
@@ -0,0 +1,211 @@
+#ifndef __GRINTERNAL_H
+#define __GRINTERNAL_H
@@ -46282,7 +46694,7 @@ diff -urNp linux-2.6.32.21/include/linux/grinternal.h linux-2.6.32.21/include/li
+extern int grsec_enable_tpe;
+extern int grsec_tpe_gid;
+extern int grsec_enable_tpe_all;
-+extern int grsec_enable_sidcaps;
++extern int grsec_enable_tpe_invert;
+extern int grsec_enable_socket_all;
+extern int grsec_socket_all_gid;
+extern int grsec_enable_socket_client;
@@ -47499,7 +47911,7 @@ diff -urNp linux-2.6.32.21/include/linux/reiserfs_fs_sb.h linux-2.6.32.21/includ
on-disk FS format */
diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/sched.h
--- linux-2.6.32.21/include/linux/sched.h 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/include/linux/sched.h 2010-09-14 18:41:02.000000000 -0400
++++ linux-2.6.32.21/include/linux/sched.h 2010-09-17 18:34:04.000000000 -0400
@@ -101,6 +101,7 @@ struct bio;
struct fs_struct;
struct bts_context;
@@ -47508,7 +47920,19 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
/*
* List of flags we want to share for kernel threads,
-@@ -667,6 +668,15 @@ struct signal_struct {
+@@ -372,9 +373,11 @@ struct user_namespace;
+ #define DEFAULT_MAX_MAP_COUNT (USHORT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
+
+ extern int sysctl_max_map_count;
++extern unsigned long sysctl_heap_stack_gap;
+
+ #include <linux/aio.h>
+
++extern bool check_heap_stack_gap(struct vm_area_struct *vma, unsigned long addr, unsigned long len);
+ extern unsigned long
+ arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
+ unsigned long, unsigned long);
+@@ -667,6 +670,15 @@ struct signal_struct {
struct tty_audit_buf *tty_audit_buf;
#endif
@@ -47524,7 +47948,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
int oom_adj; /* OOM kill score adjustment (bit shift) */
};
-@@ -1220,7 +1230,7 @@ struct rcu_node;
+@@ -1220,7 +1232,7 @@ struct rcu_node;
struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
@@ -47533,7 +47957,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
atomic_t usage;
unsigned int flags; /* per process flags, defined below */
unsigned int ptrace;
-@@ -1332,8 +1342,8 @@ struct task_struct {
+@@ -1332,8 +1344,8 @@ struct task_struct {
struct list_head thread_group;
struct completion *vfork_done; /* for vfork() */
@@ -47544,7 +47968,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
-@@ -1347,16 +1357,6 @@ struct task_struct {
+@@ -1347,16 +1359,6 @@ struct task_struct {
struct task_cputime cputime_expires;
struct list_head cpu_timers[3];
@@ -47561,7 +47985,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
-@@ -1440,6 +1440,15 @@ struct task_struct {
+@@ -1440,6 +1442,15 @@ struct task_struct {
int hardirq_context;
int softirq_context;
#endif
@@ -47577,7 +48001,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
#ifdef CONFIG_LOCKDEP
# define MAX_LOCK_DEPTH 48UL
u64 curr_chain_key;
-@@ -1460,6 +1469,9 @@ struct task_struct {
+@@ -1460,6 +1471,9 @@ struct task_struct {
struct backing_dev_info *backing_dev_info;
@@ -47587,7 +48011,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
struct io_context *io_context;
unsigned long ptrace_message;
-@@ -1523,6 +1535,20 @@ struct task_struct {
+@@ -1523,6 +1537,20 @@ struct task_struct {
unsigned long default_timer_slack_ns;
struct list_head *scm_work_list;
@@ -47608,7 +48032,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/* Index of current stored adress in ret_stack */
int curr_ret_stack;
-@@ -1546,6 +1572,52 @@ struct task_struct {
+@@ -1546,6 +1574,52 @@ struct task_struct {
#endif /* CONFIG_TRACING */
};
@@ -47661,7 +48085,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
/* Future-safe accessor for struct task_struct's cpus_allowed. */
#define tsk_cpumask(tsk) (&(tsk)->cpus_allowed)
-@@ -2146,7 +2218,7 @@ extern void __cleanup_sighand(struct sig
+@@ -2146,7 +2220,7 @@ extern void __cleanup_sighand(struct sig
extern void exit_itimers(struct signal_struct *);
extern void flush_itimer_signals(void);
@@ -47670,7 +48094,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
extern void daemonize(const char *, ...);
extern int allow_signal(int);
-@@ -2259,8 +2331,8 @@ static inline void unlock_task_sighand(s
+@@ -2259,8 +2333,8 @@ static inline void unlock_task_sighand(s
#ifndef __HAVE_THREAD_FUNCTIONS
@@ -47681,7 +48105,7 @@ diff -urNp linux-2.6.32.21/include/linux/sched.h linux-2.6.32.21/include/linux/s
static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
{
-@@ -2275,13 +2347,17 @@ static inline unsigned long *end_of_stac
+@@ -2275,13 +2349,17 @@ static inline unsigned long *end_of_stac
#endif
@@ -49315,7 +49739,7 @@ diff -urNp linux-2.6.32.21/kernel/fork.c linux-2.6.32.21/kernel/fork.c
new_fs = fs;
diff -urNp linux-2.6.32.21/kernel/futex.c linux-2.6.32.21/kernel/futex.c
--- linux-2.6.32.21/kernel/futex.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/kernel/futex.c 2010-09-04 15:54:52.000000000 -0400
++++ linux-2.6.32.21/kernel/futex.c 2010-09-17 17:43:01.000000000 -0400
@@ -54,6 +54,7 @@
#include <linux/mount.h>
#include <linux/pagemap.h>
@@ -49345,19 +49769,17 @@ diff -urNp linux-2.6.32.21/kernel/futex.c linux-2.6.32.21/kernel/futex.c
restart->futex.val = val;
restart->futex.time = abs_time->tv64;
restart->futex.bitset = bitset;
-@@ -2376,7 +2382,10 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
+@@ -2376,7 +2382,9 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
{
struct robust_list_head __user *head;
unsigned long ret;
-- const struct cred *cred = current_cred(), *pcred;
+#ifndef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ const struct cred *cred = current_cred();
-+ const struct cred *pcred;
+ const struct cred *cred = current_cred(), *pcred;
+#endif
if (!futex_cmpxchg_enabled)
return -ENOSYS;
-@@ -2392,11 +2401,16 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
+@@ -2392,11 +2400,16 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
if (!p)
goto err_unlock;
ret = -EPERM;
@@ -49374,7 +49796,7 @@ diff -urNp linux-2.6.32.21/kernel/futex.c linux-2.6.32.21/kernel/futex.c
head = p->robust_list;
rcu_read_unlock();
}
-@@ -2458,7 +2472,7 @@ retry:
+@@ -2458,7 +2471,7 @@ retry:
*/
static inline int fetch_robust_entry(struct robust_list __user **entry,
struct robust_list __user * __user *head,
@@ -50948,7 +51370,7 @@ diff -urNp linux-2.6.32.21/kernel/sys.c linux-2.6.32.21/kernel/sys.c
}
diff -urNp linux-2.6.32.21/kernel/sysctl.c linux-2.6.32.21/kernel/sysctl.c
--- linux-2.6.32.21/kernel/sysctl.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/kernel/sysctl.c 2010-09-04 15:54:52.000000000 -0400
++++ linux-2.6.32.21/kernel/sysctl.c 2010-09-17 18:34:04.000000000 -0400
@@ -63,6 +63,13 @@
static int deprecated_sysctl_warning(struct __sysctl_args *args);
@@ -51018,7 +51440,21 @@ diff -urNp linux-2.6.32.21/kernel/sysctl.c linux-2.6.32.21/kernel/sysctl.c
{
.ctl_name = CTL_UNNUMBERED,
.procname = "sched_child_runs_first",
-@@ -1803,6 +1844,8 @@ static int do_sysctl_strategy(struct ctl
+@@ -1247,6 +1288,13 @@ static struct ctl_table vm_table[] = {
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
++ {
++ .procname = "heap_stack_gap",
++ .data = &sysctl_heap_stack_gap,
++ .maxlen = sizeof(sysctl_heap_stack_gap),
++ .mode = 0644,
++ .proc_handler = proc_doulongvec_minmax,
++ },
+ #else
+ {
+ .ctl_name = CTL_UNNUMBERED,
+@@ -1803,6 +1851,8 @@ static int do_sysctl_strategy(struct ctl
return 0;
}
@@ -51027,7 +51463,7 @@ diff -urNp linux-2.6.32.21/kernel/sysctl.c linux-2.6.32.21/kernel/sysctl.c
static int parse_table(int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen,
-@@ -1821,7 +1864,7 @@ repeat:
+@@ -1821,7 +1871,7 @@ repeat:
if (n == table->ctl_name) {
int error;
if (table->child) {
@@ -51036,7 +51472,7 @@ diff -urNp linux-2.6.32.21/kernel/sysctl.c linux-2.6.32.21/kernel/sysctl.c
return -EPERM;
name++;
nlen--;
-@@ -1906,6 +1949,33 @@ int sysctl_perm(struct ctl_table_root *r
+@@ -1906,6 +1956,33 @@ int sysctl_perm(struct ctl_table_root *r
int error;
int mode;
@@ -51260,25 +51696,6 @@ diff -urNp linux-2.6.32.21/kernel/trace/ftrace.c linux-2.6.32.21/kernel/trace/ft
}
/*
-diff -urNp linux-2.6.32.21/kernel/trace/Kconfig linux-2.6.32.21/kernel/trace/Kconfig
---- linux-2.6.32.21/kernel/trace/Kconfig 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/kernel/trace/Kconfig 2010-09-04 15:54:52.000000000 -0400
-@@ -126,6 +126,7 @@ if FTRACE
- config FUNCTION_TRACER
- bool "Kernel Function Tracer"
- depends on HAVE_FUNCTION_TRACER
-+ depends on !PAX_KERNEXEC
- select FRAME_POINTER
- select KALLSYMS
- select GENERIC_TRACER
-@@ -343,6 +344,7 @@ config POWER_TRACER
- config STACK_TRACER
- bool "Trace max stack"
- depends on HAVE_FUNCTION_TRACER
-+ depends on !PAX_KERNEXEC
- select FUNCTION_TRACER
- select STACKTRACE
- select KALLSYMS
diff -urNp linux-2.6.32.21/kernel/trace/ring_buffer.c linux-2.6.32.21/kernel/trace/ring_buffer.c
--- linux-2.6.32.21/kernel/trace/ring_buffer.c 2010-08-13 16:24:37.000000000 -0400
+++ linux-2.6.32.21/kernel/trace/ring_buffer.c 2010-09-04 15:54:52.000000000 -0400
@@ -51821,16 +52238,8 @@ diff -urNp linux-2.6.32.21/mm/madvise.c linux-2.6.32.21/mm/madvise.c
goto out;
diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
--- linux-2.6.32.21/mm/memory.c 2010-08-29 21:08:20.000000000 -0400
-+++ linux-2.6.32.21/mm/memory.c 2010-09-04 15:54:52.000000000 -0400
-@@ -48,6 +48,7 @@
- #include <linux/ksm.h>
- #include <linux/rmap.h>
- #include <linux/module.h>
-+#include <linux/security.h>
- #include <linux/delayacct.h>
- #include <linux/init.h>
- #include <linux/writeback.h>
-@@ -187,8 +188,12 @@ static inline void free_pmd_range(struct
++++ linux-2.6.32.21/mm/memory.c 2010-09-17 18:20:06.000000000 -0400
+@@ -187,8 +187,12 @@ static inline void free_pmd_range(struct
return;
pmd = pmd_offset(pud, start);
@@ -51843,7 +52252,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
}
static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
-@@ -220,8 +225,12 @@ static inline void free_pud_range(struct
+@@ -220,8 +224,12 @@ static inline void free_pud_range(struct
return;
pud = pud_offset(pgd, start);
@@ -51856,7 +52265,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
}
/*
-@@ -1251,10 +1260,10 @@ int __get_user_pages(struct task_struct
+@@ -1251,10 +1259,10 @@ int __get_user_pages(struct task_struct
(VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
i = 0;
@@ -51869,7 +52278,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
if (!vma && in_gate_area(tsk, start)) {
unsigned long pg = start & PAGE_MASK;
struct vm_area_struct *gate_vma = get_gate_vma(tsk);
-@@ -1306,7 +1315,7 @@ int __get_user_pages(struct task_struct
+@@ -1306,7 +1314,7 @@ int __get_user_pages(struct task_struct
continue;
}
@@ -51878,7 +52287,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
(vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
!(vm_flags & vma->vm_flags))
return i ? : -EFAULT;
-@@ -1381,7 +1390,7 @@ int __get_user_pages(struct task_struct
+@@ -1381,7 +1389,7 @@ int __get_user_pages(struct task_struct
start += PAGE_SIZE;
nr_pages--;
} while (nr_pages && start < vma->vm_end);
@@ -51887,7 +52296,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
return i;
}
-@@ -1977,6 +1986,186 @@ static inline void cow_user_page(struct
+@@ -1977,6 +1985,186 @@ static inline void cow_user_page(struct
copy_user_highpage(dst, src, va, vma);
}
@@ -52074,7 +52483,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
/*
* This routine handles present pages, when users try to write
* to a shared page. It is done by copying the page to a new address
-@@ -2156,6 +2345,12 @@ gotten:
+@@ -2156,6 +2344,12 @@ gotten:
*/
page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
if (likely(pte_same(*page_table, orig_pte))) {
@@ -52087,7 +52496,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
if (old_page) {
if (!PageAnon(old_page)) {
dec_mm_counter(mm, file_rss);
-@@ -2207,6 +2402,10 @@ gotten:
+@@ -2207,6 +2401,10 @@ gotten:
page_remove_rmap(old_page);
}
@@ -52098,7 +52507,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
/* Free the old page.. */
new_page = old_page;
ret |= VM_FAULT_WRITE;
-@@ -2604,6 +2803,11 @@ static int do_swap_page(struct mm_struct
+@@ -2604,6 +2802,11 @@ static int do_swap_page(struct mm_struct
swap_free(entry);
if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
try_to_free_swap(page);
@@ -52110,7 +52519,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
unlock_page(page);
if (flags & FAULT_FLAG_WRITE) {
-@@ -2615,6 +2819,11 @@ static int do_swap_page(struct mm_struct
+@@ -2615,6 +2818,11 @@ static int do_swap_page(struct mm_struct
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, address, pte);
@@ -52122,7 +52531,41 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
unlock:
pte_unmap_unlock(page_table, ptl);
out:
-@@ -2665,7 +2874,7 @@ static int do_anonymous_page(struct mm_s
+@@ -2630,33 +2838,6 @@ out_release:
+ }
+
+ /*
+- * This is like a special single-page "expand_downwards()",
+- * except we must first make sure that 'address-PAGE_SIZE'
+- * doesn't hit another vma.
+- *
+- * The "find_vma()" will do the right thing even if we wrap
+- */
+-static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
+-{
+- address &= PAGE_MASK;
+- if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
+- struct vm_area_struct *prev = vma->vm_prev;
+-
+- /*
+- * Is there a mapping abutting this one below?
+- *
+- * That's only ok if it's the same stack mapping
+- * that has gotten split..
+- */
+- if (prev && prev->vm_end == address)
+- return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
+-
+- expand_stack(vma, address - PAGE_SIZE);
+- }
+- return 0;
+-}
+-
+-/*
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
+@@ -2665,27 +2846,23 @@ static int do_anonymous_page(struct mm_s
unsigned long address, pte_t *page_table, pmd_t *pmd,
unsigned int flags)
{
@@ -52131,7 +52574,31 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
spinlock_t *ptl;
pte_t entry;
-@@ -2704,6 +2913,11 @@ static int do_anonymous_page(struct mm_s
+- pte_unmap(page_table);
+-
+- /* Check if we need to add a guard page to the stack */
+- if (check_stack_guard_page(vma, address) < 0)
+- return VM_FAULT_SIGBUS;
+-
+- /* Use the zero-page for reads */
+ if (!(flags & FAULT_FLAG_WRITE)) {
+ entry = pte_mkspecial(pfn_pte(my_zero_pfn(address),
+ vma->vm_page_prot));
+- page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
++ ptl = pte_lockptr(mm, pmd);
++ spin_lock(ptl);
+ if (!pte_none(*page_table))
+ goto unlock;
+ goto setpte;
+ }
+
+ /* Allocate our own private page. */
++ pte_unmap(page_table);
++
+ if (unlikely(anon_vma_prepare(vma)))
+ goto oom;
+ page = alloc_zeroed_user_highpage_movable(vma, address);
+@@ -2704,6 +2881,11 @@ static int do_anonymous_page(struct mm_s
if (!pte_none(*page_table))
goto release;
@@ -52143,7 +52610,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
inc_mm_counter(mm, anon_rss);
page_add_new_anon_rmap(page, vma, address);
setpte:
-@@ -2711,6 +2925,12 @@ setpte:
+@@ -2711,6 +2893,12 @@ setpte:
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, address, entry);
@@ -52156,7 +52623,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
unlock:
pte_unmap_unlock(page_table, ptl);
return 0;
-@@ -2853,6 +3073,12 @@ static int __do_fault(struct mm_struct *
+@@ -2853,6 +3041,12 @@ static int __do_fault(struct mm_struct *
*/
/* Only go through if we didn't race with anybody else... */
if (likely(pte_same(*page_table, orig_pte))) {
@@ -52169,7 +52636,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
flush_icache_page(vma, page);
entry = mk_pte(page, vma->vm_page_prot);
if (flags & FAULT_FLAG_WRITE)
-@@ -2872,6 +3098,14 @@ static int __do_fault(struct mm_struct *
+@@ -2872,6 +3066,14 @@ static int __do_fault(struct mm_struct *
/* no need to invalidate: a not-present page won't be cached */
update_mmu_cache(vma, address, entry);
@@ -52184,7 +52651,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
} else {
if (charged)
mem_cgroup_uncharge_page(page);
-@@ -3019,6 +3253,12 @@ static inline int handle_pte_fault(struc
+@@ -3019,6 +3221,12 @@ static inline int handle_pte_fault(struc
if (flags & FAULT_FLAG_WRITE)
flush_tlb_page(vma, address);
}
@@ -52197,7 +52664,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
unlock:
pte_unmap_unlock(pte, ptl);
return 0;
-@@ -3035,6 +3275,10 @@ int handle_mm_fault(struct mm_struct *mm
+@@ -3035,6 +3243,10 @@ int handle_mm_fault(struct mm_struct *mm
pmd_t *pmd;
pte_t *pte;
@@ -52208,7 +52675,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
__set_current_state(TASK_RUNNING);
count_vm_event(PGFAULT);
-@@ -3042,6 +3286,34 @@ int handle_mm_fault(struct mm_struct *mm
+@@ -3042,6 +3254,34 @@ int handle_mm_fault(struct mm_struct *mm
if (unlikely(is_vm_hugetlb_page(vma)))
return hugetlb_fault(mm, vma, address, flags);
@@ -52243,7 +52710,7 @@ diff -urNp linux-2.6.32.21/mm/memory.c linux-2.6.32.21/mm/memory.c
pgd = pgd_offset(mm, address);
pud = pud_alloc(mm, pgd, address);
if (!pud)
-@@ -3139,7 +3411,7 @@ static int __init gate_vma_init(void)
+@@ -3139,7 +3379,7 @@ static int __init gate_vma_init(void)
gate_vma.vm_start = FIXADDR_USER_START;
gate_vma.vm_end = FIXADDR_USER_END;
gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
@@ -52386,7 +52853,7 @@ diff -urNp linux-2.6.32.21/mm/migrate.c linux-2.6.32.21/mm/migrate.c
goto out;
diff -urNp linux-2.6.32.21/mm/mlock.c linux-2.6.32.21/mm/mlock.c
--- linux-2.6.32.21/mm/mlock.c 2010-08-29 21:08:20.000000000 -0400
-+++ linux-2.6.32.21/mm/mlock.c 2010-09-04 15:54:56.000000000 -0400
++++ linux-2.6.32.21/mm/mlock.c 2010-09-17 18:47:09.000000000 -0400
@@ -13,6 +13,7 @@
#include <linux/pagemap.h>
#include <linux/mempolicy.h>
@@ -52395,7 +52862,40 @@ diff -urNp linux-2.6.32.21/mm/mlock.c linux-2.6.32.21/mm/mlock.c
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/rmap.h>
-@@ -454,6 +455,9 @@ static int do_mlock(unsigned long start,
+@@ -138,19 +139,6 @@ void munlock_vma_page(struct page *page)
+ }
+ }
+
+-/* Is the vma a continuation of the stack vma above it? */
+-static inline int vma_stack_continue(struct vm_area_struct *vma, unsigned long addr)
+-{
+- return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN);
+-}
+-
+-static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr)
+-{
+- return (vma->vm_flags & VM_GROWSDOWN) &&
+- (vma->vm_start == addr) &&
+- !vma_stack_continue(vma->vm_prev, addr);
+-}
+-
+ /**
+ * __mlock_vma_pages_range() - mlock a range of pages in the vma.
+ * @vma: target vma
+@@ -183,12 +171,6 @@ static long __mlock_vma_pages_range(stru
+ if (vma->vm_flags & VM_WRITE)
+ gup_flags |= FOLL_WRITE;
+
+- /* We don't try to access the guard page of a stack vma */
+- if (stack_guard_page(vma, start)) {
+- addr += PAGE_SIZE;
+- nr_pages--;
+- }
+-
+ while (nr_pages > 0) {
+ int i;
+
+@@ -454,6 +436,9 @@ static int do_mlock(unsigned long start,
return -EINVAL;
if (end == start)
return 0;
@@ -52405,7 +52905,7 @@ diff -urNp linux-2.6.32.21/mm/mlock.c linux-2.6.32.21/mm/mlock.c
vma = find_vma_prev(current->mm, start, &prev);
if (!vma || vma->vm_start > start)
return -ENOMEM;
-@@ -464,6 +468,11 @@ static int do_mlock(unsigned long start,
+@@ -464,6 +449,11 @@ static int do_mlock(unsigned long start,
for (nstart = start ; ; ) {
unsigned int newflags;
@@ -52417,7 +52917,7 @@ diff -urNp linux-2.6.32.21/mm/mlock.c linux-2.6.32.21/mm/mlock.c
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */
newflags = vma->vm_flags | VM_LOCKED;
-@@ -513,6 +522,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
+@@ -513,6 +503,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
lock_limit >>= PAGE_SHIFT;
/* check against resource limits */
@@ -52425,7 +52925,7 @@ diff -urNp linux-2.6.32.21/mm/mlock.c linux-2.6.32.21/mm/mlock.c
if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
error = do_mlock(start, len, 1);
up_write(&current->mm->mmap_sem);
-@@ -534,17 +544,23 @@ SYSCALL_DEFINE2(munlock, unsigned long,
+@@ -534,17 +525,23 @@ SYSCALL_DEFINE2(munlock, unsigned long,
static int do_mlockall(int flags)
{
struct vm_area_struct * vma, * prev = NULL;
@@ -52453,17 +52953,17 @@ diff -urNp linux-2.6.32.21/mm/mlock.c linux-2.6.32.21/mm/mlock.c
newflags = vma->vm_flags | VM_LOCKED;
if (!(flags & MCL_CURRENT))
newflags &= ~VM_LOCKED;
-@@ -576,6 +592,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
+@@ -576,6 +573,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
lock_limit >>= PAGE_SHIFT;
ret = -ENOMEM;
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm << PAGE_SHIFT, 1);
if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
capable(CAP_IPC_LOCK))
ret = do_mlockall(flags);
diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
--- linux-2.6.32.21/mm/mmap.c 2010-08-29 21:08:20.000000000 -0400
-+++ linux-2.6.32.21/mm/mmap.c 2010-09-04 15:54:52.000000000 -0400
++++ linux-2.6.32.21/mm/mmap.c 2010-09-17 18:34:04.000000000 -0400
@@ -45,6 +45,16 @@
#define arch_rebalance_pgtables(addr, len) (addr)
#endif
@@ -52481,7 +52981,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
unsigned long start, unsigned long end);
-@@ -70,16 +80,25 @@ static void unmap_region(struct mm_struc
+@@ -70,22 +80,32 @@ static void unmap_region(struct mm_struc
* x: (no) no x: (no) yes x: (no) yes x: (yes) yes
*
*/
@@ -52509,7 +53009,14 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
}
EXPORT_SYMBOL(vm_get_page_prot);
-@@ -231,6 +250,7 @@ static struct vm_area_struct *remove_vma
+ int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
+ int sysctl_overcommit_ratio = 50; /* default is 50% */
+ int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
++unsigned long sysctl_heap_stack_gap __read_mostly = 64*1024;
+ struct percpu_counter vm_committed_as;
+
+ /*
+@@ -231,6 +251,7 @@ static struct vm_area_struct *remove_vma
struct vm_area_struct *next = vma->vm_next;
might_sleep();
@@ -52517,7 +53024,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
if (vma->vm_file) {
-@@ -267,6 +287,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
+@@ -267,6 +288,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
* not page aligned -Ram Gupta
*/
rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
@@ -52525,7 +53032,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
(mm->end_data - mm->start_data) > rlim)
goto out;
-@@ -704,6 +725,12 @@ static int
+@@ -704,6 +726,12 @@ static int
can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
{
@@ -52538,7 +53045,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (is_mergeable_vma(vma, file, vm_flags) &&
is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
if (vma->vm_pgoff == vm_pgoff)
-@@ -723,6 +750,12 @@ static int
+@@ -723,6 +751,12 @@ static int
can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
{
@@ -52551,7 +53058,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (is_mergeable_vma(vma, file, vm_flags) &&
is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
pgoff_t vm_pglen;
-@@ -765,12 +798,19 @@ can_vma_merge_after(struct vm_area_struc
+@@ -765,12 +799,19 @@ can_vma_merge_after(struct vm_area_struc
struct vm_area_struct *vma_merge(struct mm_struct *mm,
struct vm_area_struct *prev, unsigned long addr,
unsigned long end, unsigned long vm_flags,
@@ -52572,7 +53079,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* We later require that vma->vm_flags == vm_flags,
* so this tests vma->vm_flags & VM_SPECIAL, too.
-@@ -786,6 +826,15 @@ struct vm_area_struct *vma_merge(struct
+@@ -786,6 +827,15 @@ struct vm_area_struct *vma_merge(struct
if (next && next->vm_end == end) /* cases 6, 7, 8 */
next = next->vm_next;
@@ -52588,7 +53095,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* Can it merge with the predecessor?
*/
-@@ -805,9 +854,24 @@ struct vm_area_struct *vma_merge(struct
+@@ -805,9 +855,24 @@ struct vm_area_struct *vma_merge(struct
/* cases 1, 6 */
vma_adjust(prev, prev->vm_start,
next->vm_end, prev->vm_pgoff, NULL);
@@ -52614,7 +53121,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return prev;
}
-@@ -818,12 +882,27 @@ struct vm_area_struct *vma_merge(struct
+@@ -818,12 +883,27 @@ struct vm_area_struct *vma_merge(struct
mpol_equal(policy, vma_policy(next)) &&
can_vma_merge_before(next, vm_flags,
anon_vma, file, pgoff+pglen)) {
@@ -52644,7 +53151,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return area;
}
-@@ -898,14 +977,11 @@ none:
+@@ -898,14 +978,11 @@ none:
void vm_stat_account(struct mm_struct *mm, unsigned long flags,
struct file *file, long pages)
{
@@ -52660,7 +53167,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
mm->stack_vm += pages;
if (flags & (VM_RESERVED|VM_IO))
mm->reserved_vm += pages;
-@@ -932,7 +1008,7 @@ unsigned long do_mmap_pgoff(struct file
+@@ -932,7 +1009,7 @@ unsigned long do_mmap_pgoff(struct file
* (the exception is when the underlying filesystem is noexec
* mounted, in which case we dont add PROT_EXEC.)
*/
@@ -52669,7 +53176,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
prot |= PROT_EXEC;
-@@ -958,7 +1034,7 @@ unsigned long do_mmap_pgoff(struct file
+@@ -958,7 +1035,7 @@ unsigned long do_mmap_pgoff(struct file
/* Obtain the address to map to. we verify (or select) it and ensure
* that it represents a valid section of the address space.
*/
@@ -52678,7 +53185,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (addr & ~PAGE_MASK)
return addr;
-@@ -969,6 +1045,28 @@ unsigned long do_mmap_pgoff(struct file
+@@ -969,6 +1046,28 @@ unsigned long do_mmap_pgoff(struct file
vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
@@ -52707,7 +53214,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (flags & MAP_LOCKED)
if (!can_do_mlock())
return -EPERM;
-@@ -980,6 +1078,7 @@ unsigned long do_mmap_pgoff(struct file
+@@ -980,6 +1079,7 @@ unsigned long do_mmap_pgoff(struct file
locked += mm->locked_vm;
lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
lock_limit >>= PAGE_SHIFT;
@@ -52715,7 +53222,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
return -EAGAIN;
}
-@@ -1053,6 +1152,9 @@ unsigned long do_mmap_pgoff(struct file
+@@ -1053,6 +1153,9 @@ unsigned long do_mmap_pgoff(struct file
if (error)
return error;
@@ -52725,7 +53232,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return mmap_region(file, addr, len, flags, vm_flags, pgoff);
}
EXPORT_SYMBOL(do_mmap_pgoff);
-@@ -1065,10 +1167,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
+@@ -1065,10 +1168,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
*/
int vma_wants_writenotify(struct vm_area_struct *vma)
{
@@ -52738,7 +53245,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return 0;
/* The backer wishes to know when pages are first written to? */
-@@ -1117,14 +1219,24 @@ unsigned long mmap_region(struct file *f
+@@ -1117,14 +1220,24 @@ unsigned long mmap_region(struct file *f
unsigned long charged = 0;
struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
@@ -52765,7 +53272,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
}
/* Check against address space limit. */
-@@ -1173,6 +1285,16 @@ munmap_back:
+@@ -1173,6 +1286,16 @@ munmap_back:
goto unacct_error;
}
@@ -52782,7 +53289,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
vma->vm_mm = mm;
vma->vm_start = addr;
vma->vm_end = addr + len;
-@@ -1195,6 +1317,19 @@ munmap_back:
+@@ -1195,6 +1318,19 @@ munmap_back:
error = file->f_op->mmap(file, vma);
if (error)
goto unmap_and_free_vma;
@@ -52802,7 +53309,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (vm_flags & VM_EXECUTABLE)
added_exe_file_vma(mm);
-@@ -1218,6 +1353,11 @@ munmap_back:
+@@ -1218,6 +1354,11 @@ munmap_back:
vma_link(mm, vma, prev, rb_link, rb_parent);
file = vma->vm_file;
@@ -52814,7 +53321,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/* Once vma denies write, undo our temporary denial count */
if (correct_wcount)
atomic_inc(&inode->i_writecount);
-@@ -1226,6 +1366,7 @@ out:
+@@ -1226,6 +1367,7 @@ out:
mm->total_vm += len >> PAGE_SHIFT;
vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
@@ -52822,7 +53329,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (vm_flags & VM_LOCKED) {
/*
* makes pages present; downgrades, drops, reacquires mmap_sem
-@@ -1248,6 +1389,12 @@ unmap_and_free_vma:
+@@ -1248,6 +1390,12 @@ unmap_and_free_vma:
unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
charged = 0;
free_vma:
@@ -52835,7 +53342,41 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
kmem_cache_free(vm_area_cachep, vma);
unacct_error:
if (charged)
-@@ -1281,6 +1428,10 @@ arch_get_unmapped_area(struct file *filp
+@@ -1255,6 +1403,33 @@ unacct_error:
+ return error;
+ }
+
++bool check_heap_stack_gap(struct vm_area_struct *vma, unsigned long addr, unsigned long len)
++{
++ if (!vma) {
++#ifdef CONFIG_STACK_GROWSUP
++ if (addr > sysctl_heap_stack_gap)
++ vma = find_vma(current->mm, addr - sysctl_heap_stack_gap);
++ else
++ vma = find_vma(current->mm, 0);
++ if (vma && (vma->vm_flags & VM_GROWSUP))
++ return false;
++#endif
++ return true;
++ }
++
++ if (addr + len > vma->vm_start)
++ return false;
++
++ if (vma->vm_flags & VM_GROWSDOWN)
++ return sysctl_heap_stack_gap <= vma->vm_start - addr - len;
++#ifdef CONFIG_STACK_GROWSUP
++ else if (vma->vm_prev && (vma->vm_prev->vm_flags & VM_GROWSUP))
++ return addr - vma->vm_prev->vm_end <= sysctl_heap_stack_gap;
++#endif
++
++ return true;
++}
++
+ /* Get an address range which is currently unmapped.
+ * For shmat() with addr=0.
+ *
+@@ -1281,18 +1456,23 @@ arch_get_unmapped_area(struct file *filp
if (flags & MAP_FIXED)
return addr;
@@ -52845,9 +53386,15 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
+
if (addr) {
addr = PAGE_ALIGN(addr);
- vma = find_vma(mm, addr);
-@@ -1289,10 +1440,10 @@ arch_get_unmapped_area(struct file *filp
- return addr;
+- vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
+- return addr;
++ if (TASK_SIZE - len >= addr) {
++ vma = find_vma(mm, addr);
++ if (check_heap_stack_gap(vma, addr, len))
++ return addr;
++ }
}
if (len > mm->cached_hole_size) {
- start_addr = addr = mm->free_area_cache;
@@ -52860,7 +53407,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
}
full_search:
-@@ -1303,9 +1454,8 @@ full_search:
+@@ -1303,34 +1483,40 @@ full_search:
* Start a new search - just in case we missed
* some holes.
*/
@@ -52872,7 +53419,29 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
mm->cached_hole_size = 0;
goto full_search;
}
-@@ -1327,10 +1477,16 @@ full_search:
+ return -ENOMEM;
+ }
+- if (!vma || addr + len <= vma->vm_start) {
+- /*
+- * Remember the place where we stopped the search:
+- */
+- mm->free_area_cache = addr + len;
+- return addr;
+- }
++ if (check_heap_stack_gap(vma, addr, len))
++ break;
+ if (addr + mm->cached_hole_size < vma->vm_start)
+ mm->cached_hole_size = vma->vm_start - addr;
+ addr = vma->vm_end;
+ }
++
++ /*
++ * Remember the place where we stopped the search:
++ */
++ mm->free_area_cache = addr + len;
++ return addr;
+ }
+ #endif
void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
{
@@ -52890,7 +53459,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
mm->free_area_cache = addr;
mm->cached_hole_size = ~0UL;
}
-@@ -1348,7 +1504,7 @@ arch_get_unmapped_area_topdown(struct fi
+@@ -1348,7 +1534,7 @@ arch_get_unmapped_area_topdown(struct fi
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
@@ -52899,7 +53468,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/* requested length too big for entire address space */
if (len > TASK_SIZE)
-@@ -1357,6 +1513,10 @@ arch_get_unmapped_area_topdown(struct fi
+@@ -1357,13 +1543,18 @@ arch_get_unmapped_area_topdown(struct fi
if (flags & MAP_FIXED)
return addr;
@@ -52910,7 +53479,37 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/* requesting a specific address */
if (addr) {
addr = PAGE_ALIGN(addr);
-@@ -1414,13 +1574,21 @@ bottomup:
+- vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
+- return addr;
++ if (TASK_SIZE - len >= addr) {
++ vma = find_vma(mm, addr);
++ if (check_heap_stack_gap(vma, addr, len))
++ return addr;
++ }
+ }
+
+ /* check if free_area_cache is useful for us */
+@@ -1378,7 +1569,7 @@ arch_get_unmapped_area_topdown(struct fi
+ /* make sure it can fit in the remaining address space */
+ if (addr > len) {
+ vma = find_vma(mm, addr-len);
+- if (!vma || addr <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr - len, len))
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr-len);
+ }
+@@ -1395,7 +1586,7 @@ arch_get_unmapped_area_topdown(struct fi
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
+- if (!vma || addr+len <= vma->vm_start)
++ if (check_heap_stack_gap(vma, addr, len))
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr);
+
+@@ -1414,13 +1605,21 @@ bottomup:
* can happen with large stack limits and large mmap()
* allocations.
*/
@@ -52934,7 +53533,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
mm->cached_hole_size = ~0UL;
return addr;
-@@ -1429,6 +1597,12 @@ bottomup:
+@@ -1429,6 +1628,12 @@ bottomup:
void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
{
@@ -52947,7 +53546,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* Is this a new hole at the highest possible address?
*/
-@@ -1436,8 +1610,10 @@ void arch_unmap_area_topdown(struct mm_s
+@@ -1436,8 +1641,10 @@ void arch_unmap_area_topdown(struct mm_s
mm->free_area_cache = addr;
/* dont allow allocations above current base */
@@ -52959,7 +53558,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
}
unsigned long
-@@ -1545,6 +1721,27 @@ out:
+@@ -1545,6 +1752,27 @@ out:
return prev ? prev->vm_next : vma;
}
@@ -52987,7 +53586,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* Verify that the stack growth is acceptable and
* update accounting. This is shared with both the
-@@ -1561,6 +1758,7 @@ static int acct_stack_growth(struct vm_a
+@@ -1561,6 +1789,7 @@ static int acct_stack_growth(struct vm_a
return -ENOMEM;
/* Stack limit test */
@@ -52995,7 +53594,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (size > rlim[RLIMIT_STACK].rlim_cur)
return -ENOMEM;
-@@ -1570,6 +1768,7 @@ static int acct_stack_growth(struct vm_a
+@@ -1570,6 +1799,7 @@ static int acct_stack_growth(struct vm_a
unsigned long limit;
locked = mm->locked_vm + grow;
limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
@@ -53003,7 +53602,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (locked > limit && !capable(CAP_IPC_LOCK))
return -ENOMEM;
}
-@@ -1605,35 +1804,40 @@ static
+@@ -1605,35 +1835,42 @@ static
#endif
int expand_upwards(struct vm_area_struct *vma, unsigned long address)
{
@@ -53026,7 +53625,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (unlikely(anon_vma_prepare(vma)))
return -ENOMEM;
+ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
-+ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
++ if (locknext && anon_vma_prepare(vma->vm_next))
+ return -ENOMEM;
anon_vma_lock(vma);
+ if (locknext)
@@ -53050,11 +53649,13 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/* Somebody else might have raced and expanded it already */
- if (address > vma->vm_end) {
-+ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
++ if (vma->vm_next && (vma->vm_next->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) && vma->vm_next->vm_start - address < sysctl_heap_stack_gap)
++ error = -ENOMEM;
++ else if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
unsigned long size, grow;
size = address - vma->vm_start;
-@@ -1643,6 +1847,8 @@ int expand_upwards(struct vm_area_struct
+@@ -1643,6 +1880,8 @@ int expand_upwards(struct vm_area_struct
if (!error)
vma->vm_end = address;
}
@@ -53063,25 +53664,25 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
anon_vma_unlock(vma);
return error;
}
-@@ -1654,7 +1860,8 @@ int expand_upwards(struct vm_area_struct
+@@ -1654,7 +1893,8 @@ int expand_upwards(struct vm_area_struct
static int expand_downwards(struct vm_area_struct *vma,
unsigned long address)
{
- int error;
+ int error, lockprev = 0;
-+ struct vm_area_struct *prev = NULL;
++ struct vm_area_struct *prev;
/*
* We must make sure the anon_vma is allocated
-@@ -1668,6 +1875,15 @@ static int expand_downwards(struct vm_ar
+@@ -1668,6 +1908,15 @@ static int expand_downwards(struct vm_ar
if (error)
return error;
++ prev = vma->vm_prev;
+#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
-+ find_vma_prev(vma->vm_mm, address, &prev);
+ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
+#endif
-+ if (lockprev && unlikely(anon_vma_prepare(prev)))
++ if (lockprev && anon_vma_prepare(prev))
+ return -ENOMEM;
+ if (lockprev)
+ anon_vma_lock(prev);
@@ -53089,12 +53690,14 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
anon_vma_lock(vma);
/*
-@@ -1677,9 +1893,15 @@ static int expand_downwards(struct vm_ar
+@@ -1677,9 +1926,17 @@ static int expand_downwards(struct vm_ar
*/
/* Somebody else might have raced and expanded it already */
- if (address < vma->vm_start) {
-+ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
++ if (prev && (prev->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) && address - prev->vm_end < sysctl_heap_stack_gap)
++ error = -ENOMEM;
++ else if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
unsigned long size, grow;
+#ifdef CONFIG_PAX_SEGMEXEC
@@ -53106,7 +53709,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
size = vma->vm_end - address;
grow = (vma->vm_start - address) >> PAGE_SHIFT;
-@@ -1687,9 +1909,20 @@ static int expand_downwards(struct vm_ar
+@@ -1687,9 +1944,20 @@ static int expand_downwards(struct vm_ar
if (!error) {
vma->vm_start = address;
vma->vm_pgoff -= grow;
@@ -53127,7 +53730,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return error;
}
-@@ -1765,6 +1998,13 @@ static void remove_vma_list(struct mm_st
+@@ -1765,6 +2033,13 @@ static void remove_vma_list(struct mm_st
do {
long nrpages = vma_pages(vma);
@@ -53141,7 +53744,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
mm->total_vm -= nrpages;
vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
vma = remove_vma(vma);
-@@ -1810,6 +2050,16 @@ detach_vmas_to_be_unmapped(struct mm_str
+@@ -1810,6 +2085,16 @@ detach_vmas_to_be_unmapped(struct mm_str
insertion_point = (prev ? &prev->vm_next : &mm->mmap);
vma->vm_prev = NULL;
do {
@@ -53158,7 +53761,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
rb_erase(&vma->vm_rb, &mm->mm_rb);
mm->map_count--;
tail_vma = vma;
-@@ -1837,10 +2087,25 @@ int split_vma(struct mm_struct * mm, str
+@@ -1837,10 +2122,25 @@ int split_vma(struct mm_struct * mm, str
struct mempolicy *pol;
struct vm_area_struct *new;
@@ -53184,7 +53787,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
-@@ -1848,6 +2113,16 @@ int split_vma(struct mm_struct * mm, str
+@@ -1848,6 +2148,16 @@ int split_vma(struct mm_struct * mm, str
if (!new)
return -ENOMEM;
@@ -53201,7 +53804,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/* most fields are the same, copy all, and then fixup */
*new = *vma;
-@@ -1858,8 +2133,29 @@ int split_vma(struct mm_struct * mm, str
+@@ -1858,8 +2168,29 @@ int split_vma(struct mm_struct * mm, str
new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
}
@@ -53231,7 +53834,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
kmem_cache_free(vm_area_cachep, new);
return PTR_ERR(pol);
}
-@@ -1880,6 +2176,28 @@ int split_vma(struct mm_struct * mm, str
+@@ -1880,6 +2211,28 @@ int split_vma(struct mm_struct * mm, str
else
vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
@@ -53260,7 +53863,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return 0;
}
-@@ -1888,11 +2206,30 @@ int split_vma(struct mm_struct * mm, str
+@@ -1888,11 +2241,30 @@ int split_vma(struct mm_struct * mm, str
* work. This now handles partial unmappings.
* Jeremy Fitzhardinge <jeremy@goop.org>
*/
@@ -53291,7 +53894,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
return -EINVAL;
-@@ -1956,6 +2293,8 @@ int do_munmap(struct mm_struct *mm, unsi
+@@ -1956,6 +2328,8 @@ int do_munmap(struct mm_struct *mm, unsi
/* Fix up all other VM information */
remove_vma_list(mm, vma);
@@ -53300,7 +53903,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return 0;
}
-@@ -1968,22 +2307,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a
+@@ -1968,22 +2342,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a
profile_munmap(addr);
@@ -53329,7 +53932,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* this is really a simplified "do_mmap". it only handles
* anonymous maps. eventually we may be able to do some
-@@ -1997,6 +2332,7 @@ unsigned long do_brk(unsigned long addr,
+@@ -1997,6 +2367,7 @@ unsigned long do_brk(unsigned long addr,
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
int error;
@@ -53337,7 +53940,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
len = PAGE_ALIGN(len);
if (!len)
-@@ -2008,16 +2344,30 @@ unsigned long do_brk(unsigned long addr,
+@@ -2008,16 +2379,30 @@ unsigned long do_brk(unsigned long addr,
flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
@@ -53369,7 +53972,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
locked += mm->locked_vm;
lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
lock_limit >>= PAGE_SHIFT;
-@@ -2034,22 +2384,22 @@ unsigned long do_brk(unsigned long addr,
+@@ -2034,22 +2419,22 @@ unsigned long do_brk(unsigned long addr,
/*
* Clear old maps. this also does some error checking for us
*/
@@ -53396,7 +53999,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return -ENOMEM;
/* Can we just expand an old private anonymous mapping? */
-@@ -2063,7 +2413,7 @@ unsigned long do_brk(unsigned long addr,
+@@ -2063,7 +2448,7 @@ unsigned long do_brk(unsigned long addr,
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (!vma) {
@@ -53405,7 +54008,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return -ENOMEM;
}
-@@ -2075,11 +2425,12 @@ unsigned long do_brk(unsigned long addr,
+@@ -2075,11 +2460,12 @@ unsigned long do_brk(unsigned long addr,
vma->vm_page_prot = vm_get_page_prot(flags);
vma_link(mm, vma, prev, rb_link, rb_parent);
out:
@@ -53420,7 +54023,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return addr;
}
-@@ -2126,8 +2477,10 @@ void exit_mmap(struct mm_struct *mm)
+@@ -2126,8 +2512,10 @@ void exit_mmap(struct mm_struct *mm)
* Walk the list again, actually closing and freeing it,
* with preemption enabled, without holding any MM locks.
*/
@@ -53432,7 +54035,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
}
-@@ -2141,6 +2494,10 @@ int insert_vm_struct(struct mm_struct *
+@@ -2141,6 +2529,10 @@ int insert_vm_struct(struct mm_struct *
struct vm_area_struct * __vma, * prev;
struct rb_node ** rb_link, * rb_parent;
@@ -53443,7 +54046,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* The vm_pgoff of a purely anonymous vma should be irrelevant
* until its first write fault, when page's anon_vma and index
-@@ -2163,7 +2520,22 @@ int insert_vm_struct(struct mm_struct *
+@@ -2163,7 +2555,22 @@ int insert_vm_struct(struct mm_struct *
if ((vma->vm_flags & VM_ACCOUNT) &&
security_vm_enough_memory_mm(mm, vma_pages(vma)))
return -ENOMEM;
@@ -53466,7 +54069,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
return 0;
}
-@@ -2181,6 +2553,8 @@ struct vm_area_struct *copy_vma(struct v
+@@ -2181,6 +2588,8 @@ struct vm_area_struct *copy_vma(struct v
struct rb_node **rb_link, *rb_parent;
struct mempolicy *pol;
@@ -53475,7 +54078,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* If anonymous vma has not yet been faulted, update new pgoff
* to match new location, to increase its chance of merging.
-@@ -2224,6 +2598,35 @@ struct vm_area_struct *copy_vma(struct v
+@@ -2224,6 +2633,35 @@ struct vm_area_struct *copy_vma(struct v
return new_vma;
}
@@ -53511,7 +54114,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
/*
* Return true if the calling process may expand its vm space by the passed
* number of pages
-@@ -2234,7 +2637,7 @@ int may_expand_vm(struct mm_struct *mm,
+@@ -2234,7 +2672,7 @@ int may_expand_vm(struct mm_struct *mm,
unsigned long lim;
lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
@@ -53520,7 +54123,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
if (cur + npages > lim)
return 0;
return 1;
-@@ -2303,6 +2706,17 @@ int install_special_mapping(struct mm_st
+@@ -2303,6 +2741,17 @@ int install_special_mapping(struct mm_st
vma->vm_start = addr;
vma->vm_end = addr + len;
@@ -53540,7 +54143,7 @@ diff -urNp linux-2.6.32.21/mm/mmap.c linux-2.6.32.21/mm/mmap.c
diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
--- linux-2.6.32.21/mm/mprotect.c 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/mm/mprotect.c 2010-09-04 15:54:52.000000000 -0400
++++ linux-2.6.32.21/mm/mprotect.c 2010-09-17 18:34:04.000000000 -0400
@@ -24,10 +24,16 @@
#include <linux/mmu_notifier.h>
#include <linux/migrate.h>
@@ -53607,7 +54210,7 @@ diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
int
mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
unsigned long start, unsigned long end, unsigned long newflags)
-@@ -144,6 +192,14 @@ mprotect_fixup(struct vm_area_struct *vm
+@@ -144,11 +192,29 @@ mprotect_fixup(struct vm_area_struct *vm
int error;
int dirty_accountable = 0;
@@ -53622,7 +54225,22 @@ diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
if (newflags == oldflags) {
*pprev = vma;
return 0;
-@@ -165,6 +221,38 @@ mprotect_fixup(struct vm_area_struct *vm
+ }
+
++ if (newflags & (VM_READ | VM_WRITE | VM_EXEC)) {
++ struct vm_area_struct *prev = vma->vm_prev, *next = vma->vm_next;
++
++ if (next && (next->vm_flags & VM_GROWSDOWN) && sysctl_heap_stack_gap > next->vm_start - end)
++ return -ENOMEM;
++
++ if (prev && (prev->vm_flags & VM_GROWSUP) && sysctl_heap_stack_gap > start - prev->vm_end)
++ return -ENOMEM;
++ }
++
+ /*
+ * If we make a private mapping writable we increase our commit;
+ * but (without finer accounting) cannot reduce our commit if we
+@@ -165,6 +231,38 @@ mprotect_fixup(struct vm_area_struct *vm
}
}
@@ -53661,7 +54279,7 @@ diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
/*
* First try to merge with previous and/or next vma.
*/
-@@ -195,9 +283,21 @@ success:
+@@ -195,9 +293,21 @@ success:
* vm_flags and vm_page_prot are protected by the mmap_sem
* held in write mode.
*/
@@ -53684,7 +54302,7 @@ diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
if (vma_wants_writenotify(vma)) {
vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
-@@ -238,6 +338,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
+@@ -238,6 +348,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
end = start + len;
if (end <= start)
return -ENOMEM;
@@ -53702,7 +54320,7 @@ diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
if (!arch_validate_prot(prot))
return -EINVAL;
-@@ -245,7 +356,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
+@@ -245,7 +366,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
/*
* Does the application expect PROT_READ to imply PROT_EXEC:
*/
@@ -53711,7 +54329,7 @@ diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
prot |= PROT_EXEC;
vm_flags = calc_vm_prot_bits(prot);
-@@ -277,6 +388,16 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
+@@ -277,6 +398,16 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
if (start > vma->vm_start)
prev = vma;
@@ -53728,7 +54346,7 @@ diff -urNp linux-2.6.32.21/mm/mprotect.c linux-2.6.32.21/mm/mprotect.c
for (nstart = start ; ; ) {
unsigned long newflags;
-@@ -301,6 +422,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
+@@ -301,6 +432,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
if (error)
goto out;
perf_event_mmap(vma);
@@ -53843,8 +54461,16 @@ diff -urNp linux-2.6.32.21/mm/mremap.c linux-2.6.32.21/mm/mremap.c
if (ret & ~PAGE_MASK)
diff -urNp linux-2.6.32.21/mm/nommu.c linux-2.6.32.21/mm/nommu.c
--- linux-2.6.32.21/mm/nommu.c 2010-08-29 21:08:20.000000000 -0400
-+++ linux-2.6.32.21/mm/nommu.c 2010-09-04 15:54:52.000000000 -0400
-@@ -761,15 +761,6 @@ struct vm_area_struct *find_vma(struct m
++++ linux-2.6.32.21/mm/nommu.c 2010-09-17 18:34:04.000000000 -0400
+@@ -67,7 +67,6 @@ int sysctl_overcommit_memory = OVERCOMMI
+ int sysctl_overcommit_ratio = 50; /* default is 50% */
+ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
+ int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
+-int heap_stack_gap = 0;
+
+ atomic_long_t mmap_pages_allocated;
+
+@@ -761,15 +760,6 @@ struct vm_area_struct *find_vma(struct m
EXPORT_SYMBOL(find_vma);
/*
@@ -56492,7 +57118,7 @@ diff -urNp linux-2.6.32.21/security/integrity/ima/ima_queue.c linux-2.6.32.21/se
return 0;
diff -urNp linux-2.6.32.21/security/Kconfig linux-2.6.32.21/security/Kconfig
--- linux-2.6.32.21/security/Kconfig 2010-08-13 16:24:37.000000000 -0400
-+++ linux-2.6.32.21/security/Kconfig 2010-09-14 20:52:17.000000000 -0400
++++ linux-2.6.32.21/security/Kconfig 2010-09-17 17:39:35.000000000 -0400
@@ -4,6 +4,505 @@
menu "Security options"
@@ -56516,7 +57142,7 @@ diff -urNp linux-2.6.32.21/security/Kconfig linux-2.6.32.21/security/Kconfig
+
+config PAX
+ bool "Enable various PaX features"
-+ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC || SPARC || X86)
++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS || PARISC || PPC || SPARC || X86)
+ help
+ This allows you to enable various PaX features. PaX adds
+ intrusion prevention mechanisms to the kernel that reduce