php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73773 Seg fault when loading hostile phar
Submitted: 2016-12-17 12:06 UTC Modified: 2017-07-12 17:09 UTC
From: eyal dot itkin at gmail dot com Assigned: stas (profile)
Status: Closed Package: PHAR related
PHP Version: 5.6.29 OS:
Private report: No CVE-ID: 2017-11147
 [2016-12-17 12:06 UTC] eyal dot itkin at gmail dot com
Description:
------------
phar.c - phar_parse_pharfile() has insufficient sanity checks on the entry data. A hostile phar archive can lead the parser to access memory out of the allocated buffer, resulting in a crash.

The for loop that parses the manifest entries does not properly checks that the metadata_len 4 bytes field is inside the buffer, enabling a huge page aligned archive to trigger an out-of-page read, causing a segmentation fault - as presented in the attached trace.

The proposed fix is to add a check before reading this length field (just like the check in the start of the for loop):
if ( 4 > (size_t)(endbuffer - buffer))
{
    <report error>
}

This report is somewhat connected to report #73764, and both should probably be fixed together so to avoid confusion.

Test script:
---------------
<?php
	$p = new Phar('example_hostile.phar', 0);
	echo "Loaded the phar archive\n";
?>

Expected result:
----------------
no crash, calling the echo with the specified message as intended

Actual result:
--------------
segmentation fault.

(gdb) bt
#0  0xb4c7cb56 in ?? () from /usr/lib/php/20151012/phar.so
#1  0xb4c7ebce in phar_create_or_parse_filename ()
   from /usr/lib/php/20151012/phar.so
#2  0xb4c7f8b7 in phar_open_or_create_filename ()
   from /usr/lib/php/20151012/phar.so
#3  0xb4c8120e in zim_Phar___construct () from /usr/lib/php/20151012/phar.so
#4  0x80348662 in execute_internal ()
#5  0x802a1dce in dtrace_execute_internal ()
#6  0x80339f65 in ?? ()
#7  0x802f26da in execute_ex ()
#8  0x802a1c35 in dtrace_execute_ex ()
#9  0x8034a1b6 in zend_execute ()
#10 0x802b210d in zend_execute_scripts ()
#11 0x80251054 in php_execute_script ()
#12 0x8034c01f in ?? ()
#13 0x8012b64f in main ()
(gdb) info reg
eax            0xa8200000	-1474297856
ecx            0x0	0
edx            0xb49fffec	-1264582676
ebx            0xb4ca6c40	-1261802432
esp            0xbfeee240	0xbfeee240
ebp            0xb5274000	0xb5274000
esi            0x640001b	104857627
edi            0xb4a00000	-1264582656
eip            0xb4c7cb56	0xb4c7cb56
eflags         0x210246	[ PF ZF IF RF ID ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-27 07:05 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-12-27 07:05 UTC] stas@php.net
Please provide example_hostile.phar
 [2016-12-27 09:04 UTC] eyal dot itkin at gmail dot com
-Status: Feedback +Status: Open
 [2016-12-27 09:04 UTC] eyal dot itkin at gmail dot com
Uploaded the example_hostile.phar (+ the python script than generated it) to this link: http://www.cs.tau.ac.il/~eyalitki/Upload/73773/
 [2016-12-31 00:07 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-12-31 00:07 UTC] stas@php.net
I can't reproduce this after fix for #73764 is applied. Could you please check if it still happens for you?
 [2016-12-31 08:56 UTC] eyal dot itkin at gmail dot com
-Status: Feedback +Status: Open
 [2016-12-31 08:56 UTC] eyal dot itkin at gmail dot com
It still happens, and this is because:
1) #73764 checked that the static 24 entry bytes (entry.filename_len, entry.uncompressed_filesize, timestamp, compressed_filesize, crc32, flags) have enough space in the buffer.
2) #73764 also checked that the dynamic filename has enough space in the buffer
3) After all of these fields there are additional fields:
 a) 4   bytes - len (metadata_len)
 b) len bytes - the actual metadata

The current code reads the 4 bytes (without checking it is inside the buffer), and the checks that has enough (len) bytes so to read the metadata itself.
 [2016-12-31 09:19 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-12-31 09:19 UTC] stas@php.net
Could you please supply the file that reproduces it for you? For me it does not reproduce with the file at the link here.
 [2016-12-31 10:29 UTC] eyal dot itkin at gmail dot com
-Status: Feedback +Status: Open
 [2016-12-31 10:29 UTC] eyal dot itkin at gmail dot com
* I uploaded a new .phar file that was tested in my environment to reproduce the error.
* Again, I uploaded the python script that generated it (build_phar_new.py).
* Both files can be found in the same link as before:  http://www.cs.tau.ac.il/~eyalitki/Upload/73773/
 [2017-01-01 02:48 UTC] stas@php.net
-PHP Version: 7.1.0 +PHP Version: 5.6.29 -Assigned To: +Assigned To: stas
 [2017-01-01 02:48 UTC] stas@php.net
The fix is in security repo as e5246580a85f031e1a3b8064edbaa55c1643a451 and in https://gist.github.com/b7b2c560555bedec94a12f73cacc182f

please verify
 [2017-01-01 04:02 UTC] eyal dot itkin at gmail dot com
I approve of the suggested fix.
 [2017-01-03 05:11 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e5246580a85f031e1a3b8064edbaa55c1643a451
Log: Fix bug #73773 - Seg fault when loading hostile phar
 [2017-01-03 05:11 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2017-01-03 05:26 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e5246580a85f031e1a3b8064edbaa55c1643a451
Log: Fix bug #73773 - Seg fault when loading hostile phar
 [2017-01-05 23:57 UTC] tyrael@php.net
-Summary: Seg fault when loading hostile phar +Summary: Segfault when loading hostile phar
 [2017-01-06 00:00 UTC] tyrael@php.net
-Summary: Segfault when loading hostile phar +Summary: Seg fault when loading hostile phar
 [2017-02-13 00:54 UTC] stas@php.net
-CVE-ID: +CVE-ID: needed
 [2017-07-12 10:41 UTC] henri at nerv dot fi
CVE-2017-11147 has been assigned for this issue.
 [2017-07-12 17:09 UTC] stas@php.net
-CVE-ID: needed +CVE-ID: 2017-11147
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Nov 05 19:01:29 2024 UTC