[kernel] r15102 - in dists/trunk/linux-2.6/debian: . patches/bugfix/all patches/series

Dann Frazier dannf at alioth.debian.org
Tue Feb 2 23:38:42 UTC 2010


Author: dannf
Date: Tue Feb  2 23:38:40 2010
New Revision: 15102

Log:
* 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)

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch
   dists/trunk/linux-2.6/debian/patches/bugfix/all/split-flush_old_exec-into-two-functions.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/7

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Tue Feb  2 22:54:43 2010	(r15101)
+++ dists/trunk/linux-2.6/debian/changelog	Tue Feb  2 23:38:40 2010	(r15102)
@@ -11,6 +11,10 @@
   [ 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 at debian.org>  Mon, 01 Feb 2010 17:16:31 +0100
 

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch	Tue Feb  2 23:38:40 2010	(r15102)
@@ -0,0 +1,105 @@
+From 04e4f2b18c8de1389d1e00fef0f42a8099910daf Mon Sep 17 00:00:00 2001
+From: Mike Frysinger <vapier at 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 at 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 at gentoo.org>
+Signed-off-by: David Howells <dhowells at redhat.com>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at 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);
+ 

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/split-flush_old_exec-into-two-functions.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/split-flush_old_exec-into-two-functions.patch	Tue Feb  2 23:38:40 2010	(r15102)
@@ -0,0 +1,245 @@
+From 221af7f87b97431e3ee21ce4b0e77d5411cf1549 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds at linux-foundation.org>
+Date: Thu, 28 Jan 2010 22:14:42 -0800
+Subject: Split 'flush_old_exec' into two functions
+
+From: Linus Torvalds <torvalds at 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 at zytor.com>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at 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

Modified: dists/trunk/linux-2.6/debian/patches/series/7
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/7	Tue Feb  2 22:54:43 2010	(r15101)
+++ dists/trunk/linux-2.6/debian/patches/series/7	Tue Feb  2 23:38:40 2010	(r15102)
@@ -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



More information about the Kernel-svn-changes mailing list