Bug #73505 [Opn->Csd]: string length overflow in mbfl_memory_device_output function

From: Date: Sun, 23 Jul 2017 10:12:47 +0000
Subject: Bug #73505 [Opn->Csd]: string length overflow in mbfl_memory_device_output function
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-210224@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73505&edit=1 ID: 73505 Updated by: nikic@php.net Reported by: nguyenluan dot vnn at gmail dot com Summary: string length overflow in mbfl_memory_device_output function -Status: Open +Status: Closed Type: Bug Package: mbstring related PHP Version: 5.6.28 -Assigned To: +Assigned To: nikic Block user comment: N Private report: N New Comment: The specific issue here already seems to be resolved in PHP 7. The first duplicate is fixed in master. Previous Comments: ------------------------------------------------------------------------ [2016-11-26 22:56:22] stas@php.net Related To: Bug #73268 ------------------------------------------------------------------------ [2016-11-16 22:02:47] stas@php.net Related To: Bug #73534 ------------------------------------------------------------------------ [2016-11-12 12:34:31] nguyenluan dot vnn at gmail dot com Description: ------------ This bug is related to Bug #73082. The fix https://gist.github.com/anonymous/5677c59cc852e4935cad3571a0daf761, although can prevent produce string with size larger than 2Gb but does NOT totally resolve this bug. PHP 5 still crashes because the index value "device->pos" in function mbfl_memory_device_output is larger than 2Gb. int mbfl_memory_device_output(int c, void *data) { mbfl_memory_device *device = (mbfl_memory_device *)data; if (device->pos >= device->length) { /* reallocate buffer */ int newlen; unsigned char *tmp; newlen = device->length + device->allocsz; tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen*sizeof(unsigned char)); if (tmp == NULL) { return -1; } device->length = newlen; device->buffer = tmp; } device->buffer[device->pos++] = (unsigned char)c; // (1) crash here return c; } Test script: --------------- <?php ini_set('memory_limit', -1); $str = str_repeat("a", 0xffffffff/9); //a -> &#97; output_len = input_len*5 -> overflow integer var_dump(strlen($str)); $str1 = mb_encode_numericentity ($str, array (0x0, 0xffff, 0, 0xffff), 'UTF-8'); ?> Expected result: ---------------- No crash. Actual result: -------------- gdb-peda$ r ../test/string/test.php Starting program: /home/user/Desktop/php-5.6.28/sapi/cli/php ../test/string/test.php [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". int(477218588) Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] RAX: 0x7ffe6b3e6070 RBX: 0xae8b93 (<execute_ex>: push rbp) RCX: 0x80000001 RDX: 0x37 ('7') RSI: 0x7ffeeb3e6070 ("&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;"...) RDI: 0x37 ('7') RBP: 0x7fffffffa4d0 --> 0x7fffffffa4f0 --> 0x7fffffffa540 --> 0x7fffffffa570 --> 0x7fffffffa610 --> 0x7fffffffa740 (--> ...) RSP: 0x7fffffffa4a0 --> 0x7fffffffa5c0 --> 0x7ffeeb3e6070 ("&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;"...) RIP: 0x78f6ba (<mbfl_memory_device_output+162>: mov BYTE PTR [rax],dl) R8 : 0x280 R9 : 0x0 R10: 0x1 R11: 0x7ffff3603730 --> 0xfffda400fffda12f R12: 0x444220 (<_start>: xor ebp,ebp) R13: 0x7fffffffe1a0 --> 0x2 R14: 0x0 R15: 0x0 EFLAGS: 0x10203 (CARRY parity adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x78f6b2 <mbfl_memory_device_output+154>: cdqe 0x78f6b4 <mbfl_memory_device_output+156>: add rax,rsi 0x78f6b7 <mbfl_memory_device_output+159>: mov edx,DWORD PTR [rbp-0x24] => 0x78f6ba <mbfl_memory_device_output+162>: mov BYTE PTR [rax],dl 0x78f6bc <mbfl_memory_device_output+164>: mov eax,DWORD PTR [rbp-0x24] 0x78f6bf <mbfl_memory_device_output+167>: leave 0x78f6c0 <mbfl_memory_device_output+168>: ret 0x78f6c1 <mbfl_memory_device_output2>: push rbp [------------------------------------stack-------------------------------------] 0000| 0x7fffffffa4a0 --> 0x7fffffffa5c0 --> 0x7ffeeb3e6070 ("&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;"...) 0008| 0x7fffffffa4a8 --> 0x37f7fba377 0016| 0x7fffffffa4b0 --> 0x3748 ('H7') 0024| 0x7fffffffa4b8 --> 0x800008dc00000000 0032| 0x7fffffffa4c0 --> 0x7fffffffa5c0 --> 0x7ffeeb3e6070 ("&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;"...) 0040| 0x7fffffffa4c8 --> 0x7ffeeb3e6070 ("&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;&#97;"...) 0048| 0x7fffffffa4d0 --> 0x7fffffffa4f0 --> 0x7fffffffa540 --> 0x7fffffffa570 --> 0x7fffffffa610 --> 0x7fffffffa740 (--> ...) 0056| 0x7fffffffa4d8 --> 0x786713 (<mbfl_filt_conv_wchar_utf8+70>: test eax,eax) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x000000000078f6ba in mbfl_memory_device_output (c=0x37, data=0x7fffffffa5c0) at /home/user/Desktop/php-5.6.28/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c:157 157 device->buffer[device->pos++] = (unsigned char)c; gdb-peda$ bt #0 0x000000000078f6ba in mbfl_memory_device_output (c=0x37, data=0x7fffffffa5c0) at /home/user/Desktop/php-5.6.28/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c:157 #1 0x0000000000786713 in mbfl_filt_conv_wchar_utf8 (c=0x37, filter=0x7ffff7fba738) at /home/user/Desktop/php-5.6.28/ext/mbstring/libmbfl/filters/mbfilter_utf8.c:219 #2 0x000000000078d14e in collector_encode_htmlnumericentity (c=0x61, data=0x7fffffffa5e0) at /home/user/Desktop/php-5.6.28/ext/mbstring/libmbfl/mbfl/mbfilter.c:2709 #3 0x0000000000786388 in mbfl_filt_conv_utf8_wchar (c=0x61, filter=0x7ffff7fba800) at /home/user/Desktop/php-5.6.28/ext/mbstring/libmbfl/filters/mbfilter_utf8.c:118 #4 0x000000000078e0f4 in mbfl_html_numeric_entity (string=0x7fffffffa700, result=0x7fffffffa720, convmap=0x7ffff7fb9bb8, mapsize=0x1, type=0x0) at /home/user/Desktop/php-5.6.28/ext/mbstring/libmbfl/mbfl/mbfilter.c:3092 #5 0x000000000079a629 in php_mb_numericentity_exec (ht=0x3, return_value=0x7ffff7fba6c0, return_value_ptr=0x7ffff7f80218, this_ptr=0x0, return_value_used=0x1, type=0x0) at /home/user/Desktop/php-5.6.28/ext/mbstring/mbstring.c:3842 #6 0x000000000079a79f in zif_mb_encode_numericentity (ht=0x3, return_value=0x7ffff7fba6c0, return_value_ptr=0x7ffff7f80218, this_ptr=0x0, return_value_used=0x1) at /home/user/Desktop/php-5.6.28/ext/mbstring/mbstring.c:3856 #7 0x0000000000ae958b in zend_do_fcall_common_helper_SPEC ( execute_data=0x7ffff7f80310) at /home/user/Desktop/php-5.6.28/Zend/zend_vm_execute.h:558 #8 0x0000000000aef0b6 in ZEND_DO_FCALL_SPEC_CONST_HANDLER ( execute_data=0x7ffff7f80310) at /home/user/Desktop/php-5.6.28/Zend/zend_vm_execute.h:2602 #9 0x0000000000ae8bf3 in execute_ex (execute_data=0x7ffff7f80310) at /home/user/Desktop/php-5.6.28/Zend/zend_vm_execute.h:363 #10 0x0000000000ae8c7a in zend_execute (op_array=0x7ffff7fb84e0) at /home/user/Desktop/php-5.6.28/Zend/zend_vm_execute.h:388 #11 0x0000000000aa162a in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /home/user/Desktop/php-5.6.28/Zend/zend.c:1341 #12 0x0000000000a0264f in php_execute_script (primary_file=0x7fffffffcd70) at /home/user/Desktop/php-5.6.28/main/main.c:2613 #13 0x0000000000b5e442 in do_cli (argc=0x2, argv=0x1462630) at /home/user/Desktop/php-5.6.28/sapi/cli/php_cli.c:998 #14 0x0000000000b5f7a5 in main (argc=0x2, argv=0x1462630) at /home/user/Desktop/php-5.6.28/sapi/cli/php_cli.c:1382 #15 0x00007ffff348f830 in __libc_start_main (main=0xb5ef88 <main>, argc=0x2, argv=0x7fffffffe1a8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe198) at ../csu/libc-start.c:291 #16 0x0000000000444249 in _start () gdb-peda$ p device->pos $1 = 0x80000001 // value larger than 2Gb ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=73505&edit=1

« previous php.bugs (#210224) next »