php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #79037 global buffer-overflow in `mbfl_filt_conv_big5_wchar`
Submitted: 2019-12-26 21:22 UTC Modified: 2020-01-21 07:15 UTC
From: reza at iseclab dot org Assigned: stas (profile)
Status: Closed Package: mbstring related
PHP Version: 7.4Git-2019-12-26 (Git) OS: Ubuntu 16.04
Private report: No CVE-ID: 2020-7060
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: reza at iseclab dot org
New email:
PHP Version: OS:

 

 [2019-12-26 21:22 UTC] reza at iseclab dot org
Description:
------------
There is an Undefined Behaviour in libmbfl at `mbfl_filt_conv_big5_wchar` function which leads to a buffer overflow on `cp950_pua_tbl` global variable.

./php --version
PHP 7.4.2-dev (cli) (built: Dec 26 2019 15:32:36) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies


Compiled with:
CC=clang-6.0  CFLAGS="-fPIE -fsanitize=address,undefined -g" LDFLAGS="-pie" ./configure --enable-exif --enable-mbstring

Test script:
---------------
./php -r 'mb_decode_mimeheader(file_get_contents("php://stdin"));' < global-overflow-cp950_pua_tbl.poc

You can download the poc from this repository.

https://github.com/gaintcome/fuzz-php/blob/master/poc/mbstrings/global-overflow-cp950_pua_tbl.poc



Actual result:
--------------
php-src/ext/mbstring/libmbfl/filters/mbfilter_big5.c:212:11: runtime error: index 5 out of bounds for type 'unsigned short [5][4]'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior php-src/ext/mbstring/libmbfl/filters/mbfilter_big5.c:212:11 in 
=================================================================
==32013==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000004f80a4c at pc 0x00000126177b bp 0x7fffffff9540 sp 0x7fffffff9538
READ of size 2 at 0x000004f80a4c thread T0
    #0 0x126177a in mbfl_filt_conv_big5_wchar php-src/ext/mbstring/libmbfl/filters/mbfilter_big5.c:212:11
    #1 0x13b836f in mbfl_filter_output_pipe php-src/ext/mbstring/libmbfl/mbfl/mbfl_filter_output.c:41:9
    #2 0x12fa512 in mbfl_filt_conv_qprintdec php-src/ext/mbstring/libmbfl/filters/mbfilter_qprint.c:218:4
    #3 0x13a1155 in mime_header_decoder_collector php-src/ext/mbstring/libmbfl/mbfl/mbfilter.c:2285:4
    #4 0x13a33a3 in mbfl_mime_header_decode php-src/ext/mbstring/libmbfl/mbfl/mbfilter.c:2451:3
    #5 0x11de031 in zif_mb_decode_mimeheader php-src/ext/mbstring/mbstring.c:3735:8
    #6 0x39858b1 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER php-src/Zend/zend_vm_execute.h:1269:2
    #7 0x30cfe4e in execute_ex php-src/Zend/zend_vm_execute.h:53611:7
    #8 0x30d2f86 in zend_execute php-src/Zend/zend_vm_execute.h:57913:2
    #9 0x2a45235 in zend_eval_stringl php-src/Zend/zend_execute_API.c:1086:4
    #10 0x2a469f0 in zend_eval_stringl_ex php-src/Zend/zend_execute_API.c:1127:11
    #11 0x2a46bd0 in zend_eval_string_ex php-src/Zend/zend_execute_API.c:1138:9
    #12 0x3cbd3aa in do_cli php-src/sapi/cli/php_cli.c:992:8
    #13 0x3cb8471 in main php-src/sapi/cli/php_cli.c:1352:18
    #14 0x7ffff619882f in __libc_start_main /build/glibc-LK5gWL/glibc-2.23/csu/../csu/libc-start.c:291
    #15 0x441d28 in _start (php-src/sapi/cli/php+0x441d28)

0x000004f80a4c is located 4 bytes to the right of global variable 'cp950_pua_tbl' defined in 'php-src/ext/mbstring/libmbfl/filters/mbfilter_big5.c:137:23' (0x4f80a20) of size 40
SUMMARY: AddressSanitizer: global-buffer-overflow php-src/ext/mbstring/libmbfl/filters/mbfilter_big5.c:212:11 in mbfl_filt_conv_big5_wchar
Shadow bytes around the buggy address:
  0x0000809e80f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0000809e8140: 00 00 00 00 00 00 00 00 00[f9]f9 f9 f9 f9 f9 f9
  0x0000809e8150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000809e8190: 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
  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
==32013==ABORTING

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-12-28 12:03 UTC] cmb@php.net
-Status: Open +Status: Verified -Package: Unknown/Other Function +Package: mbstring related
 [2019-12-28 12:03 UTC] cmb@php.net
Thanks for reporting!

Possible fix including a test case:
<https://gist.github.com/cmb69/951f7404fda6d71400ac63dcbe3b1463>.
 [2019-12-30 04:50 UTC] reza at iseclab dot org
Thanks for the fix. I can confirm I don't see the issue after applying the patch.
 [2019-12-30 15:27 UTC] cmb@php.net
-Assigned To: +Assigned To: nikic
 [2019-12-30 15:27 UTC] cmb@php.net
Thanks for verifying!

@nikic, could you please have a look?
 [2019-12-30 15:44 UTC] nikic@php.net
This doesn't look right to me. The is_in_cp950_pua() check should be making sure that the table entry exists. Why doesn't it?
 [2019-12-30 15:52 UTC] nikic@php.net
Okay, I see the issue. The is_in_cp950_pua() code does a check for c > 0x39, while the table entry starts at 0x40 ... which would be fine if this were decimals, but this is hex, so there's still 0x3a..0x3f between there!
 [2019-12-30 15:59 UTC] nikic@php.net
Here is an alternative patch and reduced test-case: https://gist.github.com/nikic/f52bd4b3c9ab12e5cee1eb89ae13f351
 [2019-12-30 17:49 UTC] cmb@php.net
Ah, much better than my patch.  Can we assign to Stas?
 [2019-12-30 19:04 UTC] nikic@php.net
-Status: Verified +Status: Assigned -Assigned To: nikic +Assigned To: stas
 [2020-01-05 01:11 UTC] reza at iseclab dot org
Do you assign a CVE to this?
 [2020-01-21 05:30 UTC] stas@php.net
-CVE-ID: +CVE-ID: 2020-7060
 [2020-01-21 07:16 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2bcbc95f033c31b00595ed39f79c3a99b4ed0501
Log: Fix bug #79037 (global buffer-overflow in `mbfl_filt_conv_big5_wchar`)
 [2020-01-21 07:16 UTC] stas@php.net
-Status: Assigned +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Oct 09 06:01:26 2024 UTC