php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73268 Out of Bounds access violation in mbfl_memory_device_output
Submitted: 2016-10-08 07:49 UTC Modified: 2016-11-26 22:56 UTC
From: nguyenluan dot vnn at gmail dot com Assigned: hirokawa (profile)
Status: Duplicate Package: mbstring related
PHP Version: 5.6.26 OS:
Private report: No CVE-ID: None
 [2016-10-08 07:49 UTC] nguyenluan dot vnn at gmail dot com
Description:
------------
Function mbfl_memory_device_output causes PHP 5.6.24 to crash when access an out of boundary address.

int
mbfl_memory_device_output(int c, void *data)
{
	mbfl_memory_device *device = (mbfl_memory_device *)data;

	if (device->pos >= device->length) {
		/* reallocate buffer */
		int newlen;
		unsigned char *tmp;

		newlen = device->length + device->allocsz;
		tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen*sizeof(unsigned char));
		if (tmp == NULL) {
			return -1;
		}
		device->length = newlen;
		device->buffer = tmp;
	}

	device->buffer[device->pos++] = (unsigned char)c;  // out of boundary access here
	return c;
}

device->pos is declared as type INT.

As you can see in the output of GDB, when value of device->pos is over INTMAX (0x80000001), a sign extension operation is done to assign it value 0xffffffff80000001. Then the access to device->buffer[device->pos] will be an out of boundary access violation and causes PHP to crash.

Test script:
---------------
<?php
    ini_set('memory_limit', -1);

    $str = str_repeat("Prüfung Prüfung", 0xffffffff/50);
    $str1 = mb_encode_mimeheader($str, "ISO-8859-1", "Q");
?>

Expected result:
----------------
No crash

Actual result:
--------------
gdb-peda$ r ../test/test_mime2.php 
Starting program: /home/user/Desktop/php-5.6.26/sapi/cli/php ../test/test_mime2.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.

 [----------------------------------registers-----------------------------------]
