php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73378 crash in get_icu_value_internal function
Submitted: 2016-10-23 10:53 UTC Modified: 2017-10-15 21:35 UTC
From: nguyenluan dot vnn at gmail dot com Assigned: stas (profile)
Status: Closed Package: intl (PECL)
PHP Version: 7.0.13 OS:
Private report: No CVE-ID: None
 [2016-10-23 10:53 UTC] nguyenluan dot vnn at gmail dot com
Description:
------------
In function get_icu_value_internal:

static zend_string* get_icu_value_internal( const char* loc_name , char* tag_name, int* result , int fromParseLocale)
{
	zend_string*	tag_value	= NULL;

        ...
        ...
		if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){
			buflen = uloc_getScript ( mod_loc_name , tag_value->val , tag_value_len , &status);
		}
		if( strcmp(tag_name , LOC_LANG_TAG )==0 ){
			buflen = uloc_getLanguage ( mod_loc_name , tag_value->val , tag_value_len , &status);  // (1) crash here
		}
		if( strcmp(tag_name , LOC_REGION_TAG)==0 ){
			buflen = uloc_getCountry ( mod_loc_name , tag_value->val , tag_value_len , &status);  // (2) crash here
		}
		if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){
			buflen = uloc_getVariant ( mod_loc_name , tag_value->val , tag_value_len , &status);  // (3) crash here
		}
		if( strcmp(tag_name , LOC_CANONICALIZE_TAG)==0 ){
			buflen = uloc_canonicalize ( mod_loc_name , tag_value->val , tag_value_len , &status);  // (4) crash here
		}

        ...
        ...
}

When passing locale string larger than 2Gb, this function may cause PHP 7 to crash at 4 points as above source code comments. Please refer to the test script and GDB output.

Test script:
---------------
    ini_set('memory_limit', -1);
    
    $str = str_repeat('a', 0x8fffffff);
    $str1 = "sl-Latn-IT-$str";
    $arr = locale_parse($str1);
?>

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

Actual result:
--------------
gdb-peda$ r ../test/string/test.php 
Starting program: /home/user/Desktop/php-7.0.12/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: 0x41 ('A')
RBX: 0x80000000 
RCX: 0x200 
RDX: 0x0 
RSI: 0x2d ('-')
RDI: 0x61 ('a')
RBP: 0x7ffebb20000b ('a' <repeats 200 times>...)
RSP: 0x7fffffffa500 --> 0xffffffffffffffff 
RIP: 0x7ffff43508f9 (mov    BYTE PTR [r12],al)
R8 : 0x0 
R9 : 0x0 
R10: 0x389 
R11: 0x7ffff4351d50 (<uloc_getVariant_55>:	push   r14)
R12: 0x80006bc64798 
R13: 0x200 
R14: 0x7fffebc14030 --> 0x7fffebc821c0 --> 0xad8472 (<ZEND_DO_ICALL_SPEC_HANDLER>:	push   rbp)
R15: 0x7fffebc821c0 --> 0xad8472 (<ZEND_DO_ICALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x10216 (carry PARITY ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x7ffff43508f0:	call   0x7ffff436b2c0 <uprv_toupper_55>
   0x7ffff43508f5:	cmp    al,0x2d
   0x7ffff43508f7:	je     0x7ffff4350910
=> 0x7ffff43508f9:	mov    BYTE PTR [r12],al
   0x7ffff43508fd:	jmp    0x7ffff43508d0
   0x7ffff43508ff:	nop
   0x7ffff4350900:	mov    BYTE PTR [r12],0x5f
   0x7ffff4350905:	jmp    0x7ffff4350858
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa500 --> 0xffffffffffffffff 
0008| 0x7fffffffa508 --> 0x7ffe3b200000 ("sl-Latn-IT-", 'a' <repeats 189 times>...)
0016| 0x7fffffffa510 --> 0x7fffffffa664 --> 0x20000000000 
0024| 0x7fffffffa518 --> 0x7ffe3b200000 ("sl-Latn-IT-", 'a' <repeats 189 times>...)
0032| 0x7fffffffa520 --> 0x7fffffffa664 --> 0x20000000000 
0040| 0x7fffffffa528 --> 0x7fffebc64798 ('A' <repeats 200 times>...)
0048| 0x7fffffffa530 --> 0x200 
0056| 0x7fffffffa538 --> 0x7ffff4351f21 (<uloc_getVariant_55+465>:	mov    edx,eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00007ffff43508f9 in ?? () from /usr/lib/x86_64-linux-gnu/libicuuc.so.55

gdb-peda$ bt
#0  0x00007ffff43508f9 in ?? () from /usr/lib/x86_64-linux-gnu/libicuuc.so.55
#1  0x00007ffff4351f21 in uloc_getVariant_55 ()
   from /usr/lib/x86_64-linux-gnu/libicuuc.so.55
#2  0x00000000006edd0c in get_icu_value_internal (
    loc_name=0x7ffecb400018 "sl-Latn-IT-", 'a' <repeats 189 times>..., 
    tag_name=0xf78b61 "variant", result=0x7fffffffa6cc, fromParseLocale=0x1)
    at /home/user/Desktop/php-7.0.12/ext/intl/locale/locale_methods.c:329
#3  0x00000000006ef61b in add_array_entry (
    loc_name=0x7ffecb400018 "sl-Latn-IT-", 'a' <repeats 189 times>..., 
    hash_arr=0x7fffebc14110, key_name=0xf78b61 "variant")
    at /home/user/Desktop/php-7.0.12/ext/intl/locale/locale_methods.c:1057
#4  0x00000000006ef9c8 in zif_locale_parse (execute_data=0x7fffebc14150, 
    return_value=0x7fffebc14110)
    at /home/user/Desktop/php-7.0.12/ext/intl/locale/locale_methods.c:1138
