php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #77370 Buffer overflow on mb regex functions - fetch_token
Submitted: 2018-12-29 20:45 UTC Modified: 2019-02-22 22:08 UTC
From: hugh at allthethings dot co dot nz Assigned: stas (profile)
Status: Closed Package: mbstring related
PHP Version: 5.6.39 OS: *
Private report: No CVE-ID: 2019-9023
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: hugh at allthethings dot co dot nz
New email:
PHP Version: OS:

 

 [2018-12-29 20:45 UTC] hugh at allthethings dot co dot nz
Description:
------------
Affects the $pattern of mb_ regex functions, such as mb_split, mb_ereg, and probably others given where my fix was.

In ext/mbstring/oniguruma/regparse.c, the function fetch_token takes a UChar **src, and a UChar *end. At completion of the method it sets *src to be where the pointer is currently (p). If there is an unfinished multibyte char at the end of the string then p can go beyond end. This causes flow on affects where src is then passed to onig_node_str_cat with *src which points past the end of the string buffer. This leads to a heap buffer overflow, which could cause memory corruption and/or leakage.

Could reproduce this on php 5.6.39, 7.0.33, and 7.1.25. I could not reproduce on 7.2.13, 7.3.0 or master due to the file being replaced.

A patch to fix is available at https://gist.github.com/hughdavenport/c5696e48ea3a83bfe12075f79b2b5abf

Test script:
---------------
php -r 'var_dump(mb_split("   \xfd",""));'

on php 5.6, weirdly it didn't crash with a plain string, but could get it to crash passing in a file.

$ xxd -g 1 mb_split_heap_crash-min5_6
00000000: fd                                               .

$ php -r 'var_dump(mb_ereg(file_get_contents($argv[1]),""));' mb_split_heap_crash-min5_6


Expected result:
----------------
no crash

Actual result:
--------------
$ ~/php-5.6.39/sapi/cli/php -r 'var_dump(mb_ereg(file_get_contents($argv[1]),""));' ../mb_split_heap_crash-min5_6
=================================================================
==16331==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000d7f2 at pc 0x0000004d67d1 bp 0x7ffcaa0ba840 sp 0x7ffcaa0b9ff0
READ of size 6 at 0x60200000d7f2 thread T0
    #0 0x4d67d0 in __asan_memcpy (/home/hugh/php-5.6.39/sapi/cli/php+0x4d67d0)
    #1 0x87dddb in onig_strcpy /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:223:5
    #2 0x87dddb in onig_node_str_cat /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:1447
    #3 0x88e660 in node_new_str /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:1506:7
    #4 0x88e660 in parse_exp /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:5092
    #5 0x88c525 in parse_branch /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:5441:7
    #6 0x889442 in parse_subexp /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:5478:7
    #7 0x8802e5 in parse_regexp /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:5522:7
    #8 0x8802e5 in onig_parse_make_tree /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regparse.c:5549
    #9 0x805655 in onig_compile /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regcomp.c:5300:7
    #10 0x82df69 in onig_new /home/hugh/php-5.6.39/ext/mbstring/oniguruma/regcomp.c:5545:7
    #11 0x9a7895 in php_mbregex_compile_pattern /home/hugh/php-5.6.39/ext/mbstring/php_mbregex.c:458:19
    #12 0x9a0809 in _php_mb_regex_ereg_exec /home/hugh/php-5.6.39/ext/mbstring/php_mbregex.c:728:7
    #13 0x11a27d8 in zend_do_fcall_common_helper_SPEC /home/hugh/php-5.6.39/Zend/zend_vm_execute.h:558:5
    #14 0xffc73d in execute_ex /home/hugh/php-5.6.39/Zend/zend_vm_execute.h:363:14
    #15 0xffe722 in zend_execute /home/hugh/php-5.6.39/Zend/zend_vm_execute.h:388:2
    #16 0xebe557 in zend_eval_stringl /home/hugh/php-5.6.39/Zend/zend_execute_API.c:1080:4
    #17 0xebfcd9 in zend_eval_stringl_ex /home/hugh/php-5.6.39/Zend/zend_execute_API.c:1127:11
    #18 0xebfcd9 in zend_eval_string_ex /home/hugh/php-5.6.39/Zend/zend_execute_API.c:1138
    #19 0x125a228 in do_cli /home/hugh/php-5.6.39/sapi/cli/php_cli.c:1038:8
    #20 0x12570a1 in main /home/hugh/php-5.6.39/sapi/cli/php_cli.c:1382:18
    #21 0x7f8fbd5ddb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #22 0x436129 in _start (/home/hugh/php-5.6.39/sapi/cli/php+0x436129)

