php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73382 Invalid memory access in zend_strtod() function
Submitted: 2016-10-24 16:01 UTC Modified: 2017-02-13 01:00 UTC
From: nguyenluan dot vnn at gmail dot com Assigned: stas (profile)
Status: Closed Package: Unknown/Other Function
PHP Version: 7.0.13 OS:
Private report: No CVE-ID: None
 [2016-10-24 16:01 UTC] nguyenluan dot vnn at gmail dot com
Description:
------------
In zend_strtod() defines "tens" as:

tens[] = {
		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
		1e20, 1e21, 1e22
#ifdef VAX
		, 1e23, 1e24
#endif
		};

Then in line 2811, an access using index variable i:
    
    dval(&rv) *= tens[i];  // (1) invalid access here

If the input number is too long that make i larger enough then there will be an invalid access to "tens" array and causes PHP 7 to crash. Please refer to the test script and GDB output.

Test script:
---------------
<?php
    ini_set('memory_limit', -1);
    
    $str = '1.'.str_repeat('1', 0x8fffffff);
    $fmt = numfmt_create("de_DE", NumberFormatter::DECIMAL);
    
    $str1 = numfmt_format($fmt, $str);
?>

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".

 [----------------------------------registers-----------------------------------]
RAX: 0x7000000f 
RBX: 0x0 
RCX: 0x7fffebc141b0 --> 0x7ffecb400000 --> 0x600000002 
RDX: 0xc71c71c6 
RSI: 0x7fffffffa578 --> 0x7ffecb400019 (".", '1' <repeats 199 times>...)
RDI: 0x7ffecb400018 ("1.", '1' <repeats 198 times>...)
RBP: 0x7fffffffa520 --> 0x7fffffffa5a0 --> 0x7fffffffa5e0 --> 0x7fffffffa620 --> 0x7fffffffa670 --> 0x7fffffffa740 (--> ...)
RSP: 0x7fffffffa3d0 --> 0x7fffffffa578 --> 0x7ffecb400019 (".", '1' <repeats 199 times>...)
RIP: 0xaaa145 (<zend_strtod+2456>:	movsd  xmm1,QWORD PTR [rbp-0x20])
R8 : 0x1 
R9 : 0x0 
R10: 0x2 
R11: 0x7ffff3a1a548 --> 0xfff1ddc8fff1ddb8 
R12: 0x447580 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1a0 --> 0x2 
R14: 0x7fffebc14030 --> 0x7fffebc82240 --> 0xad8472 (<ZEND_DO_ICALL_SPEC_HANDLER>:	push   rbp)
R15: 0x7fffebc82240 --> 0xad8472 (<ZEND_DO_ICALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x293 (CARRY parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0xaaa133 <zend_strtod+2438>:	jl     0xaaa1d8 <zend_strtod+2603>
   0xaaa139 <zend_strtod+2444>:	mov    eax,DWORD PTR [rbp-0x108]
   0xaaa13f <zend_strtod+2450>:	sub    DWORD PTR [rbp-0x114],eax
=> 0xaaa145 <zend_strtod+2456>:	movsd  xmm1,QWORD PTR [rbp-0x20]
   0xaaa14a <zend_strtod+2461>:	mov    eax,DWORD PTR [rbp-0x108]
   0xaaa150 <zend_strtod+2467>:	cdqe   
   0xaaa152 <zend_strtod+2469>:	lea    rdx,[rax*8+0x0]
   0xaaa15a <zend_strtod+2477>:	
    lea    rax,[rip+0x6553bf]        # 0x10ff520 <tens>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa3d0 --> 0x7fffffffa578 --> 0x7ffecb400019 (".", '1' <repeats 199 times>...)
0008| 0x7fffffffa3d8 --> 0x7ffecb400018 ("1.", '1' <repeats 198 times>...)
0016| 0x7fffffffa3e0 --> 0x16a1188 --> 0x7ffff4649c80 --> 0x7ffff43619d0 (<_ZN6icu_5513UnicodeStringD2Ev>:	)
0024| 0x7fffffffa3e8 --> 0x7fffffffa6b8 --> 0x7fffebc141a0 --> 0x7fffebc6c170 --> 0x800000002 
0032| 0x7fffffffa3f0 --> 0x15e8990 --> 0x7fffffffd901 --> 0xc000000000016973 
0040| 0x7fffffffa3f8 --> 0x16a11b0 --> 0x7ffff4649378 --> 0x7ffff43538e0 (<_ZN6icu_556LocaleD2Ev>:	)
0048| 0x7fffffffa400 --> 0x169bea0 --> 0x7ffff4aa7b18 --> 0x7ffff472ce80 (<_ZN6icu_5520DecimalFormatSymbolsD2Ev>:	)
0056| 0x7fffffffa408 --> 0xfffffff200000000 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 2, zend_strtod (
    s00=0x7ffecb400018 "1.", '1' <repeats 198 times>..., se=0x7fffffffa578)
    at /home/user/Desktop/php-7.0.12/Zend/zend_strtod.c:2811
2811					dval(&rv) *= tens[i];

gdb-peda$ p i
$17 = 0x7000000f

gdb-peda$ p tens[i]
Cannot access memory at address 0x3810ff598  // (2) invalid access

gdb-peda$ c
Continuing.

Program received signal SIGSEGV, Segmentation fault.

 [----------------------------------registers-----------------------------------]
RAX: 0x10ff520 --> 0x3ff0000000000000 
RBX: 0x0 
RCX: 0x7fffebc141b0 --> 0x7ffecb400000 --> 0x600000002 
RDX: 0x380000078 
RSI: 0x7fffffffa578 --> 0x7ffecb400019 (".", '1' <repeats 199 times>...)
RDI: 0x7ffecb400018 ("1.", '1' <repeats 198 times>...)
RBP: 0x7fffffffa520 --> 0x7fffffffa5a0 --> 0x7fffffffa5e0 --> 0x7fffffffa620 --> 0x7fffffffa670 --> 0x7fffffffa740 (--> ...)
RSP: 0x7fffffffa3d0 --> 0x7fffffffa578 --> 0x7ffecb400019 (".", '1' <repeats 199 times>...)
RIP: 0xaaa161 (<zend_strtod+2484>:	movsd  xmm0,QWORD PTR [rdx+rax*1])
R8 : 0x1 
R9 : 0x0 
R10: 0x2 
R11: 0x7ffff3a1a548 --> 0xfff1ddc8fff1ddb8 
R12: 0x447580 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1a0 --> 0x2 
R14: 0x7fffebc14030 --> 0x7fffebc82240 --> 0xad8472 (<ZEND_DO_ICALL_SPEC_HANDLER>:	push   rbp)
R15: 0x7fffebc82240 --> 0xad8472 (<ZEND_DO_ICALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x10293 (CARRY parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0xaaa150 <zend_strtod+2467>:	cdqe   
   0xaaa152 <zend_strtod+2469>:	lea    rdx,[rax*8+0x0]
   0xaaa15a <zend_strtod+2477>:	
    lea    rax,[rip+0x6553bf]        # 0x10ff520 <tens>
=> 0xaaa161 <zend_strtod+2484>:	movsd  xmm0,QWORD PTR [rdx+rax*1]
   0xaaa166 <zend_strtod+2489>:	mulsd  xmm0,xmm1
   0xaaa16a <zend_strtod+2493>:	movsd  QWORD PTR [rbp-0x20],xmm0
   0xaaa16f <zend_strtod+2498>:	movsd  xmm1,QWORD PTR [rbp-0x20]
   0xaaa174 <zend_strtod+2503>:	mov    eax,DWORD PTR [rbp-0x114]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa3d0 --> 0x7fffffffa578 --> 0x7ffecb400019 (".", '1' <repeats 199 times>...)
0008| 0x7fffffffa3d8 --> 0x7ffecb400018 ("1.", '1' <repeats 198 times>...)
0016| 0x7fffffffa3e0 --> 0x16a1188 --> 0x7ffff4649c80 --> 0x7ffff43619d0 (<_ZN6icu_5513UnicodeStringD2Ev>:	)
0024| 0x7fffffffa3e8 --> 0x7fffffffa6b8 --> 0x7fffebc141a0 --> 0x7fffebc6c170 --> 0x800000002 
0032| 0x7fffffffa3f0 --> 0x15e8990 --> 0x7fffffffd901 --> 0xc000000000016973 
0040| 0x7fffffffa3f8 --> 0x16a11b0 --> 0x7ffff4649378 --> 0x7ffff43538e0 (<_ZN6icu_556LocaleD2Ev>:	)
0048| 0x7fffffffa400 --> 0x169bea0 --> 0x7ffff4aa7b18 --> 0x7ffff472ce80 (<_ZN6icu_5520DecimalFormatSymbolsD2Ev>:	)
0056| 0x7fffffffa408 --> 0xfffffff200000000 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000000aaa161 in zend_strtod (
    s00=0x7ffecb400018 "1.", '1' <repeats 198 times>..., se=0x7fffffffa578)
    at /home/user/Desktop/php-7.0.12/Zend/zend_strtod.c:2811
2811					dval(&rv) *= tens[i];

gdb-peda$ bt
#0  0x0000000000aaa161 in zend_strtod (
    s00=0x7ffecb400018 "1.", '1' <repeats 198 times>..., se=0x7fffffffa578)
    at /home/user/Desktop/php-7.0.12/Zend/zend_strtod.c:2811
#1  0x0000000000a739b6 in _is_numeric_string_ex (
    str=0x7ffecb400018 "1.", '1' <repeats 198 times>..., length=0x90000001, 
    lval=0x7fffebc141b0, dval=0x7fffebc141b0, allow_errors=0x1, oflow_info=0x0)
    at /home/user/Desktop/php-7.0.12/Zend/zend_operators.c:2831
#2  0x0000000000a66b07 in is_numeric_string_ex (
    str=0x7ffecb400018 "1.", '1' <repeats 198 times>..., length=0x90000001, 
    lval=0x7fffebc141b0, dval=0x7fffebc141b0, allow_errors=0x1, oflow_info=0x0)
    at /home/user/Desktop/php-7.0.12/Zend/zend_operators.h:135
#3  0x0000000000a66b49 in is_numeric_string (
    str=0x7ffecb400018 "1.", '1' <repeats 198 times>..., length=0x90000001, 
    lval=0x7fffebc141b0, dval=0x7fffebc141b0, allow_errors=0x1)
    at /home/user/Desktop/php-7.0.12/Zend/zend_operators.h:139
