Sec Bug->Bug #73662 [Opn->Csd]: Phar::mapPhar illegal memory access
| From: | stas@php.net | Date: | Mon, 16 Jan 2017 09:13:15 +0000 |
| Subject: | Sec Bug->Bug #73662 [Opn->Csd]: Phar::mapPhar illegal memory access | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-206658@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73662&edit=1
ID: 73662
Updated by: stas@php.net
Reported by: fernando at null-life dot com
Summary: Phar::mapPhar illegal memory access
-Status: Open
+Status: Closed
-Type: Security
+Type: Bug
Package: PHAR related
Operating System: Linux
PHP Version: 7.0.13
-Assigned To:
+Assigned To: stas
Block user comment: N
Private report: Y
New Comment:
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.
Previous Comments:
------------------------------------------------------------------------
[2016-12-06 00:40:27] 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
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73662&edit=1