diff options
author | Josh Boyer <jwboyer@redhat.com> | 2012-04-23 08:24:30 -0400 |
---|---|---|
committer | Josh Boyer <jwboyer@redhat.com> | 2012-04-23 08:24:35 -0400 |
commit | 2b371fe14722275d23b381aa31e9098791f8059c (patch) | |
tree | 974e40cc1d337fd30a533d5fa0e2b24724a2affa /linux-2.6-32bit-mmap-exec-randomization.patch | |
parent | 1caa16e27879815eec1dca303787346727f5f95d (diff) | |
download | kernel-2b371fe14722275d23b381aa31e9098791f8059c.tar.gz kernel-2b371fe14722275d23b381aa31e9098791f8059c.tar.xz kernel-2b371fe14722275d23b381aa31e9098791f8059c.zip |
Linux v3.4-rc4
Disable debugging options.
Diffstat (limited to 'linux-2.6-32bit-mmap-exec-randomization.patch')
-rw-r--r-- | linux-2.6-32bit-mmap-exec-randomization.patch | 194 |
1 files changed, 100 insertions, 94 deletions
diff --git a/linux-2.6-32bit-mmap-exec-randomization.patch b/linux-2.6-32bit-mmap-exec-randomization.patch index c25323323..e4936991a 100644 --- a/linux-2.6-32bit-mmap-exec-randomization.patch +++ b/linux-2.6-32bit-mmap-exec-randomization.patch @@ -7,10 +7,96 @@ Heap randomisation test (PIE) : 19 bits (guessed) Main executable randomisation (PIE) : 12 bits (guessed) - ---- b/include/linux/sched.h +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index 1d92a5a..81fef23 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -753,6 +753,16 @@ unsigned long arch_align_stack(unsigned long sp) + unsigned long arch_randomize_brk(struct mm_struct *mm) + { + unsigned long range_end = mm->brk + 0x02000000; +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk; ++ unsigned long bump = 0; ++#ifdef CONFIG_X86_32 ++ /* in the case of NX emulation, shove the brk segment way out of the ++ way of the exec randomization area, since it can collide with ++ future allocations if not. */ ++ if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) && ++ (mm->brk < 0x08000000) ) { ++ bump = (TASK_SIZE/6); ++ } ++#endif ++ return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk); + } + +diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c +index 845df68..d437466 100644 +--- a/arch/x86/mm/mmap.c ++++ b/arch/x86/mm/mmap.c +@@ -119,6 +119,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm) + } else { + mm->mmap_base = mmap_base(); + mm->get_unmapped_area = arch_get_unmapped_area_topdown; ++#ifdef CONFIG_X86_32 ++ if (!(current->personality & READ_IMPLIES_EXEC) ++ && !(__supported_pte_mask & _PAGE_NX) ++ && mmap_is_ia32()) ++ mm->get_unmapped_exec_area = arch_get_unmapped_exec_area; ++#endif + mm->unmap_area = arch_unmap_area_topdown; + } + } +diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c +index 66e6d93..b80cde7 100644 +--- a/arch/x86/vdso/vdso32-setup.c ++++ b/arch/x86/vdso/vdso32-setup.c +@@ -330,7 +330,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) + if (compat) + addr = VDSO_HIGH_BASE; + else { +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); ++ addr = get_unmapped_area_prot(NULL, 0, PAGE_SIZE, 0, 0, 1); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 74aa71b..d9971db 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1391,7 +1391,13 @@ extern int install_special_mapping(struct mm_struct *mm, + unsigned long addr, unsigned long len, + unsigned long flags, struct page **pages); + +-extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); ++extern unsigned long get_unmapped_area_prot(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, int); ++ ++static inline unsigned long get_unmapped_area(struct file *file, unsigned long addr, ++ unsigned long len, unsigned long pgoff, unsigned long flags) ++{ ++ return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0); ++} + + extern unsigned long mmap_region(struct file *file, unsigned long addr, + unsigned long len, unsigned long flags, +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 3cc3062..b42f00b 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -293,6 +293,9 @@ struct mm_struct { + unsigned long (*get_unmapped_area) (struct file *filp, + unsigned long addr, unsigned long len, + unsigned long pgoff, unsigned long flags); ++ unsigned long (*get_unmapped_exec_area) (struct file *filp, ++ unsigned long addr, unsigned long len, ++ unsigned long pgoff, unsigned long flags); + void (*unmap_area) (struct mm_struct *mm, unsigned long addr); + #endif + unsigned long mmap_base; /* base of mmap area */ +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 81a173c..3f9f5c4 100644 +--- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -397,6 +397,10 @@ +@@ -390,6 +390,10 @@ extern void arch_pick_mmap_layout(struct mm_struct *mm); extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); @@ -21,9 +107,11 @@ Main executable randomisation (PIE) : 12 bits (guessed) extern unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, ---- b/mm/mmap.c +diff --git a/mm/mmap.c b/mm/mmap.c +index 848ef52..65650a5 100644 +--- a/mm/mmap.c +++ b/mm/mmap.c -@@ -28,6 +28,7 @@ +@@ -30,6 +30,7 @@ #include <linux/perf_event.h> #include <linux/audit.h> #include <linux/khugepaged.h> @@ -31,7 +119,7 @@ Main executable randomisation (PIE) : 12 bits (guessed) #include <asm/uaccess.h> #include <asm/cacheflush.h> -@@ -1000,7 +1001,8 @@ +@@ -995,7 +996,8 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, /* Obtain the address to map to. we verify (or select) it and ensure * that it represents a valid section of the address space. */ @@ -41,7 +129,7 @@ Main executable randomisation (PIE) : 12 bits (guessed) if (addr & ~PAGE_MASK) return addr; -@@ -1552,8 +1554,8 @@ +@@ -1580,8 +1582,8 @@ void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) } unsigned long @@ -52,7 +140,7 @@ Main executable randomisation (PIE) : 12 bits (guessed) { unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); -@@ -1566,7 +1568,11 @@ +@@ -1594,7 +1596,11 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, if (len > TASK_SIZE) return -ENOMEM; @@ -65,7 +153,7 @@ Main executable randomisation (PIE) : 12 bits (guessed) if (file && file->f_op && file->f_op->get_unmapped_area) get_area = file->f_op->get_unmapped_area; addr = get_area(file, addr, len, pgoff, flags); -@@ -1580,8 +1586,83 @@ +@@ -1608,8 +1614,83 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, return arch_rebalance_pgtables(addr, len); } @@ -150,71 +238,11 @@ Main executable randomisation (PIE) : 12 bits (guessed) /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) ---- a/arch/x86/mm/mmap.c -+++ b/arch/x86/mm/mmap.c -@@ -124,13 +124,19 @@ static unsigned long mmap_legacy_base(void) - */ - void arch_pick_mmap_layout(struct mm_struct *mm) - { - if (mmap_is_legacy()) { - mm->mmap_base = mmap_legacy_base(); - mm->get_unmapped_area = arch_get_unmapped_area; - mm->unmap_area = arch_unmap_area; - } else { - mm->mmap_base = mmap_base(); - mm->get_unmapped_area = arch_get_unmapped_area_topdown; -+#ifdef CONFIG_X86_32 -+ if (!(current->personality & READ_IMPLIES_EXEC) -+ && !(__supported_pte_mask & _PAGE_NX) -+ && mmap_is_ia32()) -+ mm->get_unmapped_exec_area = arch_get_unmapped_exec_area; -+#endif - mm->unmap_area = arch_unmap_area_topdown; - } - } ---- a/arch/x86/vdso/vdso32-setup.c -+++ b/arch/x86/vdso/vdso32-setup.c -@@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) - if (compat) - addr = VDSO_HIGH_BASE; - else { -- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); -+ addr = get_unmapped_area_prot(NULL, 0, PAGE_SIZE, 0, 0, 1); - if (IS_ERR_VALUE(addr)) { - ret = addr; - goto up_fail; ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1263,7 +1263,13 @@ extern int install_special_mapping(struct mm_struct *mm, - unsigned long addr, unsigned long len, - unsigned long flags, struct page **pages); - --extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); -+extern unsigned long get_unmapped_area_prot(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, int); -+ -+static inline unsigned long get_unmapped_area(struct file *file, unsigned long addr, -+ unsigned long len, unsigned long pgoff, unsigned long flags) -+{ -+ return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0); -+} - - extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -227,6 +227,9 @@ struct mm_struct { - unsigned long (*get_unmapped_area) (struct file *filp, - unsigned long addr, unsigned long len, - unsigned long pgoff, unsigned long flags); -+ unsigned long (*get_unmapped_exec_area) (struct file *filp, -+ unsigned long addr, unsigned long len, -+ unsigned long pgoff, unsigned long flags); - void (*unmap_area) (struct mm_struct *mm, unsigned long addr); - #endif - unsigned long mmap_base; /* base of mmap area */ +diff --git a/mm/mremap.c b/mm/mremap.c +index db8d983..3a2d940 100644 --- a/mm/mremap.c +++ b/mm/mremap.c -@@ -487,10 +487,10 @@ unsigned long do_mremap(unsigned long addr, +@@ -521,10 +521,10 @@ unsigned long do_mremap(unsigned long addr, if (vma->vm_flags & VM_MAYSHARE) map_flags |= MAP_SHARED; @@ -227,25 +255,3 @@ Main executable randomisation (PIE) : 12 bits (guessed) if (new_addr & ~PAGE_MASK) { ret = new_addr; goto out; -diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c -index 57d1868..29c0c35 100644 ---- a/arch/x86/kernel/process.c -+++ b/arch/x86/kernel/process.c -@@ -669,6 +669,16 @@ unsigned long arch_align_stack(unsigned long sp) - unsigned long arch_randomize_brk(struct mm_struct *mm) - { - unsigned long range_end = mm->brk + 0x02000000; -- return randomize_range(mm->brk, range_end, 0) ? : mm->brk; -+ unsigned long bump = 0; -+#ifdef CONFIG_X86_32 -+ /* in the case of NX emulation, shove the brk segment way out of the -+ way of the exec randomization area, since it can collide with -+ future allocations if not. */ -+ if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) && -+ (mm->brk < 0x08000000) ) { -+ bump = (TASK_SIZE/6); -+ } -+#endif -+ return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk); - } - |