aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordann frazier <dannf@debian.org>2010-02-02 23:38:40 +0000
committerdann frazier <dannf@debian.org>2010-02-02 23:38:40 +0000
commit42ee301828066a3544990984161b56484e2c36b4 (patch)
tree595a47c59e3fc23160ce297da0b4f8a31ecca4a8
parentec0059d2e1dd5667d040be50af69c0c9fb7956a1 (diff)
downloadkernel_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
-rw-r--r--debian/changelog4
-rw-r--r--debian/patches/bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch105
-rw-r--r--debian/patches/bugfix/all/split-flush_old_exec-into-two-functions.patch245
-rw-r--r--debian/patches/series/72
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(&current->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