Fix GH-22845: use-after-free with a stashed user-filter bucket brigade#188
Closed
iliaal wants to merge 1 commit into
Closed
Fix GH-22845: use-after-free with a stashed user-filter bucket brigade#188iliaal wants to merge 1 commit into
iliaal wants to merge 1 commit into
Conversation
…gade The bucket brigades passed to a user filter's filter() method are allocated on the filter caller's C stack and handed to userland as le_bucket_brigade resources, but userfilter_filter never closed them. A filter that stashed $in or $out (e.g. in a global) kept a resource whose ptr still pointed at the popped stack frame; the stream_bucket_*() functions fetch by resource type only, so a later call dereferenced freed stack. Close both resources after the callback so a stashed copy becomes non-fetchable and throws instead, and wrap the callback in zend_try/zend_catch so the close still runs when the filter bails out (which otherwise longjmps past it and leaves the resource reachable from a shutdown function). Fixes phpGH-22845
Owner
Author
|
Promoted upstream: php#22850 |
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.
A user stream filter's
filter($in, $out, ...)receives its bucket brigades asle_bucket_brigaderesources, but every caller that dispatches a filter allocates those brigades on its own C stack.userfilter_filteronlyzval_ptr_dtors the argument zvals after the callback and never closes the resources, so a filter that stashes$inor$outkeeps a resource whoseptrstill points at the popped stack frame.stream_bucket_make_writeable()andstream_bucket_append()fetch by resource type only, so reusing a stashed brigade dereferences freed stack (ASAN reports stack-use-after-return). Closing both resources right after the callback invalidates any stashed copy, which then throws a TypeError instead of corrupting memory.The callback is wrapped in
zend_try/zend_catchso the close runs even when the filter bails out (a fatal error would otherwise longjmp past it, leaving the resource fetchable from aregister_shutdown_function).