php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73316 Invalid memory access in spl_filesystem_dir_open function
Submitted: 2016-10-13 14:14 UTC Modified: 2016-11-14 11:41 UTC
From: nguyenluan dot vnn at gmail dot com Assigned: stas (profile)
Status: Closed Package: SPL related
PHP Version: 7.0.11 OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: nguyenluan dot vnn at gmail dot com
New email:
PHP Version: OS:

 

 [2016-10-13 14:14 UTC] nguyenluan dot vnn at gmail dot com
Description:
------------
In function spl_filesystem_dir_open:

static void spl_filesystem_dir_open(spl_filesystem_object* intern, char *path)
{
	int skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS);

	intern->type = SPL_FS_DIR;
	intern->_path_len = (int)strlen(path); // (1)
	intern->u.dir.dirp = php_stream_opendir(path, REPORT_ERRORS, FG(default_context));

	if (intern->_path_len > 1 && IS_SLASH_AT(path, intern->_path_len-1)) {  // (2) crash here because intern->_path_len is larger than strlen(path)
		intern->_path = estrndup(path, --intern->_path_len);
	} else {
		intern->_path = estrndup(path, intern->_path_len);
	}
	intern->u.dir.index = 0;

        ...
        ...
}

After the cast intern->_path_len = (int)strlen(path);, intern->_path_len has very large value and causes crash in IS_SLASH_AT(path, intern->_path_len-1)). Please refer to the test script and trace log.

Test script:
---------------
<?php
    ini_set('memory_limit', -1);
    $str = str_repeat('a', 0x8fffff00);
    $path = "/test/$str";
    $dir = new DirectoryIterator($path);
?>

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

Actual result:
--------------
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".

Program received signal SIGSEGV, Segmentation fault.

 [----------------------------------registers-----------------------------------]