#4  0x0000000000a67120 in convert_scalar_to_number (op=0x7fffebc141b0)
    at /home/user/Desktop/php-7.0.12/Zend/zend_operators.c:162
#5  0x00000000006eaab3 in zif_numfmt_format (execute_data=0x7fffebc14140, 
    return_value=0x7fffebc14120)
    at /home/user/Desktop/php-7.0.12/ext/intl/formatter/formatter_format.c:57
#6  0x0000000000ad8506 in ZEND_DO_ICALL_SPEC_HANDLER ()
    at /home/user/Desktop/php-7.0.12/Zend/zend_vm_execute.h:586
#7  0x0000000000ad7f32 in execute_ex (ex=0x7fffebc14030)
    at /home/user/Desktop/php-7.0.12/Zend/zend_vm_execute.h:414
#8  0x0000000000ad8043 in zend_execute (op_array=0x7fffebc81000, 
    return_value=0x0)
    at /home/user/Desktop/php-7.0.12/Zend/zend_vm_execute.h:458
#9  0x0000000000a78cfc in zend_execute_scripts (type=0x8, retval=0x0, 
    file_count=0x3) at /home/user/Desktop/php-7.0.12/Zend/zend.c:1427
#10 0x00000000009e11d5 in php_execute_script (primary_file=0x7fffffffce20)
    at /home/user/Desktop/php-7.0.12/main/main.c:2494
