Bug 54223 (CVE-2004-0394)

Summary: VUL-0: CVE-2004-0394: memleak in do_fork()
Product: [Novell Products] SUSE Security Incidents Reporter: Sebastian Krahmer <krahmer>
Component: IncidentsAssignee: Sebastian Krahmer <krahmer>
Status: RESOLVED FIXED QA Contact: Security Team bot <security-team>
Severity: Major    
Priority: P3 - Medium CC: security-team
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Whiteboard: CVE-2004-0394: CVSS v2 Base Score: 2.1 (AV:L/AC:L/Au:N/C:P/I:N/A:N)
Found By: Other Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Sebastian Krahmer 2004-04-21 18:07:38 UTC
Details will be added later. Just to get a bugzilla-ID soon.
Comment 1 Sebastian Krahmer 2004-04-21 18:07:38 UTC
<!-- SBZ_reproduce  -->
...
Comment 2 Sebastian Krahmer 2004-04-21 18:16:19 UTC
Date: Thu, 15 Apr 2004 15:05:05 -0700
From: Chris Wright <chrisw@osdl.org>
To: vendor-sec@lst.de
Subject: [vendor-sec] [john.l.byrne@hp.com: [PATCH]: 2.4/2.6 do_fork() error
     path memory leak]

This has been fixed recently in both 2.4 and 2.6 trees.  It's a trivial
DoS without patch.  Just a heads up.

thanks,
-chris

----- Forwarded message from john.l.byrne@hp.com -----

Date:  Wed, 07 Apr 2004 19:14:08 -0700
From: john.l.byrne@hp.com
To: linux-kernel@vger.kernel.org
Cc: marcelo.tosatti@cyclades.com, akpm@osdl.org
Subject: [PATCH]: 2.4/2.6 do_fork() error path memory leak


In do_fork(), if an error occurs after the mm_struct for the child has
been allocated, it is never freed. The exit_mm() meant to free it
increments the mm_count and this count is never decremented. (For a
running process that is exitting, schedule() takes care this; however,
the child process being cleaned up is not running.) In the CLONE_VM
case, the parent's mm_struct will get an extra mm_count and so it will
never be freed.

This patch against 2.4.25 should fix both the CLONE_VM and the not
CLONE_VM case; the test of p->active_mm prevents a panic in the case
that a kernel-thread is being cloned.

It looks from the code that the problem exists in 2.6 as well; I can
send a separate patch for that, if necessary.


John Byrne

diff -Nar -U 4 linux-2.4.25/kernel/fork.c linux-2.4.25-new/kernel/fork.c
--- linux-2.4.25/kernel/fork.c 2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.25-new/kernel/fork.c     2004-04-07 17:43:29.000000000 -0700
@@ -825,8 +825,10 @@
 bad_fork_cleanup_namespace:
       exit_namespace(p);
 bad_fork_cleanup_mm:
       exit_mm(p);
+      if (p->active_mm)
+      mmdrop(p->active_mm);
 bad_fork_cleanup_sighand:
       exit_sighand(p);
 bad_fork_cleanup_fs:
       exit_fs(p); /* blocking */

Comment 3 Hubert Mantel 2004-04-21 18:29:10 UTC
Fixes are in CVS.
Comment 4 Sebastian Krahmer 2004-04-26 19:39:35 UTC
CAN-2004-0394
Comment 5 Hubert Mantel 2004-04-26 20:29:44 UTC
Kernels have been submitted and are waiting for check in.
Comment 6 Sebastian Krahmer 2004-04-27 16:37:17 UTC
The CAN-2004-0394 is wrong. It rather belongs to panic() issue.
Comment 7 Bernhard Kaindl 2004-04-29 00:04:22 UTC
I'm just noting that not all kernels are affected by this bug. 
--------- 
Affected are: 
 
Kernel 2.4.19 and newer and kernels copy_namespace() 
 
IA64 Kernel, if CONFIG_PERFMON was enabled during compilation, 
and you have to bring the Machine OOM first and then you can 
possibly trigger the leak. 
 
All other Kernels are *not* affected which includes 
so SLES7-s390 (2.4.7) and SLES7-s390x (2.4.17) and likely the PPC 2.4.13. 
 
Two reasons for this: 
 
a) there is no copy_namespace(), the code to exploit using clone() 
   is not there. 
b) Even if you bring the machine OOM first and then try, it you 
   can't reach the code postion because there is no chance to 
   enter the code path where the fix is applied because on these 
   kernels, copy_thread always returns 0: 
Details: 
================================================================================ 
 
int copy_thread(int nr, unsigned long clone_flags, unsigned long 
new_stackp, ..) 
{ 
       .... 
       return 0; 
} 
 
        retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 
        if (retval) 
                goto bad_fork_cleanup_mm; 
 
...... function ....... 
 
        return (success code) 
 
NEVER REACHED BEGIN 
 
bad_fork_cleanup_mm: 
       exit_mm(p); 
       (fix would be inserted here) 
 
NEVER REACHED END 
 
bad_fork_cleanup_sighand: 
================================================================================ 
So there is simply no memory leak at this place on 2.4.17 and 2.4.7. 
 
But we can add the fix anyway, it should not hurt that much ;-) 
 
But SLES7/s390* and SLES7 PCC(2.4.13) Clients are safe from this DoS. 
 
-> I've submited the sles7-s390* kernels also - just for the journalists. 
 
BTW: As "remote/network" is in the "Component" field: 
This can only be exploited if you have control over locally running process, 
for me this is a local DoS "only". 
Comment 8 Sebastian Krahmer 2004-05-04 17:26:43 UTC
kernels have been approved and announced.
Comment 9 Thomas Biege 2009-10-13 20:21:04 UTC
CVE-2004-0394: CVSS v2 Base Score: 2.1 (AV:L/AC:L/Au:N/C:P/I:N/A:N)