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

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 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-2025 The PHP Group
All rights reserved.
Last updated: Sun Jul 06 20:01:35 2025 UTC