[kernel] r14482 - in dists/etch-security/linux-2.6.24/debian: . patches/bugfix/all patches/series

Dann Frazier dannf at alioth.debian.org
Wed Oct 28 05:31:07 UTC 2009


Author: dannf
Date: Wed Oct 28 05:31:05 2009
New Revision: 14482

Log:
execve: must clear current->clear_child_tid (CVE-2009-2848)

Added:
   dists/etch-security/linux-2.6.24/debian/patches/bugfix/all/execve-must-clear-current-clear_child_tid.patch
      - copied unchanged from r14470, dists/lenny-security/linux-2.6/debian/patches/bugfix/all/execve-must-clear-current-clear_child_tid.patch
Modified:
   dists/etch-security/linux-2.6.24/debian/changelog
   dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.8etch4

Modified: dists/etch-security/linux-2.6.24/debian/changelog
==============================================================================
--- dists/etch-security/linux-2.6.24/debian/changelog	Wed Oct 28 05:29:05 2009	(r14481)
+++ dists/etch-security/linux-2.6.24/debian/changelog	Wed Oct 28 05:31:05 2009	(r14482)
@@ -3,6 +3,7 @@
   * [parisc] isa-eeprom - Fix loff_t usage (CVE-2009-2846)
   * do_sigaltstack: avoid copying 'stack_t' as a structure to user space
     (CVE-2009-2847)
+  * execve: must clear current->clear_child_tid (CVE-2009-2848)
 
  -- dann frazier <dannf at debian.org>  Tue, 27 Oct 2009 22:41:25 -0600
 

Copied: dists/etch-security/linux-2.6.24/debian/patches/bugfix/all/execve-must-clear-current-clear_child_tid.patch (from r14470, dists/lenny-security/linux-2.6/debian/patches/bugfix/all/execve-must-clear-current-clear_child_tid.patch)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/etch-security/linux-2.6.24/debian/patches/bugfix/all/execve-must-clear-current-clear_child_tid.patch	Wed Oct 28 05:31:05 2009	(r14482, copy of r14470, dists/lenny-security/linux-2.6/debian/patches/bugfix/all/execve-must-clear-current-clear_child_tid.patch)
@@ -0,0 +1,121 @@
+commit 9c8a8228d0827e0d91d28527209988f672f97d28
+Author: Eric Dumazet <eric.dumazet at gmail.com>
+Date:   Thu Aug 6 15:09:28 2009 -0700
+
+    execve: must clear current->clear_child_tid
+    
+    While looking at Jens Rosenboom bug report
+    (http://lkml.org/lkml/2009/7/27/35) about strange sys_futex call done from
+    a dying "ps" program, we found following problem.
+    
+    clone() syscall has special support for TID of created threads.  This
+    support includes two features.
+    
+    One (CLONE_CHILD_SETTID) is to set an integer into user memory with the
+    TID value.
+    
+    One (CLONE_CHILD_CLEARTID) is to clear this same integer once the created
+    thread dies.
+    
+    The integer location is a user provided pointer, provided at clone()
+    time.
+    
+    kernel keeps this pointer value into current->clear_child_tid.
+    
+    At execve() time, we should make sure kernel doesnt keep this user
+    provided pointer, as full user memory is replaced by a new one.
+    
+    As glibc fork() actually uses clone() syscall with CLONE_CHILD_SETTID and
+    CLONE_CHILD_CLEARTID set, chances are high that we might corrupt user
+    memory in forked processes.
+    
+    Following sequence could happen:
+    
+    1) bash (or any program) starts a new process, by a fork() call that
+       glibc maps to a clone( ...  CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID
+       ...) syscall
+    
+    2) When new process starts, its current->clear_child_tid is set to a
+       location that has a meaning only in bash (or initial program) context
+       (&THREAD_SELF->tid)
+    
+    3) This new process does the execve() syscall to start a new program.
+       current->clear_child_tid is left unchanged (a non NULL value)
+    
+    4) If this new program creates some threads, and initial thread exits,
+       kernel will attempt to clear the integer pointed by
+       current->clear_child_tid from mm_release() :
+    
+            if (tsk->clear_child_tid
+                && !(tsk->flags & PF_SIGNALED)
+                && atomic_read(&mm->mm_users) > 1) {
+                    u32 __user * tidptr = tsk->clear_child_tid;
+                    tsk->clear_child_tid = NULL;
+    
+                    /*
+                     * We don't check the error code - if userspace has
+                     * not set up a proper pointer then tough luck.
+                     */
+    << here >>      put_user(0, tidptr);
+                    sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
+            }
+    
+    5) OR : if new program is not multi-threaded, but spied by /proc/pid
+       users (ps command for example), mm_users > 1, and the exiting program
+       could corrupt 4 bytes in a persistent memory area (shm or memory mapped
+       file)
+    
+    If current->clear_child_tid points to a writeable portion of memory of the
+    new program, kernel happily and silently corrupts 4 bytes of memory, with
+    unexpected effects.
+    
+    Fix is straightforward and should not break any sane program.
+    
+    Reported-by: Jens Rosenboom <jens at mcbone.net>
+    Acked-by: Linus Torvalds <torvalds at linux-foundation.org>
+    Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+    Signed-off-by: Oleg Nesterov <oleg at redhat.com>
+    Cc: Peter Zijlstra <peterz at infradead.org>
+    Cc: Sonny Rao <sonnyrao at us.ibm.com>
+    Cc: Ingo Molnar <mingo at elte.hu>
+    Cc: Thomas Gleixner <tglx at linutronix.de>
+    Cc: Ulrich Drepper <drepper at redhat.com>
+    Cc: Oleg Nesterov <oleg at redhat.com>
+    Cc: <stable at kernel.org>
+    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 466531e..021e113 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -568,18 +568,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
+ 	 * the value intact in a core dump, and to save the unnecessary
+ 	 * trouble otherwise.  Userland only wants this done for a sys_exit.
+ 	 */
+-	if (tsk->clear_child_tid
+-	    && !(tsk->flags & PF_SIGNALED)
+-	    && atomic_read(&mm->mm_users) > 1) {
+-		u32 __user * tidptr = tsk->clear_child_tid;
++	if (tsk->clear_child_tid) {
++		if (!(tsk->flags & PF_SIGNALED) &&
++		    atomic_read(&mm->mm_users) > 1) {
++			/*
++			 * We don't check the error code - if userspace has
++			 * not set up a proper pointer then tough luck.
++			 */
++			put_user(0, tsk->clear_child_tid);
++			sys_futex(tsk->clear_child_tid, FUTEX_WAKE,
++					1, NULL, NULL, 0);
++		}
+ 		tsk->clear_child_tid = NULL;
+-
+-		/*
+-		 * We don't check the error code - if userspace has
+-		 * not set up a proper pointer then tough luck.
+-		 */
+-		put_user(0, tidptr);
+-		sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
+ 	}
+ }
+ 

Modified: dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.8etch4
==============================================================================
--- dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.8etch4	Wed Oct 28 05:29:05 2009	(r14481)
+++ dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.8etch4	Wed Oct 28 05:31:05 2009	(r14482)
@@ -1,2 +1,3 @@
 + bugfix/hppa/isa-eeprom-fix-loff_t-usage.patch
 + bugfix/all/do_sigaltstack-avoid-copying-stack_t-as-a-structure-to-userspace.patch
++ bugfix/all/execve-must-clear-current-clear_child_tid.patch



More information about the Kernel-svn-changes mailing list