RAX: 0x7ffe16123070 
RBX: 0xa93d73 (<execute_ex>:	push   rbp)
RCX: 0x80000001 
RDX: 0x50 ('P')
RSI: 0x7ffe96123070 ("=?ISO-8859-1?Q?Pr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr?=\r\n =?ISO-8859-1?Q?=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung?=\r\n =?ISO-8859-1?Q?=20Pr=FCfungPr=FCfung=20Pr=FCfu"...)
RDI: 0x50 ('P')
RBP: 0x7fffffffa540 --> 0x7fffffffa570 --> 0x7fffffffa590 --> 0x7fffffffa5c0 --> 0x7fffffffa5e0 --> 0x7fffffffa610 (--> ...)
RSP: 0x7fffffffa510 --> 0x7ffff7fbed80 --> 0x7ffe96123070 ("=?ISO-8859-1?Q?Pr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr?=\r\n =?ISO-8859-1?Q?=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung?=\r\n =?ISO-8859-1?Q?=20Pr=FCfungPr=FCfung=20Pr=FCfu"...)
RIP: 0x756dae (<mbfl_memory_device_output+162>:	mov    BYTE PTR [rax],dl)
R8 : 0x280 
R9 : 0x0 
R10: 0x1 
R11: 0x7ffff44b6730 --> 0xfffda400fffda12f 
R12: 0x439790 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1b0 --> 0x2 
R14: 0x0 
R15: 0x0
EFLAGS: 0x10203 (CARRY parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x756da6 <mbfl_memory_device_output+154>:	cdqe   
   0x756da8 <mbfl_memory_device_output+156>:	add    rax,rsi
   0x756dab <mbfl_memory_device_output+159>:	mov    edx,DWORD PTR [rbp-0x24]
=> 0x756dae <mbfl_memory_device_output+162>:	mov    BYTE PTR [rax],dl
   0x756db0 <mbfl_memory_device_output+164>:	mov    eax,DWORD PTR [rbp-0x24]
   0x756db3 <mbfl_memory_device_output+167>:	leave  
   0x756db4 <mbfl_memory_device_output+168>:	ret    
   0x756db5 <mbfl_memory_device_output2>:	push   rbp
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa510 --> 0x7ffff7fbed80 --> 0x7ffe96123070 ("=?ISO-8859-1?Q?Pr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr?=\r\n =?ISO-8859-1?Q?=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung?=\r\n =?ISO-8859-1?Q?=20Pr=FCfungPr=FCfung=20Pr=FCfu"...)
0008| 0x7fffffffa518 --> 0x5000741998 
0016| 0x7fffffffa520 --> 0x7ffff7fbfdc8 --> 0x7561f7 (<mbfl_filt_conv_common_ctor>:	push   rbp)
0024| 0x7fffffffa528 --> 0x5000a10bc9 
0032| 0x7fffffffa530 --> 0x7ffff7fbed80 --> 0x7ffe96123070 ("=?ISO-8859-1?Q?Pr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr?=\r\n =?ISO-8859-1?Q?=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung?=\r\n =?ISO-8859-1?Q?=20Pr=FCfungPr=FCfung=20Pr=FCfu"...)
0040| 0x7fffffffa538 --> 0x6700000000 ('')
0048| 0x7fffffffa540 --> 0x7fffffffa570 --> 0x7fffffffa590 --> 0x7fffffffa5c0 --> 0x7fffffffa5e0 --> 0x7fffffffa610 (--> ...)
0056| 0x7fffffffa548 --> 0x741998 (<mbfl_filt_conv_qprintenc+790>:	test   eax,eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000000756dae in mbfl_memory_device_output (c=0x50, data=0x7ffff7fbed80) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c:157
157		device->buffer[device->pos++] = (unsigned char)c;

gdb-peda$ p device->pos
$5 = 0x80000001

gdb-peda$ p device->buffer
$6 = (unsigned char *) 0x7ffe96123070 "=?ISO-8859-1?Q?Pr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr?=\r\n =?ISO-8859-1?Q?=FCfungPr=FCfung=20Pr=FCfungPr=FCfung=20Pr=FCfungPr=FCfung?=\r\n =?ISO-8859-1?Q?=20Pr=FCfungPr=FCfung=20Pr=FCfu"...

gdb-peda$ p device->buffer[device->pos]
Cannot access memory at address 0x7ffe16123071

gdb-peda$ p 0x7ffe16123071 - 0x7ffe96123070
$7 = 0xffffffff80000001

gdb-peda$ p 0x7ffe16123071 - 0x7ffe96123070 == device->pos
$8 = 0x1

gdb-peda$ bt
#0  0x0000000000756dae in mbfl_memory_device_output (c=0x50, data=0x7ffff7fbed80) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c:157
#1  0x0000000000741998 in mbfl_filt_conv_qprintenc (c=0x0, filter=0x7ffff7fbfdc8) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/filters/mbfilter_qprint.c:133
#2  0x00000000007419f6 in mbfl_filt_conv_qprintenc_flush (filter=0x7ffff7fbfdc8) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/filters/mbfilter_qprint.c:147
#3  0x00000000007530d5 in mime_header_encoder_block_collector (c=0x50, data=0x7ffff7fbed50) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfilter.c:2102
#4  0x0000000000755883 in mbfl_filt_conv_pass (c=0x50, filter=0x7ffff7fbf110) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfilter_pass.c:63
#5  0x00000000007532c5 in mime_header_encoder_collector (c=0x50, data=0x7ffff7fbed50) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfilter.c:2158
#6  0x000000000074da7c in mbfl_filt_conv_utf8_wchar (c=0x50, filter=0x7ffff7fbf1d8) at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/filters/mbfilter_utf8.c:118
#7  0x0000000000753c84 in mbfl_mime_header_encode (string=0x7fffffffa740, result=0x7fffffffa760, outcode=mbfl_no_encoding_8859_1, encoding=mbfl_no_encoding_qprint, linefeed=0x1002506 "", indent=0x0)
    at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfilter.c:2377
#8  0x000000000075fbd8 in zif_mb_encode_mimeheader (ht=0x3, return_value=0x7ffff7fbecd8, return_value_ptr=0x7ffff7f86208, this_ptr=0x0, return_value_used=0x1) at /home/user/Desktop/php-5.6.26/ext/mbstring/mbstring.c:3381
#9  0x0000000000a9476b in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7f862a0) at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:558
#10 0x0000000000a9a296 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x7ffff7f862a0) at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:2602
#11 0x0000000000a93dd3 in execute_ex (execute_data=0x7ffff7f862a0) at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:363
#12 0x0000000000a93e5a in zend_execute (op_array=0x7ffff7fbe430) at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:388
#13 0x0000000000a4c498 in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /home/user/Desktop/php-5.6.26/Zend/zend.c:1341
#14 0x00000000009ad757 in php_execute_script (primary_file=0x7fffffffcd80) at /home/user/Desktop/php-5.6.26/main/main.c:2613
#15 0x0000000000b09556 in do_cli (argc=0x2, argv=0x13f5560) at /home/user/Desktop/php-5.6.26/sapi/cli/php_cli.c:994
#16 0x0000000000b0a8b9 in main (argc=0x2, argv=0x13f5560) at /home/user/Desktop/php-5.6.26/sapi/cli/php_cli.c:1378
#17 0x00007ffff4342830 in __libc_start_main (main=0xb0a09c <main>, argc=0x2, argv=0x7fffffffe1b8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe1a8) at ../csu/libc-start.c:291
#18 0x00000000004397b9 in _start ()


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-09 04:07 UTC] nguyenluan dot vnn at gmail dot com
2 other functions mbfl_memory_device_output2 and mbfl_memory_device_output4 also have the same problem.

PHP code to trigger crash in mbfl_memory_device_output4:

<?php
    ini_set('memory_limit', -1);
    $str = str_repeat('ボ', 0x7fffffff/3);
    $str1 = mb_convert_kana($str, "KVC");
?>

gdb-peda$ r ../test/string/test.php 
Starting program: /home/user/Desktop/php-5.6.26/sapi/cli/php ../test/string/test.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.

 [----------------------------------registers-----------------------------------]
RAX: 0x7ffe6d130070 
RBX: 0xa93d73 (<execute_ex>:	push   rbp)
RCX: 0x80000001 
RDX: 0x0 
RSI: 0x7ffeed130070 --> 0x83e39c83e39c83e3 
RDI: 0x0 
RBP: 0x7fffffffa5f0 --> 0x7fffffffa610 --> 0x7fffffffa6a0 --> 0x7fffffffa770 --> 0x7fffffffa7e0 --> 0x7fffffffa820 (--> ...)
RSP: 0x7fffffffa5c0 --> 0x7fffffffa680 --> 0x7ffeed130070 --> 0x83e39c83e39c83e3 
RIP: 0x756f7b (<mbfl_memory_device_output4+245>:	mov    BYTE PTR [rax],dl)
R8 : 0x748c39 (<mbfl_filt_tl_jisx0201_jisx0208>:	push   rbp)
R9 : 0x749653 (<mbfl_filt_tl_jisx0201_jisx0208_flush>:	push   rbp)
R10: 0x22 ('"')
R11: 0x246 
R12: 0x439790 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1a0 --> 0x2 
R14: 0x0 
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x756f72 <mbfl_memory_device_output4+236>:	add    rax,rsi
   0x756f75 <mbfl_memory_device_output4+239>:	mov    edx,DWORD PTR [rbp-0x24]
   0x756f78 <mbfl_memory_device_output4+242>:	sar    edx,0x8
=> 0x756f7b <mbfl_memory_device_output4+245>:	mov    BYTE PTR [rax],dl
   0x756f7d <mbfl_memory_device_output4+247>:	mov    rax,QWORD PTR [rbp-0x10]
   0x756f81 <mbfl_memory_device_output4+251>:	mov    rsi,QWORD PTR [rax]
   0x756f84 <mbfl_memory_device_output4+254>:	mov    rax,QWORD PTR [rbp-0x10]
   0x756f88 <mbfl_memory_device_output4+258>:	mov    eax,DWORD PTR [rax+0xc]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa5c0 --> 0x7fffffffa680 --> 0x7ffeed130070 --> 0x83e39c83e39c83e3 
0008| 0x7fffffffa5c8 --> 0x749744 (<mbfl_filt_tl_jisx0201_jisx0208_flush+241>:	)
0016| 0x7fffffffa5d0 --> 0x30dcf7fbeed8 
0024| 0x7fffffffa5d8 --> 0x7ffff7fbeed8 --> 0x748c13 (<mbfl_filt_tl_jisx0201_jisx0208_init>:	push   rbp)
0032| 0x7fffffffa5e0 --> 0x7fffffffa680 --> 0x7ffeed130070 --> 0x83e39c83e39c83e3 
0040| 0x7fffffffa5e8 --> 0x10900 
0048| 0x7fffffffa5f0 --> 0x7fffffffa610 --> 0x7fffffffa6a0 --> 0x7fffffffa770 --> 0x7fffffffa7e0 --> 0x7fffffffa820 (--> ...)
0056| 0x7fffffffa5f8 --> 0x756cac (<mbfl_memory_device_result+63>:	mov    rax,QWORD PTR [rbp-0x8])
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000000756f7b in mbfl_memory_device_output4 (c=0x0, data=0x7fffffffa680)
    at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c:207
207		device->buffer[device->pos++] = (unsigned char)((c >> 8) & 0xff);

gdb-peda$ bt
#0  0x0000000000756f7b in mbfl_memory_device_output4 (c=0x0, 
    data=0x7fffffffa680)
    at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c:207
