Bug #72405 [Fbk]: mb_ereg_replace - mbc_to_code (oniguruma) - oob read access

From: Date: Wed, 15 Jun 2016 15:49:22 +0000
Subject: Bug #72405 [Fbk]: mb_ereg_replace - mbc_to_code (oniguruma) - oob read access
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201658@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72405&edit=1 ID: 72405 Updated by: laruence@php.net Reported by: shm@php.net Summary: mb_ereg_replace - mbc_to_code (oniguruma) - oob read access Status: Feedback Type: Bug Package: mbstring related Operating System: Linux PHP Version: 7.0Git-2016-06-14 (Git) Block user comment: N Private report: N New Comment: hmm, this one seems really like a bug in oniguruma's bug.. Previous Comments: ------------------------------------------------------------------------ [2016-06-15 09:54:26] shm@php.net For provided case it works perfectly, but we've got another case if user provided string shorter than 6 chars, like this one: <?php mb_ereg_replace("\xfc",$_,$_); Function reads oob (but it's not using pat_buf). 105 c = *p++; gdb-peda$ print p $7 = (const OnigUChar *) 0x60060004ffdc "" gdb-peda$ bt #0 mbc_to_code (p=0x60060004ffdc "", end=0x60060004ffd9 "") at /home/shm/src/php-src/ext/mbstring/oniguruma/enc/utf8.c:105 ------------------------------------------------------------------------ [2016-06-15 07:00:29] laruence@php.net According to https://github.com/php/php-src/blob/master/ext/mbstring/oniguruma/enc/utf8.c#L291 the max bytes are 6 so...I made a attempt to fix it here: https://github.com/php/php-src/commit/999a3553d58c537b4919821855b2cc8fb62b0b2f thanks ------------------------------------------------------------------------ [2016-06-14 14:05:04] shm@php.net Description: ------------ mbc_to_code which is part of oniguruma library performs oob access if pattern is shorter than 6 characters. I'm not sure if it's PHP bug (due to misuse of oniugurma API or oniguruma internals bug, if so then please consider sending it upstream). DEBUGGER SESSION: Breakpoint 3, mbc_to_code (p=0x7fffffffa040 <incomplete sequence \374>, end=0x7fffffffa041 "") at /home/shm/src/php-src/ext/mbstring/oniguruma/enc/utf8.c:99 99 len = enclen(ONIG_ENCODING_UTF8, p); gdb-peda$ at the beginning we pushed to function following pattern "0xfc00" gdb-peda$ x/x p 0x7fffffffa040: 0x00000000000000fc gdb-peda$ c Program received signal SIGABRT, Aborted. gdb-peda$ #7 0x0000000000a08355 in mbc_to_code (p=0x7fffffffa045 "", end=0x7fffffffa041 "") at /home/shm/src/php-src/ext/mbstring/oniguruma/enc/utf8.c:105 105 c = *p++; gdb-peda$ print p $35 = (const OnigUChar *) 0x7fffffffa045 "" p is greater than end (which is unused in mbc_to_token). Pattern which is used in this function comes from _php_mb_regex_ereg_replace_exec Where pat_buf is declared as follows: 810 char pat_buf[4]; then gets initialized here: 857 /* FIXME: this code is not multibyte aware! */ 858 convert_to_long_ex(arg_pattern_zval); 859 pat_buf[0] = (char)Z_LVAL_P(arg_pattern_zval); 860 pat_buf[1] = '\0'; 861 pat_buf[2] = '\0'; 862 pat_buf[3] = '\0'; 863 864 arg_pattern = pat_buf; 865 arg_pattern_len = 1; Note the FIXME comment. Then it's used here: 868 re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, options, MBREX(current_mbctype), syntax); which internally calls mbc_to_code ASAN REPORT: ==20738==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff5c361494 at pc 0xa0b97d bp 0x7fff5c360790 sp 0x7fff5c360788 READ of size 1 at 0x7fff5c361494 thread T0 #0 0xa0b97c in mbc_to_code /home/shm/src/php-7.0.2/ext/mbstring/oniguruma/enc/utf8.c:105 #1 0x9f0420 in fetch_token /home/shm/src/php-7.0.2/ext/mbstring/oniguruma/regparse.c:3146 #2 0x9ff729 in parse_regexp /home/shm/src/php-7.0.2/ext/mbstring/oniguruma/regparse.c:5514 #3 0x9ffba6 in onig_parse_make_tree /home/shm/src/php-7.0.2/ext/mbstring/oniguruma/regparse.c:5543 #4 0x9c3b15 in onig_compile /home/shm/src/php-7.0.2/ext/mbstring/oniguruma/regcomp.c:5300 #5 0x9c4b8d in onig_new /home/shm/src/php-7.0.2/ext/mbstring/oniguruma/regcomp.c:5545 #6 0xaa051a in php_mbregex_compile_pattern /home/shm/src/php-7.0.2/ext/mbstring/php_mbregex.c:456 #7 0xaa26c8 in _php_mb_regex_ereg_replace_exec /home/shm/src/php-7.0.2/ext/mbstring/php_mbregex.c:868 #8 0xaa3a82 in zif_mb_ereg_replace /home/shm/src/php-7.0.2/ext/mbstring/php_mbregex.c:1029 #9 0x10eaac9 in ZEND_DO_ICALL_SPEC_HANDLER /home/shm/src/php-7.0.2/Zend/zend_vm_execute.h:586 #10 0x10e9b22 in execute_ex /home/shm/src/php-7.0.2/Zend/zend_vm_execute.h:414 #11 0x10e9da1 in zend_execute /home/shm/src/php-7.0.2/Zend/zend_vm_execute.h:458 #12 0xfc7b37 in zend_eval_stringl /home/shm/src/php-7.0.2/Zend/zend_execute_API.c:1129 #13 0xb82b53 in readline_shell_run /home/shm/src/php-7.0.2/ext/readline/readline_cli.c:669 #14 0x1223447 in do_cli /home/shm/src/php-7.0.2/sapi/cli/php_cli.c:972 #15 0x1225daa in main /home/shm/src/php-7.0.2/sapi/cli/php_cli.c:1345 #16 0x7fd94f301ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4) #17 0x42e208 (/home/shm/src/php-7.0.2/sapi/cli/php+0x42e208) Address 0x7fff5c361494 is located in stack of thread T0 at offset 1156 in frame #0 0xaa1e67 in _php_mb_regex_ereg_replace_exec /home/shm/src/php-7.0.2/ext/mbstring/php_mbregex.c:784 This frame has 18 object(s): [32, 36) 'eval' [96, 104) 'arg_pattern_zval' [160, 168) 'replace' [224, 232) 'replace_len' [288, 296) 'string' [352, 360) 'string_len' [416, 424) 'syntax' [480, 488) 'option_str' [544, 552) 'option_str_len' [608, 624) 'out_buf' [672, 688) 'eval_buf' [736, 752) 'args' [800, 816) 'subpats' [864, 880) 'retval' [928, 968) 'arg_replace_fci_cache' [1024, 1096) 'arg_replace_fci' [1152, 1156) 'pat_buf' <== Memory access at offset 1156 overflows this variable [1216, 1306) 'err_str' Test script: --------------- <?php mb_ereg_replace(0xfc,$_,$_); Expected result: ---------------- No oob access Actual result: -------------- Oob access in mbc_to_code ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72405&edit=1

« previous php.bugs (#201658) next »