php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72399 Use-After-Free in MBString (search_re)
Submitted: 2016-06-13 20:33 UTC Modified: 2016-06-14 08:28 UTC
From: shm@php.net Assigned: laruence (profile)
Status: Closed Package: mbstring related
PHP Version: 7.0Git-2016-06-13 (Git) OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: shm@php.net
New email:
PHP Version: OS:

 

 [2016-06-13 20:33 UTC] shm@php.net
Description:
------------
mbsearch is prone to use-after-free of global search_re memory, which in worst case can be used to gain code execution (when attacker is able to allocate memory that will be used in mbereg_search_pos).

### 1. search_re global is setup by mb_search_init

Breakpoint 2, php_mbregex_compile_pattern (pattern=0x60060004ff78 "2", patlen=0x1, options=0xc, enc=0x1f3e120 <OnigEncodingUTF8>, 
    syntax=0x1f39aa0 <OnigSyntaxRuby>) at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:456
456                     if ((err_code = onig_new(&retval, (OnigUChar *)pattern, (OnigUChar *)(pattern + patlen), options, enc, syntax, &err_info)) != ONIG_NO{
gdb-peda$ bt
#0  php_mbregex_compile_pattern (pattern=0x60060004ff78 "2", patlen=0x1, options=0xc, enc=0x1f3e120 <OnigEncodingUTF8>, syntax=0x1f39aa0 <OnigSyntaxRuby>)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:456
#1  0x0000000000aa26f6 in zif_mb_ereg_search_init (execute_data=0x7ffff23b9920, return_value=0x7ffff23b98c0)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1341
#2  0x00000000010fe846 in ZEND_DO_ICALL_SPEC_HANDLER () at /home/shm/src/php-src/Zend/zend_vm_execute.h:586
#3  0x00000000010fd8bf in execute_ex (ex=0x7ffff23b9830) at /home/shm/src/php-src/Zend/zend_vm_execute.h:414
#4  0x00000000010fdb1a in zend_execute (op_array=0x60220001fba0, return_value=0x0) at /home/shm/src/php-src/Zend/zend_vm_execute.h:458
#5  0x0000000001012aef in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /home/shm/src/php-src/Zend/zend.c:1427
#6  0x0000000000ea2159 in php_execute_script (primary_file=0x7fffffffcb30) at /home/shm/src/php-src/main/main.c:2494
#7  0x000000000122931c in do_cli (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:974
#8  0x000000000122b8f8 in main (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:1344
#9  0x00007ffff3581ec5 in __libc_start_main (main=0x122a3d0 <main>, argc=0x2, argv=0x7fffffffe038, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe028) at libc-start.c:287
#10 0x000000000042dc49 in _start ()

### 2. mb_eregi_replace compiles same pattern (but result won't be stored under search_re global

Breakpoint 2, php_mbregex_compile_pattern (pattern=0x60060004ff78 "2", patlen=0x1, options=0xd, enc=0x1f3e120 <OnigEncodingUTF8>, 
    syntax=0x1f39aa0 <OnigSyntaxRuby>) at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:456
456                     if ((err_code = onig_new(&retval, (OnigUChar *)pattern, (OnigUChar *)(pattern + patlen), options, enc, syntax, &err_info)) != ONIG_NO{
gdb-peda$ bt
#0  php_mbregex_compile_pattern (pattern=0x60060004ff78 "2", patlen=0x1, options=0xd, enc=0x1f3e120 <OnigEncodingUTF8>, syntax=0x1f39aa0 <OnigSyntaxRuby>)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:456
#1  0x0000000000a9ecdb in _php_mb_regex_ereg_replace_exec (execute_data=0x7ffff23b9920, return_value=0x7ffff23b98e0, options=0xd, is_callable=0x0)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:868
#2  0x0000000000aa022b in zif_mb_eregi_replace (execute_data=0x7ffff23b9920, return_value=0x7ffff23b98e0)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1043
#3  0x00000000010fe846 in ZEND_DO_ICALL_SPEC_HANDLER () at /home/shm/src/php-src/Zend/zend_vm_execute.h:586
#4  0x00000000010fd8bf in execute_ex (ex=0x7ffff23b9830) at /home/shm/src/php-src/Zend/zend_vm_execute.h:414
#5  0x00000000010fdb1a in zend_execute (op_array=0x60220001fba0, return_value=0x0) at /home/shm/src/php-src/Zend/zend_vm_execute.h:458
#6  0x0000000001012aef in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /home/shm/src/php-src/Zend/zend.c:1427
#7  0x0000000000ea2159 in php_execute_script (primary_file=0x7fffffffcb30) at /home/shm/src/php-src/main/main.c:2494
#8  0x000000000122931c in do_cli (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:974
#9  0x000000000122b8f8 in main (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:1344
#10 0x00007ffff3581ec5 in __libc_start_main (main=0x122a3d0 <main>, argc=0x2, argv=0x7fffffffe038, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe028) at libc-start.c:287
#11 0x000000000042dc49 in _start ()

gdb-peda$ up
#1  0x0000000000a9ecdb in _php_mb_regex_ereg_replace_exec (execute_data=0x7ffff23b9920, return_value=0x7ffff23b98e0, options=0xd, is_callable=0x0)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:868
868             re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, options, MBREX(current_mbctype), syntax);

### 3. in same the same call, reg for previous "2" pattern will be freed, but it's still referenced by global search_re 

Breakpoint 1, onig_free (reg=0x60300000fa40) at /home/shm/src/php-src/ext/mbstring/oniguruma/regcomp.c:5202
5202        xfree(reg);
gdb-peda$ bt
#0  onig_free (reg=0x60300000fa40) at /home/shm/src/php-src/ext/mbstring/oniguruma/regcomp.c:5202
#1  0x0000000000a9bed4 in php_mb_regex_free_cache (el=0x60260001ca40) at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:59
#2  0x000000000104335e in _zend_hash_add_or_update_i (ht=0x601a0000cf80, key=0x60060007b6a0, pData=0x7fffffff98d0, flag=0x1, 
    __zend_filename=0x18d7d60 "/home/shm/src/php-src/Zend/zend_hash.h", __zend_lineno=0x222) at /home/shm/src/php-src/Zend/zend_hash.c:596
#3  0x0000000001043c68 in _zend_hash_str_update (ht=0x601a0000cf80, str=0x60060004ff78 "2", len=0x1, pData=0x7fffffff98d0, 
    __zend_filename=0x18d7d60 "/home/shm/src/php-src/Zend/zend_hash.h", __zend_lineno=0x222) at /home/shm/src/php-src/Zend/zend_hash.c:667
#4  0x0000000000a9b899 in zend_hash_str_update_ptr (ht=0x601a0000cf80, str=0x60060004ff78 "2", len=0x1, pData=0x60300000f840)
    at /home/shm/src/php-src/Zend/zend_hash.h:546
#5  0x0000000000a9cdf6 in php_mbregex_compile_pattern (pattern=0x60060004ff78 "2", patlen=0x1, options=0xd, enc=0x1f3e120 <OnigEncodingUTF8>, 
    syntax=0x1f39aa0 <OnigSyntaxRuby>) at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:462
