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
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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