php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #77919 Potential UAF in Phar RSHUTDOWN
Submitted: 2019-04-18 14:01 UTC Modified: 2019-07-29 20:22 UTC
From: cmb@php.net Assigned: stas (profile)
Status: Closed Package: PHAR related
PHP Version: 7.3Git-2019-04-18 (Git) OS: *
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 this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: cmb@php.net
New email:
PHP Version: OS:

 

 [2019-04-18 14:01 UTC] cmb@php.net
Description:
------------
phar_convert_to_other() calls phar_rename_archive(), and if the
latter fails when trying to phar_flush()[1], there is already an
additional entry for the phar added to PHAR_G(phar_fname_map)
keeping a dangling pointer to phar_archive_data which causes a
use-after-free in the request shutdown sequence.

I suggest to apply something like the attached fix-phar-uaf.patch.

I believe this issue has been introduced when fixing bug #77586,
and as such is likely to affect PHP-7.1+.  Not sure whether it
qualifies as security issue, though.

[1] <https://github.com/php/php-src/blob/php-7.3.4/ext/phar/phar_object.c#L2200>


Test script:
---------------
make test TESTS="-m ext/phar/tests/bug71488.phpt"

Actual result:
--------------
==1459== Invalid read of size 4
==1459==    at 0x72A0D7: _zend_is_inconsistent (zend_hash.c:50)
==1459==    by 0x72F8EA: zend_hash_apply (zend_hash.c:1684)
==1459==    by 0x4FBD30: destroy_phar_data (phar.c:361)
==1459==    by 0x72E9E4: zend_hash_destroy (zend_hash.c:1429)
==1459==    by 0x506F43: zm_deactivate_phar (phar.c:3527)
==1459==    by 0x72360B: zend_deactivate_modules (zend_API.c:2648)
==1459==    by 0x686D6E: php_request_shutdown (main.c:1900)
==1459==    by 0x7EE100: do_cli (php_cli.c:1164)
==1459==    by 0x7EE7DA: main (php_cli.c:1389)
==1459==  Address 0x94654c0 is 80 bytes inside a block of size 328 free'd
==1459==    at 0x4C2CDDB: free (vg_replace_malloc.c:530)
==1459==    by 0x6E355D: _efree (zend_alloc.c:2510)
==1459==    by 0x50F765: phar_convert_to_other (phar_object.c:2339)
==1459==    by 0x512518: zim_Phar_decompress (phar_object.c:3286)
==1459==    by 0x77E513: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1102)
==1459==    by 0x7E57E4: execute_ex (zend_vm_execute.h:55489)
==1459==    by 0x7EADD1: zend_execute (zend_vm_execute.h:60881)
==1459==    by 0x7196C8: zend_execute_scripts (zend.c:1568)
==1459==    by 0x688353: php_execute_script (main.c:2630)
==1459==    by 0x7ED867: do_cli (php_cli.c:997)
==1459==    by 0x7EE7DA: main (php_cli.c:1389)
==1459==  Block was alloc'd at
==1459==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==1459==    by 0x6E41E2: __zend_malloc (zend_alloc.c:2903)
==1459==    by 0x6E34B6: _emalloc (zend_alloc.c:2496)
==1459==    by 0x6E3909: _ecalloc (zend_alloc.c:2581)
==1459==    by 0x50F104: phar_convert_to_other (phar_object.c:2242)
==1459==    by 0x512518: zim_Phar_decompress (phar_object.c:3286)
==1459==    by 0x77E513: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1102)
==1459==    by 0x7E57E4: execute_ex (zend_vm_execute.h:55489)
==1459==    by 0x7EADD1: zend_execute (zend_vm_execute.h:60881)
==1459==    by 0x7196C8: zend_execute_scripts (zend.c:1568)
==1459==    by 0x688353: php_execute_script (main.c:2630)
==1459==    by 0x7ED867: do_cli (php_cli.c:997)
==1459== 
==1459== Invalid read of size 4
==1459==    at 0x72A0E9: _zend_is_inconsistent (zend_hash.c:53)
==1459==    by 0x72F8EA: zend_hash_apply (zend_hash.c:1684)
==1459==    by 0x4FBD30: destroy_phar_data (phar.c:361)
==1459==    by 0x72E9E4: zend_hash_destroy (zend_hash.c:1429)
==1459==    by 0x506F43: zm_deactivate_phar (phar.c:3527)
==1459==    by 0x72360B: zend_deactivate_modules (zend_API.c:2648)
==1459==    by 0x686D6E: php_request_shutdown (main.c:1900)
==1459==    by 0x7EE100: do_cli (php_cli.c:1164)
==1459==    by 0x7EE7DA: main (php_cli.c:1389)
==1459==  Address 0x94654c0 is 80 bytes inside a block of size 328 free'd
==1459==    at 0x4C2CDDB: free (vg_replace_malloc.c:530)
==1459==    by 0x6E355D: _efree (zend_alloc.c:2510)
==1459==    by 0x50F765: phar_convert_to_other (phar_object.c:2339)
==1459==    by 0x512518: zim_Phar_decompress (phar_object.c:3286)
==1459==    by 0x77E513: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1102)
==1459==    by 0x7E57E4: execute_ex (zend_vm_execute.h:55489)
==1459==    by 0x7EADD1: zend_execute (zend_vm_execute.h:60881)
==1459==    by 0x7196C8: zend_execute_scripts (zend.c:1568)
==1459==    by 0x688353: php_execute_script (main.c:2630)
==1459==    by 0x7ED867: do_cli (php_cli.c:997)
==1459==    by 0x7EE7DA: main (php_cli.c:1389)
==1459==  Block was alloc'd at
==1459==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==1459==    by 0x6E41E2: __zend_malloc (zend_alloc.c:2903)
==1459==    by 0x6E34B6: _emalloc (zend_alloc.c:2496)
==1459==    by 0x6E3909: _ecalloc (zend_alloc.c:2581)
==1459==    by 0x50F104: phar_convert_to_other (phar_object.c:2242)
==1459==    by 0x512518: zim_Phar_decompress (phar_object.c:3286)
==1459==    by 0x77E513: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1102)
==1459==    by 0x7E57E4: execute_ex (zend_vm_execute.h:55489)
==1459==    by 0x7EADD1: zend_execute (zend_vm_execute.h:60881)
==1459==    by 0x7196C8: zend_execute_scripts (zend.c:1568)
==1459==    by 0x688353: php_execute_script (main.c:2630)
==1459==    by 0x7ED867: do_cli (php_cli.c:997)
==1459== 