#6  0x0000000000a9ecdb in _php_mb_regex_ereg_replace_exec (execute_data=0x7ffff23b9920, return_value=0x7ffff23b98e0, options=0xd, is_callable=0x0)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:868
#7  0x0000000000aa022b in zif_mb_eregi_replace (execute_data=0x7ffff23b9920, return_value=0x7ffff23b98e0)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1043
#8  0x00000000010fe846 in ZEND_DO_ICALL_SPEC_HANDLER () at /home/shm/src/php-src/Zend/zend_vm_execute.h:586
#9  0x00000000010fd8bf in execute_ex (ex=0x7ffff23b9830) at /home/shm/src/php-src/Zend/zend_vm_execute.h:414
#10 0x00000000010fdb1a in zend_execute (op_array=0x60220001fba0, return_value=0x0) at /home/shm/src/php-src/Zend/zend_vm_execute.h:458
#11 0x0000000001012aef in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /home/shm/src/php-src/Zend/zend.c:1427
#12 0x0000000000ea2159 in php_execute_script (primary_file=0x7fffffffcb30) at /home/shm/src/php-src/main/main.c:2494
#13 0x000000000122931c in do_cli (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:974
#14 0x000000000122b8f8 in main (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:1344
#15 0x00007ffff3581ec5 in __libc_start_main (main=0x122a3d0 <main>, argc=0x2, argv=0x7fffffffe038, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe028) at libc-start.c:287
#16 0x000000000042dc49 in _start ()


