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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 27 12:01:29 2024 UTC