#11 0x0000000000b412f8 in do_cli (argc=0x2, argv=0x14a6630)
    at /home/user/Desktop/php-7.0.12/sapi/cli/php_cli.c:974
#12 0x0000000000b424c6 in main (argc=0x2, argv=0x14a6630)
    at /home/user/Desktop/php-7.0.12/sapi/cli/php_cli.c:1344
#13 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
#14 0x00000000004475a9 in _start ()


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-11-05 21:49 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2016-11-05 21:49 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:48 UTC] nguyenluan dot vnn at gmail dot com
-Status: Closed +Status: Assigned -PHP Version: 7.0.12 +PHP Version: 7.0.13
 [2016-11-11 12:48 UTC] nguyenluan dot vnn at gmail dot com
It still crashes in version 7.0.13. Please check again.
 [2016-11-11 12:48 UTC] nguyenluan dot vnn at gmail dot com
-Status: Assigned +Status: Open
 [2016-11-11 12:48 UTC] nguyenluan dot vnn at gmail dot com
Open again.
 [2016-11-14 11:47 UTC] nguyenluan dot vnn at gmail dot com
-Status: Open +Status: Closed
 [2016-11-14 11:47 UTC] nguyenluan dot vnn at gmail dot com
Fixed in PHP 7.1.0 RC6. Please close.

Thanks.
 [2017-02-13 01:00 UTC] stas@php.net
-Type: Security +Type: Bug
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Sep 23 04:01:25 2020 UTC