### 4. search_re is referenced in mb_ereg_search_pos

Stopped reason: SIGABRT
0x00007ffff3596cc9 in __GI_raise (sig=sig@entry=0x6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
gdb-peda$ bt
#0  0x00007ffff3596cc9 in __GI_raise (sig=sig@entry=0x6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff359a0d8 in __GI_abort () at abort.c:89
#2  0x00007ffff4e667f9 in ?? () from /usr/lib/x86_64-linux-gnu/libasan.so.0
#3  0x00007ffff4e5d3ec in ?? () from /usr/lib/x86_64-linux-gnu/libasan.so.0
#4  0x00007ffff4e63fe2 in ?? () from /usr/lib/x86_64-linux-gnu/libasan.so.0
#5  0x00007ffff4e630f1 in __asan_report_error () from /usr/lib/x86_64-linux-gnu/libasan.so.0
#6  0x00007ffff4e5d704 in __asan_report_load4 () from /usr/lib/x86_64-linux-gnu/libasan.so.0
#7  0x00000000009db00d in onig_search (reg=0x60300000fa40, str=0x60060000ec68 "", end=0x60060000ec68 "", start=0x60060000ec68 "", range=0x60060000ec68 "", 
    region=0x60060007b640, option=0x0) at /home/shm/src/php-src/ext/mbstring/oniguruma/regexec.c:3397
#8  0x0000000000aa17b7 in _php_mb_regex_ereg_search_exec (execute_data=0x7ffff23b9920, return_value=0x7ffff23b9900, mode=0x1)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1234
#9  0x0000000000aa2337 in zif_mb_ereg_search_pos (execute_data=0x7ffff23b9920, return_value=0x7ffff23b9900)
    at /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1299
#10 0x00000000010fe846 in ZEND_DO_ICALL_SPEC_HANDLER () at /home/shm/src/php-src/Zend/zend_vm_execute.h:586
#11 0x00000000010fd8bf in execute_ex (ex=0x7ffff23b9830) at /home/shm/src/php-src/Zend/zend_vm_execute.h:414
#12 0x00000000010fdb1a in zend_execute (op_array=0x60220001fba0, return_value=0x0) at /home/shm/src/php-src/Zend/zend_vm_execute.h:458
#13 0x0000000001012aef in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /home/shm/src/php-src/Zend/zend.c:1427
#14 0x0000000000ea2159 in php_execute_script (primary_file=0x7fffffffcb30) at /home/shm/src/php-src/main/main.c:2494
#15 0x000000000122931c in do_cli (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:974
#16 0x000000000122b8f8 in main (argc=0x2, argv=0x60060000ed40) at /home/shm/src/php-src/sapi/cli/php_cli.c:1344
#17 0x00007ffff3581ec5 in __libc_start_main (main=0x122a3d0 <main>, argc=0x2, argv=0x7fffffffe038, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe028) at libc-start.c:287
#18 0x000000000042dc49 in _start ()

ASAN report:

