Check the stack limit when calling internal functions#22545
Open
iliaal wants to merge 1 commit into
Open
Conversation
zend_call_function invokes an internal callee's handler directly, with no VM frame and without the stack-limit check the interpreter runs at its call opcodes. An internal function that recurses through zend_call_function, such as a self- or mutually-attached SPL iterator, never yields back to the VM, so nothing bounds the recursion and the C stack overflows into a SEGV. Check zend_call_stack_overflowed() in the internal branch behind ZEND_CHECK_STACK_LIMIT, raise the usual "Maximum call stack size reached" error on overflow, and tear the just-built call frame down as the normal return path does. Fixes phpGH-15672 Fixes phpGH-15911
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.
GH-16492 fixes GH-15911 by guarding AppendIterator against appending to itself; this is the general form. An internal function that recurses through zend_call_function (which invokes internal handlers directly, with no VM frame and no stack-limit check) never yields back to the VM, so the C stack overflows into a SEGV. This adds the interpreter's stack-limit check to that path, behind ZEND_CHECK_STACK_LIMIT, raising the usual "Maximum call stack size reached" error instead. It covers a MultipleIterator (GH-15672) or AppendIterator (GH-15911) attached to itself and a mutual cycle between two such iterators that a per-iterator guard cannot see. For a pure internal-to-internal cycle the error is uncatchable, since there is no user frame in the recursion to unwind into. Fixes #15672 and #15911.