|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2017-05-18 02:50 UTC] l dot wei at ntu dot edu dot sg
[2017-06-20 06:21 UTC] stas@php.net
-Type: Security
+Type: Bug
-Assigned To:
+Assigned To: hirokawa
[2017-06-20 06:21 UTC] stas@php.net
[2017-10-24 07:00 UTC] kalle@php.net
-Status: Assigned
+Status: Open
-Assigned To: hirokawa
+Assigned To:
[2020-03-05 09:15 UTC] cmb@php.net
-Status: Open
+Status: Closed
-Assigned To:
+Assigned To: cmb
[2020-03-05 09:15 UTC] cmb@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 04:00:01 2025 UTC |
Description: ------------ The multi-byte regex engine oniguruma, when handling malformed regular expressions, would write out-of-bound, usually leading to a heap corruption. When the regex is from network, this potentially would lead to a remote RCE. Tested on both 5.6.30 and 7.1.5, on 32-bit and 64-bit builds in Ubuntu Linux. The following are shown on bin/php 64-bit build with -fsanitize=address, --enable-mbstring Some of the repros are attached. Test script: --------------- $ cat regex.php <?php $argc = $_SERVER['argc']; $argv = $_SERVER['argv']; $dir_str = dirname(__FILE__); $file_str = ($dir_str)."/".$argv[1]; echo "Input file: ".$file_str."\n"; if (!extension_loaded('mbstring')) print "mbstring not loaded.\n"; if (!function_exists('mb_ereg_replace')) print "mb_ereg_replace() is not available\n"; $mb_str = file_get_contents($file_str); print strlen($mb_str) . " bytes read.\n"; echo "*** Testing mb_ereg_replace() ***\n"; echo mb_ereg_replace($mb_str, "\\1", "a\\2bxc"); ?> Expected result: ---------------- No crash. Actual result: -------------- A minimal repro that gives a SEGV in next_state_val() by corrupting 1-bit with a large index, on Ubuntu x86_64: regparse.c:4087 BITSET_SET_BIT(cc->bs, (int )(*vs)); $ xxd -g 1 fs5_id29_min 00000000: 30 5b 0b 2d 30 2d 2d 30 2d 2d 30 2d fb fb fb 30 0[.-0--0--0-...0 $ bin/php regex.php fs5_id29_min Input file: /home/xie/php_fuzz/fs5_id29_min 16 bytes read. *** Testing mb_ereg_replace() *** ASAN:SIGSEGV ================================================================= ==15778==ERROR: AddressSanitizer: SEGV on unknown address 0x606000028504 (pc 0x00000084562a bp 0x7ffdb84cffb0 sp 0x7ffdb84cfe80 T0) #0 0x845629 in next_state_val /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4087 #1 0x84b97f in parse_char_class /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4304 #2 0x85511b in parse_exp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5270 #3 0x8589a5 in parse_branch /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5445 #4 0x858c2d in parse_subexp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5472 #5 0x8593ef in parse_regexp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5516 #6 0x8593ef in onig_parse_make_tree /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5543 #7 0x82de6e in onig_compile /home/xie/php-7.1.5/ext/mbstring/oniguruma/regcomp.c:5300 #8 0x82f8e5 in onig_new /home/xie/php-7.1.5/ext/mbstring/oniguruma/regcomp.c:5545 #9 0x8c50a0 in php_mbregex_compile_pattern /home/xie/php-7.1.5/ext/mbstring/php_mbregex.c:456 #10 0x8c637b in _php_mb_regex_ereg_replace_exec /home/xie/php-7.1.5/ext/mbstring/php_mbregex.c:901 #11 0xda5c21 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/xie/php-7.1.5/Zend/zend_vm_execute.h:675 #12 0xd5f93d in execute_ex /home/xie/php-7.1.5/Zend/zend_vm_execute.h:429 #13 0xec5c91 in zend_execute /home/xie/php-7.1.5/Zend/zend_vm_execute.h:474 #14 0xc7dd12 in zend_execute_scripts /home/xie/php-7.1.5/Zend/zend.c:1476 #15 0xb8044f in php_execute_script /home/xie/php-7.1.5/main/main.c:2537 #16 0xeca7d0 in do_cli /home/xie/php-7.1.5/sapi/cli/php_cli.c:993 #17 0x43ef86 in main /home/xie/php-7.1.5/sapi/cli/php_cli.c:1381 #18 0x7f7a9755082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #19 0x43f228 in _start (/home/xie/php7_asan/bin/php+0x43f228) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4087 next_state_val ==15778==ABORTING A few other variations: $ xxd -g 1 fs6_id33_min 00000000: 5b 30 2d fc 30 30 30 30 30 2d c4 30 [0-.00000-.0 $ bin/php regex.php fs6_id33_min Input file: /home/xie/php_fuzz/fs6_id33_min 12 bytes read. *** Testing mb_ereg_replace() *** ASAN:SIGSEGV ================================================================= ==15781==ERROR: AddressSanitizer: SEGV on unknown address 0x2c047fff97a2 (pc 0x0000008446e0 bp 0x00000130e0e4 sp 0x7ffe308b8920 T0) #0 0x8446df in bbuf_free /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:104 #1 0x84ae9a in onig_node_free /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:1048 #2 0x84b3bf in parse_char_class /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4497 #3 0x85511b in parse_exp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5270 #4 0x85890d in parse_branch /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5435 #5 0x858c2d in parse_subexp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5472 #6 0x8593ef in parse_regexp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5516 #7 0x8593ef in onig_parse_make_tree /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5543 #8 0x82de6e in onig_compile /home/xie/php-7.1.5/ext/mbstring/oniguruma/regcomp.c:5300 #9 0x82f8e5 in onig_new /home/xie/php-7.1.5/ext/mbstring/oniguruma/regcomp.c:5545 #10 0x8c50a0 in php_mbregex_compile_pattern /home/xie/php-7.1.5/ext/mbstring/php_mbregex.c:456 #11 0x8c637b in _php_mb_regex_ereg_replace_exec /home/xie/php-7.1.5/ext/mbstring/php_mbregex.c:901 #12 0xda5c21 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/xie/php-7.1.5/Zend/zend_vm_execute.h:675 #13 0xd5f93d in execute_ex /home/xie/php-7.1.5/Zend/zend_vm_execute.h:429 #14 0xec5c91 in zend_execute /home/xie/php-7.1.5/Zend/zend_vm_execute.h:474 #15 0xc7dd12 in zend_execute_scripts /home/xie/php-7.1.5/Zend/zend.c:1476 #16 0xb8044f in php_execute_script /home/xie/php-7.1.5/main/main.c:2537 #17 0xeca7d0 in do_cli /home/xie/php-7.1.5/sapi/cli/php_cli.c:993 #18 0x43ef86 in main /home/xie/php-7.1.5/sapi/cli/php_cli.c:1381 #19 0x7fcfe9c5582f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #20 0x43f228 in _start (/home/xie/php7_asan/bin/php+0x43f228) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:104 bbuf_free ==15781==ABORTING Other variations (repros can be uploaded on request). $ bin/php regex.php fs5_id29 Input file: /home/xie/php_fuzz/fs5_id29 1245 bytes read. *** Testing mb_ereg_replace() *** ================================================================= ==15901==ERROR: AddressSanitizer: heap-use-after-free on address 0x60600000bc30 at pc 0x00000084533a bp 0x7fff88fbfef0 sp 0x7fff88fbfee0 READ of size 8 at 0x60600000bc30 thread T0 #0 0x845339 in add_code_range_to_buf /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:1716 #1 0x84566d in add_code_range /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:1781 #2 0x84566d in next_state_val /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4089 #3 0x84b97f in parse_char_class /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4304 #4 0x84b480 in parse_char_class /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4402 #5 0x84b480 in parse_char_class /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4402 #6 0x85511b in parse_exp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5270 #7 0x85890d in parse_branch /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5435 #8 0x858c2d in parse_subexp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5472 #9 0x855f90 in parse_enclose /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:4730 #10 0x855f90 in parse_exp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5057 #11 0x85890d in parse_branch /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5435 #12 0x858c2d in parse_subexp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5472 #13 0x8593ef in parse_regexp /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5516 #14 0x8593ef in onig_parse_make_tree /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:5543 #15 0x82de6e in onig_compile /home/xie/php-7.1.5/ext/mbstring/oniguruma/regcomp.c:5300 #16 0x82f8e5 in onig_new /home/xie/php-7.1.5/ext/mbstring/oniguruma/regcomp.c:5545 #17 0x8c50a0 in php_mbregex_compile_pattern /home/xie/php-7.1.5/ext/mbstring/php_mbregex.c:456 #18 0x8c637b in _php_mb_regex_ereg_replace_exec /home/xie/php-7.1.5/ext/mbstring/php_mbregex.c:901 #19 0xda5c21 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/xie/php-7.1.5/Zend/zend_vm_execute.h:675 #20 0xd5f93d in execute_ex /home/xie/php-7.1.5/Zend/zend_vm_execute.h:429 #21 0xec5c91 in zend_execute /home/xie/php-7.1.5/Zend/zend_vm_execute.h:474 #22 0xc7dd12 in zend_execute_scripts /home/xie/php-7.1.5/Zend/zend.c:1476 #23 0xb8044f in php_execute_script /home/xie/php-7.1.5/main/main.c:2537 #24 0xeca7d0 in do_cli /home/xie/php-7.1.5/sapi/cli/php_cli.c:993 #25 0x43ef86 in main /home/xie/php-7.1.5/sapi/cli/php_cli.c:1381 #26 0x7ff18d2a682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #27 0x43f228 in _start (/home/xie/php7_asan/bin/php+0x43f228) 0x60600000bc30 is located 48 bytes inside of 56-byte region [0x60600000bc00,0x60600000bc38) freed by thread T0 here: #0 0x7ff18e1ca2ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca) #1 0xcfd166 in zend_string_release /home/xie/php-7.1.5/Zend/zend_string.h:272 #2 0xcfd166 in zend_new_interned_string_int /home/xie/php-7.1.5/Zend/zend_string.c:148 previously allocated by thread T0 here: #0 0x7ff18e1ca602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0xc05d88 in __zend_malloc /home/xie/php-7.1.5/Zend/zend_alloc.c:2820 #2 0x1a3b9df (/home/xie/php7_asan/bin/php+0x1a3b9df) SUMMARY: AddressSanitizer: heap-use-after-free /home/xie/php-7.1.5/ext/mbstring/oniguruma/regparse.c:1716 add_code_range_to_buf Shadow bytes around the buggy address: 0x0c0c7fff9730: 00 00 00 fa fa fa fa fa fd fd fd fd fd fd fd fa 0x0c0c7fff9740: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa 0x0c0c7fff9750: fd fd fd fd fd fd fd fa fa fa fa fa 00 00 00 00 0x0c0c7fff9760: 00 00 00 fa fa fa fa fa fd fd fd fd fd fd fd fa 0x0c0c7fff9770: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa =>0x0c0c7fff9780: fd fd fd fd fd fd[fd]fa fa fa fa fa 00 00 00 00 0x0c0c7fff9790: 00 00 00 fa fa fa fa fa fd fd fd fd fd fd fd fa 0x0c0c7fff97a0: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa 0x0c0c7fff97b0: fd fd fd fd fd fd fd fa fa fa fa fa 00 00 00 00 0x0c0c7fff97c0: 00 00 00 fa fa fa fa fa fd fd fd fd fd fd fd fa 0x0c0c7fff97d0: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe ==15901==ABORTING