$ ASAN_OPTIONS=symbolize=1 ./php minerva.147.1555293821
=================================================================
==24278== ERROR: AddressSanitizer: heap-use-after-free on address 0x60300000fa54 at pc 0x9db00d bp 0x7fff52215ad0 sp 0x7fff52215ac8
READ of size 4 at 0x60300000fa54 thread T0
    #0 0x9db00c in onig_search /home/shm/src/php-src/ext/mbstring/oniguruma/regexec.c:3397
    #1 0xaa17b6 in _php_mb_regex_ereg_search_exec /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1234
    #2 0xaa2336 in zif_mb_ereg_search_pos /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1299
    #3 0x10fe845 in ZEND_DO_ICALL_SPEC_HANDLER /home/shm/src/php-src/Zend/zend_vm_execute.h:586
    #4 0x10fd8be in execute_ex /home/shm/src/php-src/Zend/zend_vm_execute.h:414
    #5 0x10fdb19 in zend_execute /home/shm/src/php-src/Zend/zend_vm_execute.h:458
    #6 0x1012aee in zend_execute_scripts /home/shm/src/php-src/Zend/zend.c:1427
    #7 0xea2158 in php_execute_script /home/shm/src/php-src/main/main.c:2494
    #8 0x122931b in do_cli /home/shm/src/php-src/sapi/cli/php_cli.c:974
    #9 0x122b8f7 in main /home/shm/src/php-src/sapi/cli/php_cli.c:1344
    #10 0x7f16a28a9ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #11 0x42dc48 in _start (/home/shm/src/php-src/sapi/cli/php+0x42dc48)
0x60300000fa54 is located 20 bytes inside of 440-byte region [0x60300000fa40,0x60300000fbf8)
freed by thread T0 here:
    #0 0x7f16a41a533a (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1533a)
    #1 0x9bfba9 in onig_free /home/shm/src/php-src/ext/mbstring/oniguruma/regcomp.c:5202
    #2 0xa9bed3 in php_mb_regex_free_cache /home/shm/src/php-src/ext/mbstring/php_mbregex.c:59
    #3 0x104335d in _zend_hash_add_or_update_i /home/shm/src/php-src/Zend/zend_hash.c:596
    #4 0x1043c67 in _zend_hash_str_update /home/shm/src/php-src/Zend/zend_hash.c:667
    #5 0xa9b898 in zend_hash_str_update_ptr /home/shm/src/php-src/Zend/zend_hash.h:546
    #6 0xa9cdf5 in php_mbregex_compile_pattern /home/shm/src/php-src/ext/mbstring/php_mbregex.c:462
    #7 0xa9ecda in _php_mb_regex_ereg_replace_exec /home/shm/src/php-src/ext/mbstring/php_mbregex.c:868
    #8 0xaa022a in zif_mb_eregi_replace /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1043
    #9 0x10fe845 in ZEND_DO_ICALL_SPEC_HANDLER /home/shm/src/php-src/Zend/zend_vm_execute.h:586
    #10 0x10fd8be in execute_ex /home/shm/src/php-src/Zend/zend_vm_execute.h:414
    #11 0x10fdb19 in zend_execute /home/shm/src/php-src/Zend/zend_vm_execute.h:458
    #12 0x1012aee in zend_execute_scripts /home/shm/src/php-src/Zend/zend.c:1427
    #13 0xea2158 in php_execute_script /home/shm/src/php-src/main/main.c:2494
    #14 0x122931b in do_cli /home/shm/src/php-src/sapi/cli/php_cli.c:974
    #15 0x122b8f7 in main /home/shm/src/php-src/sapi/cli/php_cli.c:1344
    #16 0x7f16a28a9ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