Patches

fix-phar-uaf (last revision 2019-04-18 14:03 UTC by cmb@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-04-18 14:01 UTC] cmb@php.net
-Assigned To: +Assigned To: stas
 [2019-04-18 14:01 UTC] cmb@php.net
Stas, could you please have a look at this?
 [2019-04-18 14:03 UTC] cmb@php.net
The following patch has been added/updated:

Patch Name: fix-phar-uaf
Revision:   1555596207
URL:        https://bugs.php.net/patch-display.php?bug=77919&patch=fix-phar-uaf&revision=1555596207
 [2019-04-18 14:43 UTC] cmb@php.net
Hmm, fix-phar-uaf.patch breaks ext/phar/tests/bug77022.phpt, so it
cannot be used.
 [2019-04-18 16:52 UTC] stas@php.net
-Assigned To: stas +Assigned To: bishop
 [2019-04-29 03:36 UTC] stas@php.net
@bishop ay thoughts about this?
 [2019-04-29 07:09 UTC] bishop@php.net
I have confirmed the behavior, and I've identified two other paths that might also suffer. I have a preliminary fix, but;

I've not yet confirmed that bug 77586 caused it, and I'm also not sure how I missed a test failure pointing this out. I want to dig on that process issue a little further to ensure we don't have bug fixes spawning bugs.
 [2019-04-29 07:31 UTC] cmb@php.net
gcov.php.net runs valgrind enabled tests, and bug71488.phpt is
shown to fail there[1].

[1] <http://gcov.php.net/viewer.php?version=PHP_7_3&func=valgrind&file=ext%2Fphar%2Ftests%2Fbug71488.phpt>
 [2019-04-29 07:41 UTC] bishop@php.net
Thanks, Christoph. Are those build failures sent to a mailing list? I'd like to be on it.
 [2019-04-29 07:50 UTC] cmb@php.net
To my knowledge, these test results are not sent to any mailing list.
 [2019-06-25 05:29 UTC] stas@php.net
Any news here?
 [2019-07-29 10:04 UTC] nikic@php.net
Is there any particular reason why the insertion into fname_map has to happen before the flush? There were no test failures after swapping the order.

When patching this, please remove the use of %A in bug71488.phpt -- we would have noticed this issue earlier without that.
 [2019-07-29 10:23 UTC] nikic@php.net
In any case, your patch LGTM for 7.1+. In the interest of conservativeness we should probably only change the order of operations for 7.4.
 [2019-07-29 14:16 UTC] cmb@php.net
I had a look at the patch again, and found that bug77022.phpt is
failing for me regardless of the patch, but only from WSL or a
Linux VM with the test code in the Windows host NTFS; this test
failure is bogus, so the patch should be fine.

I've finished the patch including the suggested test fix:
<https://gist.github.com/cmb69/5501fed23e8c6e007b658c6c65caa810>.

Stas, could you please apply that so it makes it into the next
GAs (tagging happens tomorrow)?

Nikita, feel free to apply your suggested patch for PHP-7.4+.

Thanks.
 [2019-07-29 14:16 UTC] cmb@php.net
-Assigned To: bishop +Assigned To: stas
 [2019-07-29 20:22 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2019-07-29 20:22 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.


 [2019-07-30 07:17 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e204df55ac10a3f7d4387992ea546e46860fb955
Log: Fix #77919: Potential UAF in Phar RSHUTDOWN
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 23:01:28 2024 UTC