diff options
author | Dave Jones <davej@redhat.com> | 2012-06-04 12:32:49 -0400 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2012-06-04 12:32:49 -0400 |
commit | 48d35dba7a308ba6c6d97d99f7a3bd62b2d8cead (patch) | |
tree | bff2b4fd9ca40f2ec2dbe0530431ff02d288bf6e /linux-2.6-32bit-mmap-exec-randomization.patch | |
parent | 035f913c7c92d6916cf6cb9eaee39910cbbdfbb2 (diff) | |
download | kernel-48d35dba7a308ba6c6d97d99f7a3bd62b2d8cead.tar.gz kernel-48d35dba7a308ba6c6d97d99f7a3bd62b2d8cead.tar.xz kernel-48d35dba7a308ba6c6d97d99f7a3bd62b2d8cead.zip |
Remove 32bit NX emulation. It's time has passed. (and it seems to be broken anyway)
Diffstat (limited to 'linux-2.6-32bit-mmap-exec-randomization.patch')
-rw-r--r-- | linux-2.6-32bit-mmap-exec-randomization.patch | 248 |
1 files changed, 0 insertions, 248 deletions
diff --git a/linux-2.6-32bit-mmap-exec-randomization.patch b/linux-2.6-32bit-mmap-exec-randomization.patch deleted file mode 100644 index 1c0800127..000000000 --- a/linux-2.6-32bit-mmap-exec-randomization.patch +++ /dev/null @@ -1,248 +0,0 @@ -diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c -index 735279e..0f9f005 100644 ---- a/arch/x86/kernel/process.c -+++ b/arch/x86/kernel/process.c -@@ -756,6 +756,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 b36d08c..91e573d 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1387,7 +1387,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 dad95bd..01a150c 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -294,6 +294,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 f34437e..12fe177 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -391,6 +391,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); -+ -+extern unsigned long -+arch_get_unmapped_exec_area(struct file *, unsigned long, unsigned long, -+ unsigned long, unsigned long); - extern unsigned long - arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, -diff --git a/mm/mmap.c b/mm/mmap.c -index 3edfcdf..076ec09 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -31,6 +31,7 @@ - #include <linux/audit.h> - #include <linux/khugepaged.h> - #include <linux/uprobes.h> -+#include <linux/random.h> - - #include <asm/uaccess.h> - #include <asm/cacheflush.h> -@@ -1011,7 +1012,8 @@ 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. - */ -- addr = get_unmapped_area(file, addr, len, pgoff, flags); -+ addr = get_unmapped_area_prot(file, addr, len, pgoff, flags, -+ prot & PROT_EXEC); - if (addr & ~PAGE_MASK) - return addr; - -@@ -1568,8 +1570,8 @@ void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) - } - - unsigned long --get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, -- unsigned long pgoff, unsigned long flags) -+get_unmapped_area_prot(struct file *file, unsigned long addr, unsigned long len, -+ unsigned long pgoff, unsigned long flags, int exec) - { - unsigned long (*get_area)(struct file *, unsigned long, - unsigned long, unsigned long, unsigned long); -@@ -1582,7 +1584,11 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, - if (len > TASK_SIZE) - return -ENOMEM; - -- get_area = current->mm->get_unmapped_area; -+ if (exec && current->mm->get_unmapped_exec_area) -+ get_area = current->mm->get_unmapped_exec_area; -+ else -+ get_area = current->mm->get_unmapped_area; -+ - if (file && file->f_op && file->f_op->get_unmapped_area) - get_area = file->f_op->get_unmapped_area; - addr = get_area(file, addr, len, pgoff, flags); -@@ -1598,8 +1604,83 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, - error = security_mmap_addr(addr); - return error ? error : addr; - } -+EXPORT_SYMBOL(get_unmapped_area_prot); -+ -+static bool should_randomize(void) -+{ -+ return (current->flags & PF_RANDOMIZE) && -+ !(current->personality & ADDR_NO_RANDOMIZE); -+} -+ -+#define SHLIB_BASE 0x00110000 -+ -+unsigned long -+arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0, -+ unsigned long len0, unsigned long pgoff, unsigned long flags) -+{ -+ unsigned long addr = addr0, len = len0; -+ struct mm_struct *mm = current->mm; -+ struct vm_area_struct *vma; -+ unsigned long tmp; -+ -+ if (len > TASK_SIZE) -+ return -ENOMEM; -+ -+ if (flags & MAP_FIXED) -+ return addr; -+ -+ if (!addr) -+ addr = !should_randomize() ? SHLIB_BASE : -+ randomize_range(SHLIB_BASE, 0x01000000, len); -+ -+ if (addr) { -+ addr = PAGE_ALIGN(addr); -+ vma = find_vma(mm, addr); -+ if (TASK_SIZE - len >= addr && -+ (!vma || addr + len <= vma->vm_start)) -+ return addr; -+ } -+ -+ addr = SHLIB_BASE; -+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { -+ /* At this point: (!vma || addr < vma->vm_end). */ -+ if (TASK_SIZE - len < addr) -+ return -ENOMEM; -+ -+ if (!vma || addr + len <= vma->vm_start) { -+ /* -+ * Must not let a PROT_EXEC mapping get into the -+ * brk area: -+ */ -+ if (addr + len > mm->brk) -+ goto failed; -+ -+ /* -+ * Up until the brk area we randomize addresses -+ * as much as possible: -+ */ -+ if (addr >= 0x01000000 && should_randomize()) { -+ tmp = randomize_range(0x01000000, -+ PAGE_ALIGN(max(mm->start_brk, -+ (unsigned long)0x08000000)), len); -+ vma = find_vma(mm, tmp); -+ if (TASK_SIZE - len >= tmp && -+ (!vma || tmp + len <= vma->vm_start)) -+ return tmp; -+ } -+ /* -+ * Ok, randomization didnt work out - return -+ * the result of the linear search: -+ */ -+ return addr; -+ } -+ addr = vma->vm_end; -+ } -+ -+failed: -+ return current->mm->get_unmapped_area(filp, addr0, len0, pgoff, flags); -+} - --EXPORT_SYMBOL(get_unmapped_area); - - /* 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) -diff --git a/mm/mremap.c b/mm/mremap.c -index 21fed20..a3de1ee 100644 ---- a/mm/mremap.c -+++ b/mm/mremap.c -@@ -519,10 +519,10 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, - if (vma->vm_flags & VM_MAYSHARE) - map_flags |= MAP_SHARED; - -- new_addr = get_unmapped_area(vma->vm_file, 0, new_len, -+ new_addr = get_unmapped_area_prot(vma->vm_file, 0, new_len, - vma->vm_pgoff + - ((addr - vma->vm_start) >> PAGE_SHIFT), -- map_flags); -+ map_flags, vma->vm_flags & VM_EXEC); - if (new_addr & ~PAGE_MASK) { - ret = new_addr; - goto out; |