previously allocated by thread T0 here:
    #0 0x7f16a41a541a (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1541a)
    #1 0x9c1960 in onig_new /home/shm/src/php-src/ext/mbstring/oniguruma/regcomp.c:5539
    #2 0xa9cd18 in php_mbregex_compile_pattern /home/shm/src/php-src/ext/mbstring/php_mbregex.c:456
    #3 0xaa26f5 in zif_mb_ereg_search_init /home/shm/src/php-src/ext/mbstring/php_mbregex.c:1341
    #4 0x10fe845 in ZEND_DO_ICALL_SPEC_HANDLER /home/shm/src/php-src/Zend/zend_vm_execute.h:586
    #5 0x10fd8be in execute_ex /home/shm/src/php-src/Zend/zend_vm_execute.h:414
    #6 0x10fdb19 in zend_execute /home/shm/src/php-src/Zend/zend_vm_execute.h:458
    #7 0x1012aee in zend_execute_scripts /home/shm/src/php-src/Zend/zend.c:1427
    #8 0xea2158 in php_execute_script /home/shm/src/php-src/main/main.c:2494
    #9 0x122931b in do_cli /home/shm/src/php-src/sapi/cli/php_cli.c:974
    #10 0x122b8f7 in main /home/shm/src/php-src/sapi/cli/php_cli.c:1344
    #11 0x7f16a28a9ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
SUMMARY: AddressSanitizer: heap-use-after-free /home/shm/src/php-src/ext/mbstring/oniguruma/regexec.c:3397 onig_search
Shadow bytes around the buggy address:
  0x0c067fff9ef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9f00: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c067fff9f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff9f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff9f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
=>0x0c067fff9f40: fa fa fa fa fa fa fa fa fd fd[fd]fd fd fd fd fd
  0x0c067fff9f50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c067fff9f60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c067fff9f70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x0c067fff9f80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c067fff9f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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 righ 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
  ASan internal:         fe
==24278== ABORTING

Test script:
---------------
<?php
$var5 = mbereg_search_init("","2");
$var6 = mb_eregi_replace("2","","");
$var13 = mbereg_search_pos();

Expected result:
----------------
No use-after-free present in the code

Actual result:
--------------
use-after-free present in the code

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-06-13 20:34 UTC] shm@php.net
-PHP Version: 7.1Git-2016-06-13 (Git) +PHP Version: 7.0Git-2016-06-13 (Git)
 [2016-06-13 20:34 UTC] shm@php.net
7.1 -> 7.0
 [2016-06-14 01:17 UTC] laruence@php.net
-Type: Security +Type: Bug
 [2016-06-14 01:17 UTC] laruence@php.net
this is not a security issue, as you need specially codes to trigger it
 [2016-06-14 01:20 UTC] laruence@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3d5641872239cbd4ec8855b05c90f94fb0d11d7e
Log: Fixed bug #72399 (Use-After-Free in MBString (search_re))
 [2016-06-14 01:20 UTC] laruence@php.net
-Status: Open +Status: Closed
 [2016-06-14 06:32 UTC] shm@php.net
I'm not sure what we consider as a security issue. Previously bugs like this one were marked as security bugs (it can be used to bypass disable_functions upon code execution is done, potentially code to trigger that issue could be also present in popular script). Do we have any policy on this subject?
 [2016-06-14 07:57 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-06-14 07:57 UTC] stas@php.net
Yes, we do. Issues that require local access to trigger do not considered as a rule security issues, since once you can run code on a local host, you can do anything anyway.
 [2016-06-14 07:57 UTC] stas@php.net
-Assigned To: stas +Assigned To: laruence
 [2016-06-14 08:28 UTC] shm@php.net
Thanks for the clarification. Still, shown code pattern could be used in popular script, thus it would let to perform attack from the remote.

I don't want to force this bug (or any other as a security issue), but I'm just a little bit confused - what's the difference between this one and https://bugs.php.net/bug.php?id=72093 this one for example.
 [2016-06-22 05:58 UTC] krakjoe@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3d5641872239cbd4ec8855b05c90f94fb0d11d7e
Log: Fixed bug #72399 (Use-After-Free in MBString (search_re))
 [2016-07-20 11:30 UTC] davey@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3d5641872239cbd4ec8855b05c90f94fb0d11d7e
Log: Fixed bug #72399 (Use-After-Free in MBString (search_re))
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC