Bug #71535 [Asn->Csd]: Integer overflow in zend_mm_alloc_heap()

From: Date: Wed, 24 Feb 2016 08:06:15 +0000
Subject: Bug #71535 [Asn->Csd]: Integer overflow in zend_mm_alloc_heap()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-199441@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71535&edit=1 ID: 71535 Updated by: dmitry@php.net Reported by: hlt99 at blinkenshell dot org Summary: Integer overflow in zend_mm_alloc_heap() -Status: Assigned +Status: Closed Type: Bug Package: *General Issues Operating System: Arch Linux (64-bit) PHP Version: 7.0.3 Assigned To: dmitry Block user comment: N Private report: N New Comment: Automatic comment on behalf of dmitry@zend.com Revision: http://git.php.net/?p=php-src.git;a=commit;h=0b9c87a02bacfbf1d1383ad393bda78e5d65570c Log: Fixed bug #71535 (Integer overflow in zend_mm_alloc_heap()) Previous Comments: ------------------------------------------------------------------------ [2016-02-17 17:11:35] hlt99 at blinkenshell dot org The bug itself is located in Zend internal memory management code. It opens the door for memory corruption vulns because PHP memory checks can be circumvented. I tried to demo this by chaining this together with the other bug I reported. However, this works only in debug mode. So I guess this is a low risk bug. But be aware that this bug may as well be triggered by other bugs we don't know of. ------------------------------------------------------------------------ [2016-02-15 08:22:06] stas@php.net You seem to be talking about debug mode build and also about internal function, so I'm not sure I understand how it is a security issue. Could you please explain in some more details where the security issue comes from? ------------------------------------------------------------------------ [2016-02-05 11:13:39] hlt99 at blinkenshell dot org Description: ------------ # Build instructions ../configure --enable-debug --enable-exif && make # Description The debug code in zend_mm_alloc_heap() contains an integer overflow bug. As shown in the code snippet below the code for memory alignment may increase the size parameter resulting in an integer overflow. (PHP-7.0.2) zend_alloc.c: 1346 static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t size /*...*/) 1347 { [...] 1349 #if ZEND_DEBUG [...] 1355 size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)); // ^-- possible int overflow Overflowing the size parameter leads to a successful heap memory allocation. Then a valid pointer pointing to a much smaller then requested heap memory section is returned to the caller. This bug can be triggered and exploited using [1]. [1] For more info on the security impact of that bug see #71534 (Type confusion in exif_read_data() leading to heap overflow)! # PHP versions known to be affected 7.0.2 (git) 7.0.3 (git) Versions prior to 7.0.2 have not been tested. # PHP versions known to be not affected 5.6.18 (git) Versions prior to 5.6.18 have not been tested. Test script: --------------- /* exif_read_data.php poc.tiff: http://hlt99.blinkenshell.org/php/poc.tiff */ <?php $data = exif_read_data("poc.tiff", NULL, true, true); ?> Expected result: ---------------- Fatal out of memory error Actual result: -------------- # GDB Log $ gdb sapi/cli/php [...] gdb$ b exif.c:3675 gdb$ r exif_read_data.php [...] gdb$ si // until _safe_emalloc [----------------------------------registers-----------------------------------] RAX: 0xfc89 RBX: 0x1655c20 --> 0x607e ('~`') RCX: 0xfa73fe ("/home/rc0r/tmp/php-src/ext/exif/exif.c") RDX: 0x0 RSI: 0x1 RDI: 0xffffffffffffffff RBP: 0x7fffffffaa00 --> 0x7ffff2e5ea00 --> 0x16199b8 --> 0xc89d20 (<php_stdiop_write>: push r14) RSP: 0x7fffffffa730 --> 0x0 RIP: 0x878410 (<exif_process_IFD_in_TIFF+4560>: call 0xcd2480 <_safe_emalloc>) R8 : 0xe5b R9 : 0x0 R10: 0x1627348 --> 0x1645c20 --> 0x9200000000 R11: 0x7fffffffaa00 --> 0x7ffff2e5ea00 --> 0x16199b8 --> 0xc89d20 (<php_stdiop_write>: push r14) R12: 0x1 R13: 0xe R14: 0x1655c20 --> 0x607e ('~`') R15: 0x1627348 --> 0x1645c20 --> 0x9200000000 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x878403 <exif_process_IFD_in_TIFF+4547>: lea rcx,[rip+0x72eff4] # 0xfa73fe 0x87840a <exif_process_IFD_in_TIFF+4554>: mov r15,r10 0x87840d <exif_process_IFD_in_TIFF+4557>: mov rbp,r11 => 0x878410 <exif_process_IFD_in_TIFF+4560>: call 0xcd2480 <_safe_emalloc> 0x878415 <exif_process_IFD_in_TIFF+4565>: mov QWORD PTR [rbp+0x110],rax 0x87841c <exif_process_IFD_in_TIFF+4572>: mov rdi,QWORD PTR [rbp+0x0] 0x878420 <exif_process_IFD_in_TIFF+4576>: mov rsi,QWORD PTR [rbp+0x108] 0x878427 <exif_process_IFD_in_TIFF+4583>: xor edx,edx Guessed arguments: arg[0]: 0xffffffffffffffff arg[1]: 0x1 arg[2]: 0x0 arg[3]: 0xfa73fe ("/home/rc0r/tmp/php-src/ext/exif/exif.c") arg[4]: 0xe5b arg[5]: 0x0 [------------------------------------------------------------------------------] gdb$ si // until zend_mm_heap_alloc() [----------------------------------registers-----------------------------------] RAX: 0xffffffffffffffff RBX: 0x1655c20 --> 0x4d2a ('*M') RCX: 0xe5b RDX: 0xfa73fe ("/home/rc0r/tmp/php-src/ext/exif/exif.c") RSI: 0xffffffffffffffff RDI: 0x7ffff2e00040 --> 0x0 RBP: 0x7fffffffaa00 --> 0x7ffff2e5ea00 --> 0x16199b8 --> 0xc89d20 (<php_stdiop_write>: push r14) RSP: 0x7fffffffa700 --> 0x0 RIP: 0xcd2536 (<_safe_emalloc+182>: call 0xccefe0 <zend_mm_alloc_heap>) R8 : 0x12fca48 ("/home/rc0r/tmp/php-src/Zend/zend_alloc.c") R9 : 0x9ce R10: 0xe5b R11: 0x7ffff2e00040 --> 0x0 R12: 0x1 R13: 0xe R14: 0x1627348 --> 0x1645c20 --> 0x9200000000 R15: 0x1627348 --> 0x1645c20 --> 0x9200000000 EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xcd252d <_safe_emalloc+173>: mov rsi,rax 0xcd2530 <_safe_emalloc+176>: mov rdx,rcx 0xcd2533 <_safe_emalloc+179>: mov ecx,r10d => 0xcd2536 <_safe_emalloc+182>: call 0xccefe0 <zend_mm_alloc_heap> 0xcd253b <_safe_emalloc+187>: movzx ecx,WORD PTR [rbx] 0xcd253e <_safe_emalloc+190>: mov rdx,QWORD PTR [r14] 0xcd2541 <_safe_emalloc+193>: xor rcx,0x7ddb 0xcd2548 <_safe_emalloc+200>: inc BYTE PTR [rdx+rcx*1] Guessed arguments: arg[0]: 0x7ffff2e00040 --> 0x0 arg[1]: 0xffffffffffffffff arg[2]: 0xfa73fe ("/home/rc0r/tmp/php-src/ext/exif/exif.c") arg[3]: 0xe5b arg[4]: 0x12fca48 ("/home/rc0r/tmp/php-src/Zend/zend_alloc.c") arg[5]: 0x9ce [------------------------------------------------------------------------------] gdb$ si // until overflowing code is reached [----------------------------------registers-----------------------------------] RAX: 0x5fe9 RBX: 0x1655c20 --> 0x961 ('a\t') RCX: 0xe5b RDX: 0xfa73fe ("/home/rc0r/tmp/php-src/ext/exif/exif.c") RSI: 0xffffffffffffffff RDI: 0x7ffff2e00040 --> 0x0 RBP: 0xe5b RSP: 0x7fffffffa670 --> 0x400007575 RIP: 0xccf040 (<zend_mm_alloc_heap+96>: add r15,0x27) R8 : 0x12fca48 ("/home/rc0r/tmp/php-src/Zend/zend_alloc.c") R9 : 0x9ce R10: 0x1627348 --> 0x1645c20 --> 0x9200000000 R11: 0x7ffff2e00040 --> 0x0 R12: 0x7ffff2e00040 --> 0x0 R13: 0x1655c20 --> 0x961 ('a\t') R14: 0x1627348 --> 0x1645c20 --> 0x9200000000 R15: 0xffffffffffffffff <-- size param EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xccf032 <zend_mm_alloc_heap+82>: cmp rsi,0x1 0xccf036 <zend_mm_alloc_heap+86>: mov r15d,0x1 0xccf03c <zend_mm_alloc_heap+92>: cmova r15,rsi => 0xccf040 <zend_mm_alloc_heap+96>: add r15,0x27 <-- overflow !!! 0xccf044 <zend_mm_alloc_heap+100>: and r15,0xfffffffffffffff8 0xccf048 <zend_mm_alloc_heap+104>: cmp r15,0xc00 0xccf04f <zend_mm_alloc_heap+111>: ja 0xccf0a5 <zend_mm_alloc_heap+197> 0xccf051 <zend_mm_alloc_heap+113>: movzx eax,WORD PTR [r13+0x0] [------------------------------------------------------------------------------] ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=71535&edit=1

« previous php.bugs (#199441) next »