RAX: 0x7ffe5d1fff1d 
RBX: 0x0 
RCX: 0x7ffff4199e87 (<munmap+7>:	cmp    rax,0xfffffffffffff001)
RDX: 0xffffffff8fffff05 
RSI: 0x0 
RDI: 0x1425220 --> 0x14251c0 --> 0x9d1ed6 (<php_plain_files_stream_opener>:	push   rbp)
RBP: 0x7fffffffa670 --> 0x7fffffffa700 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 (--> ...)
RSP: 0x7fffffffa650 --> 0x7ffecd200018 ("/test/", 'a' <repeats 194 times>...)
RIP: 0x832aa1 (<spl_filesystem_dir_open+173>:	movzx  eax,BYTE PTR [rax])
R8 : 0x0 
R9 : 0x0 
R10: 0x10 
R11: 0x202 
R12: 0x4432f0 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe1a0 --> 0x2 
R14: 0x7fffed614030 --> 0x7fffed6641c0 --> 0xaa058f (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
R15: 0x7fffed6641c0 --> 0xaa058f (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x10207 (CARRY PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x832a96 <spl_filesystem_dir_open+162>:	lea    rdx,[rax-0x1]
   0x832a9a <spl_filesystem_dir_open+166>:	mov    rax,QWORD PTR [rbp-0x20]
   0x832a9e <spl_filesystem_dir_open+170>:	add    rax,rdx
=> 0x832aa1 <spl_filesystem_dir_open+173>:	movzx  eax,BYTE PTR [rax]
   0x832aa4 <spl_filesystem_dir_open+176>:	cmp    al,0x2f
   0x832aa6 <spl_filesystem_dir_open+178>:	
    jne    0x832af5 <spl_filesystem_dir_open+257>
   0x832aa8 <spl_filesystem_dir_open+180>:	mov    rax,QWORD PTR [rbp-0x18]
   0x832aac <spl_filesystem_dir_open+184>:	mov    rax,QWORD PTR [rax+0x18]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa650 --> 0x7ffecd200018 ("/test/", 'a' <repeats 194 times>...)
0008| 0x7fffffffa658 --> 0x7fffed678000 --> 0x0 
0016| 0x7fffffffa660 --> 0x15a6f30 --> 0x1 
0024| 0x7fffffffa668 --> 0xed679090 
0032| 0x7fffffffa670 --> 0x7fffffffa700 --> 0x7fffffffa720 --> 0x7fffffffa770 --> 0x7fffffffa7a0 --> 0x7fffffffa7e0 (--> ...)
0040| 0x7fffffffa678 --> 0x834702 (<spl_filesystem_object_construct+592>:	)
0048| 0x7fffffffa680 --> 0x15bca80 --> 0x7fffffffd901 --> 0xc0000000000165cf 
0056| 0x7fffffffa688 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000000832aa1 in spl_filesystem_dir_open (intern=0x7fffed678000, 
    path=0x7ffecd200018 "/test/", 'a' <repeats 194 times>...)
    at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:238
238		if (intern->_path_len > 1 && IS_SLASH_AT(path, intern->_path_len-1)) {

gdb-peda$ p path
$3 = 0x7ffecd200018 "/test/", 'a' <repeats 194 times>...

gdb-peda$ p intern->_path_len
$4 = 0xffffffff8fffff06

gdb-peda$ bt
#0  0x0000000000832aa1 in spl_filesystem_dir_open (intern=0x7fffed678000, 
    path=0x7ffecd200018 "/test/", 'a' <repeats 194 times>...)
    at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:238
#1  0x0000000000834702 in spl_filesystem_object_construct (
    execute_data=0x7fffed614140, return_value=0x7fffed614120, ctor_flags=0x0)
    at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:724
#2  0x000000000083477e in zim_spl_DirectoryIterator___construct (
    execute_data=0x7fffed614140, return_value=0x7fffed614120)
    at /home/user/Desktop/php-7.0.11/ext/spl/spl_directory.c:738
#3  0x0000000000aa0a44 in ZEND_DO_FCALL_SPEC_HANDLER ()
    at /home/user/Desktop/php-7.0.11/Zend/zend_vm_execute.h:842
#4  0x0000000000a9f8c4 in execute_ex (ex=0x7fffed614030)
    at /home/user/Desktop/php-7.0.11/Zend/zend_vm_execute.h:414
#5  0x0000000000a9f9d5 in zend_execute (op_array=0x7fffed681000, 
    return_value=0x0)
    at /home/user/Desktop/php-7.0.11/Zend/zend_vm_execute.h:458
#6  0x0000000000a40aae in zend_execute_scripts (type=0x8, retval=0x0, 
    file_count=0x3) at /home/user/Desktop/php-7.0.11/Zend/zend.c:1427
#7  0x00000000009a8eba in php_execute_script (primary_file=0x7fffffffce20)
    at /home/user/Desktop/php-7.0.11/main/main.c:2494
#8  0x0000000000b08c8a in do_cli (argc=0x2, argv=0x145a560)
    at /home/user/Desktop/php-7.0.11/sapi/cli/php_cli.c:974
#9  0x0000000000b09e58 in main (argc=0x2, argv=0x145a560)
    at /home/user/Desktop/php-7.0.11/sapi/cli/php_cli.c:1344
#10 0x00007ffff40b9830 in __libc_start_main (main=0xb0964d <main>, argc=0x2, 
    argv=0x7fffffffe1a8, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe198)
    at ../csu/libc-start.c:291
#11 0x0000000000443319 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 13:05 UTC] nguyenluan dot vnn at gmail dot com
-Status: Closed +Status: Assigned
 [2016-11-11 13:05 UTC] nguyenluan dot vnn at gmail dot com
Still crash in version 7.0.13. Please check again.
 [2016-11-11 13:06 UTC] nguyenluan dot vnn at gmail dot com
-Status: Assigned +Status: Open
 [2016-11-11 13:06 UTC] nguyenluan dot vnn at gmail dot com
Open this issue again.
 [2016-11-14 11:41 UTC] nguyenluan dot vnn at gmail dot com
-Status: Open +Status: Closed
 [2016-11-14 11:41 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 Mar 28 16:01:29 2024 UTC