|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2016-02-15 08:22 UTC] stas@php.net
-Status: Open
+Status: Feedback
[2016-02-15 08:22 UTC] stas@php.net
[2016-02-17 17:11 UTC] hlt99 at blinkenshell dot org
-Status: Feedback
+Status: Open
[2016-02-17 17:11 UTC] hlt99 at blinkenshell dot org
[2016-02-22 00:21 UTC] stas@php.net
-Type: Security
+Type: Bug
-Assigned To:
+Assigned To: dmitry
[2016-02-24 08:06 UTC] dmitry@php.net
[2016-02-24 08:06 UTC] dmitry@php.net
-Status: Assigned
+Status: Closed
[2016-07-20 11:33 UTC] davey@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 04:00:02 2025 UTC |
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] [------------------------------------------------------------------------------]