#1  0x0000000000756cac in mbfl_memory_device_result (device=0x7fffffffa680, 
    result=0x7fffffffa750)
    at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c:122
#2  0x0000000000752f92 in mbfl_ja_jp_hantozen (string=0x7fffffffa730, 
    result=0x7fffffffa750, mode=0x10900)
    at /home/user/Desktop/php-5.6.26/ext/mbstring/libmbfl/mbfl/mbfilter.c:2045
#3  0x0000000000760031 in zif_mb_convert_kana (ht=0x2, 
    return_value=0x7ffff7fbd610, return_value_ptr=0x7ffff7f86218, 
    this_ptr=0x0, return_value_used=0x1)
    at /home/user/Desktop/php-5.6.26/ext/mbstring/mbstring.c:3508
#4  0x0000000000a9476b in zend_do_fcall_common_helper_SPEC (
    execute_data=0x7ffff7f862b0)
    at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:558
#5  0x0000000000a9a296 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (
    execute_data=0x7ffff7f862b0)
    at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:2602
#6  0x0000000000a93dd3 in execute_ex (execute_data=0x7ffff7f862b0)
    at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:363
#7  0x0000000000a93e5a in zend_execute (op_array=0x7ffff7fbe4e0)
    at /home/user/Desktop/php-5.6.26/Zend/zend_vm_execute.h:388
