Fix GH-21776: use-after-free in zend_std_read_property magic __isset#36
Closed
Fix GH-21776: use-after-free in zend_std_read_property magic __isset#36
Conversation
When __isset drops the last non-temp reference to $this (e.g. $GLOBALS['o'] = 0), the OBJ_RELEASE after the __isset call freed zobj before zend_std_read_property reached the shared uninit_error check at zend_lazy_object_must_init(zobj), a heap-use-after-free. The GC_ADDREF/OBJ_RELEASE pair around __isset has been correct since 2018. The 2023 lazy-object support added a zobj read in the shared fall-through path without extending the isset branch's ref coverage to match. Defer the release via a local flag so zobj stays alive through the lazy-init check and the recursive read on the initialized instance. Route the two returns inside the lazy block through exit so the deferred release runs on those paths too. Closes phpGH-21776
Owner
Author
|
Superseded by upstream php#21786. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes php#21776.
When
__issetdrops the last non-temp reference to$this(e.g.$GLOBALS['o'] = 0), theOBJ_RELEASE(zobj)after the__issetcall freed the object before
zend_std_read_propertyreached theshared
uninit_errorcheck atzend_lazy_object_must_init(zobj).ASAN reports a heap-use-after-free.
Defer the release via a local flag so
zobjstays alive through thelazy-init check and the recursive read on the initialized instance.
Route the two
returns inside the lazy block throughexit:so thedeferred release runs on those paths too.