0x60200000d7f2 is located 0 bytes to the right of 2-byte region [0x60200000d7f0,0x60200000d7f2)
allocated by thread T0 here:
    #0 0x4ebba5 in realloc (/home/hugh/php-5.6.39/sapi/cli/php+0x4ebba5)
    #1 0xe10a82 in __zend_realloc /home/hugh/php-5.6.39/Zend/zend_alloc.h:114:6
    #2 0xb46252 in zif_file_get_contents /home/hugh/php-5.6.39/ext/standard/file.c:561:13
    #3 0x11a27d8 in zend_do_fcall_common_helper_SPEC /home/hugh/php-5.6.39/Zend/zend_vm_execute.h:558:5

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/hugh/php-5.6.39/sapi/cli/php+0x4d67d0) in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c047fff9aa0: fa fa fd fa fa fa 00 00 fa fa 00 05 fa fa fd fa
  0x0c047fff9ab0: fa fa 00 00 fa fa 00 05 fa fa 06 fa fa fa 07 fa
  0x0c047fff9ac0: fa fa 07 fa fa fa 04 fa fa fa fd fa fa fa fd fa
  0x0c047fff9ad0: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa
  0x0c047fff9ae0: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fa
=>0x0c047fff9af0: fa fa fd fa fa fa 00 00 fa fa fd fd fa fa[02]fa
  0x0c047fff9b00: fa fa 02 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9b20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9b30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9b40: fa fa fa fa fa fa fa fa fa fa fa 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==16331==ABORTING



$ ~/php-7.0.33/sapi/cli/php -r 'var_dump(mb_ereg("   \xfd",""));'
=================================================================
==16351==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300001a3a0 at pc 0x0000004d8aa1 bp 0x7fffe4892ea0 sp 0x7fffe4892650
READ of size 6 at 0x60300001a3a0 thread T0
    #0 0x4d8aa0 in __asan_memcpy (/home/hugh/php-7.0.33/sapi/cli/php+0x4d8aa0)
    #1 0x85609b in onig_strcpy /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regparse.c:223:5
    #2 0x85609b in onig_node_str_cat /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regparse.c:1447
    #3 0x866ace in parse_exp /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regparse.c:5100:6
    #4 0x8647d5 in parse_branch /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regparse.c:5441:7
    #5 0x8616f2 in parse_subexp /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regparse.c:5478:7
    #6 0x8585a5 in parse_regexp /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regparse.c:5522:7
    #7 0x8585a5 in onig_parse_make_tree /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regparse.c:5549
    #8 0x7dd735 in onig_compile /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regcomp.c:5300:7
    #9 0x806029 in onig_new /home/hugh/php-7.0.33/ext/mbstring/oniguruma/regcomp.c:5545:7
    #10 0x97f337 in php_mbregex_compile_pattern /home/hugh/php-7.0.33/ext/mbstring/php_mbregex.c:456:19
    #11 0x979a7e in _php_mb_regex_ereg_exec /home/hugh/php-7.0.33/ext/mbstring/php_mbregex.c:727:7
    #12 0x12588f5 in ZEND_DO_ICALL_SPEC_HANDLER /home/hugh/php-7.0.33/Zend/zend_vm_execute.h:586:2
    #13 0x10da51d in execute_ex /home/hugh/php-7.0.33/Zend/zend_vm_execute.h:417:7
    #14 0x10db3f7 in zend_execute /home/hugh/php-7.0.33/Zend/zend_vm_execute.h:458:2
    #15 0xeefb24 in zend_eval_stringl /home/hugh/php-7.0.33/Zend/zend_execute_API.c:1137:4
    #16 0xef062a in zend_eval_stringl_ex /home/hugh/php-7.0.33/Zend/zend_execute_API.c:1178:11
    #17 0xef062a in zend_eval_string_ex /home/hugh/php-7.0.33/Zend/zend_execute_API.c:1189
    #18 0x1319021 in do_cli /home/hugh/php-7.0.33/sapi/cli/php_cli.c:1008:8
    #19 0x1315f95 in main /home/hugh/php-7.0.33/sapi/cli/php_cli.c:1347:18
    #20 0x7f3c84dc2b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #21 0x4383f9 in _start (/home/hugh/php-7.0.33/sapi/cli/php+0x4383f9)

