diff options
author | dann frazier <dannf@debian.org> | 2010-02-02 23:38:40 +0000 |
---|---|---|
committer | dann frazier <dannf@debian.org> | 2010-02-02 23:38:40 +0000 |
commit | 42ee301828066a3544990984161b56484e2c36b4 (patch) | |
tree | 595a47c59e3fc23160ce297da0b4f8a31ecca4a8 | |
parent | ec0059d2e1dd5667d040be50af69c0c9fb7956a1 (diff) | |
download | kernel_replicant_linux-42ee301828066a3544990984161b56484e2c36b4.tar.gz kernel_replicant_linux-42ee301828066a3544990984161b56484e2c36b4.tar.bz2 kernel_replicant_linux-42ee301828066a3544990984161b56484e2c36b4.zip |
* Patches queued for 2.6.32.8:
- FDPIC: Respect PT_GNU_STACK exec protection markings when creating
NOMMU stack
- Split 'flush_old_exec' into two functions (CVE-2010-0307)
svn path=/dists/trunk/linux-2.6/; revision=15102
4 files changed, 356 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index 352f6d0047c8..0acf73411a52 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,10 @@ linux-2.6 (2.6.32-7) UNRELEASED; urgency=low [ dann frazier ] * Disable FUNCTION_TRACER due to performance/build issues. (Closes: #568025) + * Patches queued for 2.6.32.8: + - FDPIC: Respect PT_GNU_STACK exec protection markings when creating + NOMMU stack + - Split 'flush_old_exec' into two functions (CVE-2010-0307) -- maximilian attems <maks@debian.org> Mon, 01 Feb 2010 17:16:31 +0100 diff --git a/debian/patches/bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch b/debian/patches/bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch new file mode 100644 index 000000000000..ba5e8844a0a9 --- /dev/null +++ b/debian/patches/bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch @@ -0,0 +1,105 @@ +From 04e4f2b18c8de1389d1e00fef0f42a8099910daf Mon Sep 17 00:00:00 2001 +From: Mike Frysinger <vapier@gentoo.org> +Date: Wed, 6 Jan 2010 17:23:17 +0000 +Subject: FDPIC: Respect PT_GNU_STACK exec protection markings when creating NOMMU stack + +From: Mike Frysinger <vapier@gentoo.org> + +commit 04e4f2b18c8de1389d1e00fef0f42a8099910daf upstream. + +The current code will load the stack size and protection markings, but +then only use the markings in the MMU code path. The NOMMU code path +always passes PROT_EXEC to the mmap() call. While this doesn't matter +to most people whilst the code is running, it will cause a pointless +icache flush when starting every FDPIC application. Typically this +icache flush will be of a region on the order of 128KB in size, or may +be the entire icache, depending on the facilities available on the CPU. + +In the case where the arch default behaviour seems to be desired +(EXSTACK_DEFAULT), we probe VM_STACK_FLAGS for VM_EXEC to determine +whether we should be setting PROT_EXEC or not. + +For arches that support an MPU (Memory Protection Unit - an MMU without +the virtual mapping capability), setting PROT_EXEC or not will make an +important difference. + +It should be noted that this change also affects the executability of +the brk region, since ELF-FDPIC has that share with the stack. However, +this is probably irrelevant as NOMMU programs aren't likely to use the +brk region, preferring instead allocation via mmap(). + +Signed-off-by: Mike Frysinger <vapier@gentoo.org> +Signed-off-by: David Howells <dhowells@redhat.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/blackfin/include/asm/page.h | 5 +++++ + arch/frv/include/asm/page.h | 2 -- + fs/binfmt_elf_fdpic.c | 13 +++++++++++-- + 3 files changed, 16 insertions(+), 4 deletions(-) + +--- a/arch/blackfin/include/asm/page.h ++++ b/arch/blackfin/include/asm/page.h +@@ -10,4 +10,9 @@ + #include <asm-generic/page.h> + #define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) + ++#define VM_DATA_DEFAULT_FLAGS \ ++ (VM_READ | VM_WRITE | \ ++ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ ++ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) ++ + #endif +--- a/arch/frv/include/asm/page.h ++++ b/arch/frv/include/asm/page.h +@@ -63,12 +63,10 @@ extern unsigned long max_pfn; + #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + + +-#ifdef CONFIG_MMU + #define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +-#endif + + #endif /* __ASSEMBLY__ */ + +--- a/fs/binfmt_elf_fdpic.c ++++ b/fs/binfmt_elf_fdpic.c +@@ -171,6 +171,9 @@ static int load_elf_fdpic_binary(struct + #ifdef ELF_FDPIC_PLAT_INIT + unsigned long dynaddr; + #endif ++#ifndef CONFIG_MMU ++ unsigned long stack_prot; ++#endif + struct file *interpreter = NULL; /* to shut gcc up */ + char *interpreter_name = NULL; + int executable_stack; +@@ -316,6 +319,8 @@ static int load_elf_fdpic_binary(struct + * defunct, deceased, etc. after this point we have to exit via + * error_kill */ + set_personality(PER_LINUX_FDPIC); ++ if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) ++ current->personality |= READ_IMPLIES_EXEC; + set_binfmt(&elf_fdpic_format); + + current->mm->start_code = 0; +@@ -377,9 +382,13 @@ static int load_elf_fdpic_binary(struct + if (stack_size < PAGE_SIZE * 2) + stack_size = PAGE_SIZE * 2; + ++ stack_prot = PROT_READ | PROT_WRITE; ++ if (executable_stack == EXSTACK_ENABLE_X || ++ (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) ++ stack_prot |= PROT_EXEC; ++ + down_write(¤t->mm->mmap_sem); +- current->mm->start_brk = do_mmap(NULL, 0, stack_size, +- PROT_READ | PROT_WRITE | PROT_EXEC, ++ current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, + 0); + diff --git a/debian/patches/bugfix/all/split-flush_old_exec-into-two-functions.patch b/debian/patches/bugfix/all/split-flush_old_exec-into-two-functions.patch new file mode 100644 index 000000000000..8794a49a4723 --- /dev/null +++ b/debian/patches/bugfix/all/split-flush_old_exec-into-two-functions.patch @@ -0,0 +1,245 @@ +From 221af7f87b97431e3ee21ce4b0e77d5411cf1549 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds <torvalds@linux-foundation.org> +Date: Thu, 28 Jan 2010 22:14:42 -0800 +Subject: Split 'flush_old_exec' into two functions + +From: Linus Torvalds <torvalds@linux-foundation.org> + +commit 221af7f87b97431e3ee21ce4b0e77d5411cf1549 upstream. + +'flush_old_exec()' is the point of no return when doing an execve(), and +it is pretty badly misnamed. It doesn't just flush the old executable +environment, it also starts up the new one. + +Which is very inconvenient for things like setting up the new +personality, because we want the new personality to affect the starting +of the new environment, but at the same time we do _not_ want the new +personality to take effect if flushing the old one fails. + +As a result, the x86-64 '32-bit' personality is actually done using this +insane "I'm going to change the ABI, but I haven't done it yet" bit +(TIF_ABI_PENDING), with SET_PERSONALITY() not actually setting the +personality, but just the "pending" bit, so that "flush_thread()" can do +the actual personality magic. + +This patch in no way changes any of that insanity, but it does split the +'flush_old_exec()' function up into a preparatory part that can fail +(still called flush_old_exec()), and a new part that will actually set +up the new exec environment (setup_new_exec()). All callers are changed +to trivially comply with the new world order. + +Signed-off-by: H. Peter Anvin <hpa@zytor.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/sh/kernel/process_64.c | 2 +- + arch/x86/ia32/ia32_aout.c | 10 ++++++---- + fs/binfmt_aout.c | 1 + + fs/binfmt_elf.c | 27 ++------------------------- + fs/binfmt_elf_fdpic.c | 3 +++ + fs/binfmt_flat.c | 1 + + fs/binfmt_som.c | 1 + + fs/exec.c | 26 ++++++++++++++++---------- + include/linux/binfmts.h | 1 + + include/linux/sched.h | 2 +- + 10 files changed, 33 insertions(+), 41 deletions(-) + +--- a/arch/sh/kernel/process_64.c ++++ b/arch/sh/kernel/process_64.c +@@ -367,7 +367,7 @@ void exit_thread(void) + void flush_thread(void) + { + +- /* Called by fs/exec.c (flush_old_exec) to remove traces of a ++ /* Called by fs/exec.c (setup_new_exec) to remove traces of a + * previously running executable. */ + #ifdef CONFIG_SH_FPU + if (last_task_used_math == current) { +--- a/arch/x86/ia32/ia32_aout.c ++++ b/arch/x86/ia32/ia32_aout.c +@@ -308,15 +308,17 @@ static int load_aout_binary(struct linux + if (retval) + return retval; + +- regs->cs = __USER32_CS; +- regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = +- regs->r13 = regs->r14 = regs->r15 = 0; +- + /* OK, This is the point of no return */ + set_personality(PER_LINUX); + set_thread_flag(TIF_IA32); + clear_thread_flag(TIF_ABI_PENDING); + ++ setup_new_exec(bprm); ++ ++ regs->cs = __USER32_CS; ++ regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = ++ regs->r13 = regs->r14 = regs->r15 = 0; ++ + current->mm->end_code = ex.a_text + + (current->mm->start_code = N_TXTADDR(ex)); + current->mm->end_data = ex.a_data + +--- a/fs/binfmt_aout.c ++++ b/fs/binfmt_aout.c +@@ -263,6 +263,7 @@ static int load_aout_binary(struct linux + #else + set_personality(PER_LINUX); + #endif ++ setup_new_exec(bprm); + + current->mm->end_code = ex.a_text + + (current->mm->start_code = N_TXTADDR(ex)); +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -662,27 +662,6 @@ static int load_elf_binary(struct linux_ + if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') + goto out_free_interp; + +- /* +- * The early SET_PERSONALITY here is so that the lookup +- * for the interpreter happens in the namespace of the +- * to-be-execed image. SET_PERSONALITY can select an +- * alternate root. +- * +- * However, SET_PERSONALITY is NOT allowed to switch +- * this task into the new images's memory mapping +- * policy - that is, TASK_SIZE must still evaluate to +- * that which is appropriate to the execing application. +- * This is because exit_mmap() needs to have TASK_SIZE +- * evaluate to the size of the old image. +- * +- * So if (say) a 64-bit application is execing a 32-bit +- * application it is the architecture's responsibility +- * to defer changing the value of TASK_SIZE until the +- * switch really is going to happen - do this in +- * flush_thread(). - akpm +- */ +- SET_PERSONALITY(loc->elf_ex); +- + interpreter = open_exec(elf_interpreter); + retval = PTR_ERR(interpreter); + if (IS_ERR(interpreter)) +@@ -730,9 +709,6 @@ static int load_elf_binary(struct linux_ + /* Verify the interpreter has a valid arch */ + if (!elf_check_arch(&loc->interp_elf_ex)) + goto out_free_dentry; +- } else { +- /* Executables without an interpreter also need a personality */ +- SET_PERSONALITY(loc->elf_ex); + } + + /* Flush all traces of the currently running executable */ +@@ -752,7 +728,8 @@ static int load_elf_binary(struct linux_ + + if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + current->flags |= PF_RANDOMIZE; +- arch_pick_mmap_layout(current->mm); ++ ++ setup_new_exec(bprm); + + /* Do this so that we can load the interpreter, if need be. We will + change some of these later */ +--- a/fs/binfmt_elf_fdpic.c ++++ b/fs/binfmt_elf_fdpic.c +@@ -321,6 +321,9 @@ static int load_elf_fdpic_binary(struct + set_personality(PER_LINUX_FDPIC); + if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) + current->personality |= READ_IMPLIES_EXEC; ++ ++ setup_new_exec(bprm); ++ + set_binfmt(&elf_fdpic_format); + + current->mm->start_code = 0; +--- a/fs/binfmt_flat.c ++++ b/fs/binfmt_flat.c +@@ -519,6 +519,7 @@ static int load_flat_file(struct linux_b + + /* OK, This is the point of no return */ + set_personality(PER_LINUX_32BIT); ++ setup_new_exec(bprm); + } + + /* +--- a/fs/binfmt_som.c ++++ b/fs/binfmt_som.c +@@ -227,6 +227,7 @@ load_som_binary(struct linux_binprm * bp + /* OK, This is the point of no return */ + current->flags &= ~PF_FORKNOEXEC; + current->personality = PER_HPUX; ++ setup_new_exec(bprm); + + /* Set the task size for HP-UX processes such that + * the gateway page is outside the address space. +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -931,9 +931,7 @@ void set_task_comm(struct task_struct *t + + int flush_old_exec(struct linux_binprm * bprm) + { +- char * name; +- int i, ch, retval; +- char tcomm[sizeof(current->comm)]; ++ int retval; + + /* + * Make sure we have a private signal table and that +@@ -953,6 +951,20 @@ int flush_old_exec(struct linux_binprm * + goto out; + + bprm->mm = NULL; /* We're using it now */ ++ return 0; ++ ++out: ++ return retval; ++} ++EXPORT_SYMBOL(flush_old_exec); ++ ++void setup_new_exec(struct linux_binprm * bprm) ++{ ++ int i, ch; ++ char * name; ++ char tcomm[sizeof(current->comm)]; ++ ++ arch_pick_mmap_layout(current->mm); + + /* This is the point of no return */ + current->sas_ss_sp = current->sas_ss_size = 0; +@@ -1009,14 +1021,8 @@ int flush_old_exec(struct linux_binprm * + + flush_signal_handlers(current, 0); + flush_old_files(current->files); +- +- return 0; +- +-out: +- return retval; + } +- +-EXPORT_SYMBOL(flush_old_exec); ++EXPORT_SYMBOL(setup_new_exec); + + /* + * Prepare credentials and lock ->cred_guard_mutex. +--- a/include/linux/binfmts.h ++++ b/include/linux/binfmts.h +@@ -101,6 +101,7 @@ extern int prepare_binprm(struct linux_b + extern int __must_check remove_arg_zero(struct linux_binprm *); + extern int search_binary_handler(struct linux_binprm *,struct pt_regs *); + extern int flush_old_exec(struct linux_binprm * bprm); ++extern void setup_new_exec(struct linux_binprm * bprm); + + extern int suid_dumpable; + #define SUID_DUMP_DISABLE 0 /* No setuid dumping */ +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1354,7 +1354,7 @@ struct task_struct { + char comm[TASK_COMM_LEN]; /* executable name excluding path + - access with [gs]et_task_comm (which lock + it with task_lock()) +- - initialized normally by flush_old_exec */ ++ - initialized normally by setup_new_exec */ + /* file system info */ + int link_count, total_link_count; + #ifdef CONFIG_SYSVIPC diff --git a/debian/patches/series/7 b/debian/patches/series/7 index 7da901515137..bc337f7732b8 100644 --- a/debian/patches/series/7 +++ b/debian/patches/series/7 @@ -1 +1,3 @@ + bugfix/all/clocksource-events-Fix-fallout-of-generic-code-changes.patch ++ bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch ++ bugfix/all/split-flush_old_exec-into-two-functions.patch |