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

Pull Requests

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: Thu Dec 12 11:01:28 2024 UTC