php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73662 Phar::mapPhar illegal memory access
Submitted: 2016-12-06 00:40 UTC Modified: 2017-01-16 09:13 UTC
From: fernando at null-life dot com Assigned: stas (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-12-06 00:40 UTC] fernando at null-life dot com
Description:
------------
When alias parameter length is a big string, type confusion happens in alias_len parameter, and next illegal memory access in zend_inline_hash_func function.

-------------------------------------------------------------------------
Source code:
https://github.com/php/php-src/blob/PHP-7.0/Zend/zend_string.h#L330

static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
{
        register zend_ulong hash = Z_UL(5381);

        /* variant with the hash unrolled eight times */
        for (; len >= 8; len -= 8) {
                hash = ((hash << 5) + hash) + *str++;    // Illegal memory access
                hash = ((hash << 5) + hash) + *str++;
                hash = ((hash << 5) + hash) + *str++;
                hash = ((hash << 5) + hash) + *str++;
                hash = ((hash << 5) + hash) + *str++;
                hash = ((hash << 5) + hash) + *str++;
                hash = ((hash << 5) + hash) + *str++;
                hash = ((hash << 5) + hash) + *str++;
        }
        switch (len) {
                case 7: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
                case 6: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
                case 5: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
                case 4: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
                case 3: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
                case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
                case 1: hash = ((hash << 5) + hash) + *str++; break;
                case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
        }
...



GDB output

 gdb -q --args /home/operac/build5/bin/php -n poc.php
Reading symbols from /home/operac/build5/bin/php...done.
(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".

Program received signal SIGSEGV, Segmentation fault.
0x0000000000e75b1d in zend_inline_hash_func (str=0x7fffef001001 <error: Cannot access memory at address 0x7fffef001001>, len=18446744069414580238) at /home/operac/build5/php-src/Zend/zend_string.h:330
330                     hash = ((hash << 5) + hash) + *str++;
(gdb) bt
#0  0x0000000000e75b1d in zend_inline_hash_func (str=0x7fffef001001 <error: Cannot access memory at address 0x7fffef001001>, len=18446744069414580238) at /home/operac/build5/php-src/Zend/zend_string.h:330
#1  0x0000000000e85193 in zend_hash_str_find (ht=0x1ce3e38 <phar_globals+120>, str=0x7ffeef000018 'A' <repeats 200 times>..., len=18446744073709551606) at /home/operac/build5/php-src/Zend/zend_hash.c:1998
#2  0x00000000008e17b2 in zend_hash_str_find_ptr (ht=0x1ce3e38 <phar_globals+120>, str=0x7ffeef000018 'A' <repeats 200 times>..., len=18446744073709551606) at /home/operac/build5/php-src/Zend/zend_hash.h:697
#3  0x00000000008e92d9 in phar_get_archive (archive=0x7fffffffa240, fname=0x7fffef258378 "/home/operac/crashes/phar2/poc.php", fname_len=34, alias=0x7ffeef000018 'A' <repeats 200 times>..., alias_len=-10, error=0x0)
    at /home/operac/build5/php-src/ext/phar/util.c:1010
#4  0x000000000092e029 in phar_open_parsed_phar (fname=0x7fffef258378 "/home/operac/crashes/phar2/poc.php", fname_len=34, alias=0x7ffeef000018 'A' <repeats 200 times>..., alias_len=-10, is_data=0, options=8, pphar=0x0, error=0x0)
    at /home/operac/build5/php-src/ext/phar/phar.c:553
#5  0x000000000093919d in phar_open_executed_filename (alias=0x7ffeef000018 'A' <repeats 200 times>..., alias_len=-10, error=0x7fffffffa400) at /home/operac/build5/php-src/ext/phar/phar.c:2281
#6  0x0000000000949a43 in zim_Phar_mapPhar (execute_data=0x7fffef2140e0, return_value=0x7fffef2140d0) at /home/operac/build5/php-src/ext/phar/phar_object.c:970
#7  0x0000000000f29b1c in ZEND_DO_FCALL_SPEC_HANDLER () at /home/operac/build5/php-src/Zend/zend_vm_execute.h:842
#8  0x0000000000f26873 in execute_ex (ex=0x7fffef214030) at /home/operac/build5/php-src/Zend/zend_vm_execute.h:414
#9  0x0000000000f26aee in zend_execute (op_array=0x7fffef27f000, return_value=0x0) at /home/operac/build5/php-src/Zend/zend_vm_execute.h:458
#10 0x0000000000e49c67 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/operac/build5/php-src/Zend/zend.c:1427
#11 0x0000000000d0b9d9 in php_execute_script (primary_file=0x7fffffffd090) at /home/operac/build5/php-src/main/main.c:2494
#12 0x0000000001058a1d in do_cli (argc=3, argv=0x60300000edd0) at /home/operac/build5/php-src/sapi/cli/php_cli.c:974
#13 0x000000000105a82d in main (argc=3, argv=0x60300000edd0) at /home/operac/build5/php-src/sapi/cli/php_cli.c:1344




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

ini_set('memory_limit', -1);


$v1=str_repeat("A",4294967286);
Phar::mapPhar($v1);

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

Actual result:
--------------
ASan output:

ASAN:SIGSEGV
=================================================================
==16321==ERROR: AddressSanitizer: SEGV on unknown address 0x7fd9fdc01000 (pc 0x000000e75b1d bp 0x7fff638deac0 sp 0x7fff638deaa0 T0)
    #0 0xe75b1c in zend_inline_hash_func /home/operac/build5/php-src/Zend/zend_string.h:330
    #1 0xe85192 in zend_hash_str_find /home/operac/build5/php-src/Zend/zend_hash.c:1998
    #2 0x8e17b1 in zend_hash_str_find_ptr /home/operac/build5/php-src/Zend/zend_hash.h:697
    #3 0x8e92d8 in phar_get_archive /home/operac/build5/php-src/ext/phar/util.c:1010
    #4 0x92e028 in phar_open_parsed_phar /home/operac/build5/php-src/ext/phar/phar.c:553
    #5 0x93919c in phar_open_executed_filename /home/operac/build5/php-src/ext/phar/phar.c:2281
    #6 0x949a42 in zim_Phar_mapPhar /home/operac/build5/php-src/ext/phar/phar_object.c:970
    #7 0xf29b1b in ZEND_DO_FCALL_SPEC_HANDLER /home/operac/build5/php-src/Zend/zend_vm_execute.h:842
    #8 0xf26872 in execute_ex /home/operac/build5/php-src/Zend/zend_vm_execute.h:414
    #9 0xf26aed in zend_execute /home/operac/build5/php-src/Zend/zend_vm_execute.h:458
    #10 0xe49c66 in zend_execute_scripts /home/operac/build5/php-src/Zend/zend.c:1427
    #11 0xd0b9d8 in php_execute_script /home/operac/build5/php-src/main/main.c:2494
    #12 0x1058a1c in do_cli /home/operac/build5/php-src/sapi/cli/php_cli.c:974
    #13 0x105a82c in main /home/operac/build5/php-src/sapi/cli/php_cli.c:1344
    #14 0x7fda034ff82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #15 0x430a88 in _start (/home/operac/build5/bin/php+0x430a88)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/operac/build5/php-src/Zend/zend_string.h:330 zend_inline_hash_func
==16321==ABORTING


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-01-16 09:13 UTC] stas@php.net
-Status: Open +Status: Closed -Type: Security +Type: Bug -Assigned To: +Assigned To: stas
 [2017-01-16 09:13 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.

Looks like this one is already fixed.
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Fri Oct 09 01:00:01 2026 UTC