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
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: nguyenluan dot vnn at gmail dot com
New email:
PHP Version: OS:

 

 [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 Dec 21 15:01:29 2024 UTC