#8  0x0000000000a4c498 in zend_execute_scripts (type=0x8, retval=0x0, 
    file_count=0x3) at /home/user/Desktop/php-5.6.26/Zend/zend.c:1341
#9  0x00000000009ad757 in php_execute_script (primary_file=0x7fffffffcd70)
    at /home/user/Desktop/php-5.6.26/main/main.c:2613
#10 0x0000000000b09556 in do_cli (argc=0x2, argv=0x13f5560)
    at /home/user/Desktop/php-5.6.26/sapi/cli/php_cli.c:994
#11 0x0000000000b0a8b9 in main (argc=0x2, argv=0x13f5560)
    at /home/user/Desktop/php-5.6.26/sapi/cli/php_cli.c:1378
#12 0x00007ffff4342830 in __libc_start_main (main=0xb0a09c <main>, argc=0x2, 
    argv=0x7fffffffe1a8, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe198)
    at ../csu/libc-start.c:291
#13 0x00000000004397b9 in _start ()
 [2016-10-11 20:03 UTC] stas@php.net
-Assigned To: +Assigned To: hirokawa
 [2016-10-11 20:03 UTC] stas@php.net
Looks like issue in libmbfl
 [2016-11-26 22:56 UTC] stas@php.net
-Status: Assigned +Status: Duplicate -Type: Security +Type: Bug
 [2016-11-26 22:56 UTC] stas@php.net
Seems to be the same as bug #73505
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 02 18:01:29 2024 UTC