#5  0x0000000000ad8506 in ZEND_DO_ICALL_SPEC_HANDLER ()
    at /home/user/Desktop/php-7.0.12/Zend/zend_vm_execute.h:586
#6  0x0000000000ad7f32 in execute_ex (ex=0x7fffebc14030)
    at /home/user/Desktop/php-7.0.12/Zend/zend_vm_execute.h:414
#7  0x0000000000ad8043 in zend_execute (op_array=0x7fffebc81000, 
    return_value=0x0)
    at /home/user/Desktop/php-7.0.12/Zend/zend_vm_execute.h:458
#8  0x0000000000a78cfc in zend_execute_scripts (type=0x8, retval=0x0, 
    file_count=0x3) at /home/user/Desktop/php-7.0.12/Zend/zend.c:1427
#9  0x00000000009e11d5 in php_execute_script (primary_file=0x7fffffffce20)
    at /home/user/Desktop/php-7.0.12/main/main.c:2494
#10 0x0000000000b412f8 in do_cli (argc=0x2, argv=0x14a6630)
    at /home/user/Desktop/php-7.0.12/sapi/cli/php_cli.c:974
#11 0x0000000000b424c6 in main (argc=0x2, argv=0x14a6630)
    at /home/user/Desktop/php-7.0.12/sapi/cli/php_cli.c:1344
#12 0x00007ffff38b3830 in __libc_start_main (main=0xb41cbb <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 0x00000000004475a9 in _start ()


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-11-04 03:13 UTC] stas@php.net
-PHP Version: 7.0.12 +PHP Version: 5.6.27
 [2016-11-04 06:01 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2016-11-04 06:01 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.
 [2016-11-11 12:46 UTC] nguyenluan dot vnn at gmail dot com
-Status: Closed +Status: Assigned
 [2016-11-11 12:46 UTC] nguyenluan dot vnn at gmail dot com
It still crashes in version 7.0.13. Please check again.
 [2016-11-11 12:47 UTC] nguyenluan dot vnn at gmail dot com
-Status: Assigned +Status: Open -PHP Version: 5.6.27 +PHP Version: 7.0.13
 [2016-11-11 12:47 UTC] nguyenluan dot vnn at gmail dot com
Open again.
 [2016-11-14 11:46 UTC] nguyenluan dot vnn at gmail dot com
-Status: Open +Status: Closed
 [2016-11-14 11:46 UTC] nguyenluan dot vnn at gmail dot com
Fixed in PHP 7.1.0 RC6. Please close.

Thanks.
 [2017-10-15 21:35 UTC] stas@php.net
-Type: Security +Type: Bug
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Oct 21 16:01:24 2020 UTC