0x60300001a3a0 is located 0 bytes to the right of 32-byte region [0x60300001a380,0x60300001a3a0)
allocated by thread T0 here:
    #0 0x4eda50 in malloc (/home/hugh/php-7.0.33/sapi/cli/php+0x4eda50)
    #1 0xe2abcc in __zend_malloc /home/hugh/php-7.0.33/Zend/zend_alloc.c:2882:14
    #2 0xdd36f7 in lex_scan /home/hugh/php-7.0.33/Zend/zend_language_scanner.l:2054:5
    #3 0xe3af46 in zendlex /home/hugh/php-7.0.33/Zend/zend_compile.c:1587:11
    #4 0xd9fa05 in zendparse /home/hugh/php-7.0.33/Zend/zend_language_parser.c:4225:16
    #5 0xdb677e in compile_string /home/hugh/php-7.0.33/Zend/zend_language_scanner.l:760:8
    #6 0xeef95f in zend_eval_stringl /home/hugh/php-7.0.33/Zend/zend_execute_API.c:1127:17
    #7 0xef062a in zend_eval_stringl_ex /home/hugh/php-7.0.33/Zend/zend_execute_API.c:1178:11
    #8 0xef062a in zend_eval_string_ex /home/hugh/php-7.0.33/Zend/zend_execute_API.c:1189

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/hugh/php-7.0.33/sapi/cli/php+0x4d8aa0) in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c067fffb420: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00
  0x0c067fffb430: 00 00 fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa
  0x0c067fffb440: 00 00 00 fa fa fa 00 00 00 00 fa fa 00 00 00 00
  0x0c067fffb450: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00
  0x0c067fffb460: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa
=>0x0c067fffb470: 00 00 00 00[fa]fa fd fd fd fd fa fa fa fa fa fa
  0x0c067fffb480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffb490: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffb4a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffb4b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffb4c0: fa fa fa fa fa fa fa fa fa fa fa 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==16351==ABORTING



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-12-29 22:19 UTC] hugh at allthethings dot co dot nz
-Summary: Buffer overflow on mb regex functions +Summary: Buffer overflow on mb regex functions - fetch_token
 [2018-12-29 22:19 UTC] hugh at allthethings dot co dot nz
updating summary
 [2018-12-30 03:54 UTC] stas@php.net
-Assigned To: +Assigned To: stas -CVE-ID: +CVE-ID: needed
 [2018-12-30 03:54 UTC] stas@php.net
Proposed fix in security repo as 0839641503bc381d64347081b4308dd7335a26b5 and in https://gist.github.com/smalyshev/4902bc13d34390d0068163d5d8fd64f7. Please verify.
 [2018-12-30 03:55 UTC] stas@php.net
-Operating System: Linux +Operating System: * -PHP Version: 7.1.25 +PHP Version: 5.6.39
 [2018-12-30 20:25 UTC] hugh at allthethings dot co dot nz
Verified on 7.1.25, 7.0.33, and 5.6.39.
 [2019-01-07 08:10 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=20407d06ca3cb5eeb10f876a812b40c381574bcc
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:10 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2019-01-07 08:19 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=deb06bbb9cbb31292fc219501614a8c3ff25bb11
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:19 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=20407d06ca3cb5eeb10f876a812b40c381574bcc
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=deb06bbb9cbb31292fc219501614a8c3ff25bb11
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=20407d06ca3cb5eeb10f876a812b40c381574bcc
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=deb06bbb9cbb31292fc219501614a8c3ff25bb11
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=20407d06ca3cb5eeb10f876a812b40c381574bcc
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:21 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=deb06bbb9cbb31292fc219501614a8c3ff25bb11
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-01-07 08:21 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=20407d06ca3cb5eeb10f876a812b40c381574bcc
Log: Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
 [2019-02-22 22:08 UTC] stas@php.net
-CVE-ID: needed +CVE-ID: 2019-9023
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 21:01:28 2024 UTC