Fix GH-21368 crash: runtime orig_handler lookup in escape_if_undef#21710
Open
iliaal wants to merge 1 commit intophp:PHP-8.4from
Open
Fix GH-21368 crash: runtime orig_handler lookup in escape_if_undef#21710iliaal wants to merge 1 commit intophp:PHP-8.4from
iliaal wants to merge 1 commit intophp:PHP-8.4from
Conversation
…ndef PR php#21368 replaced the trace_escape stub dispatch in zend_jit_escape_if_undef with a compile-time constant load of orig_handler, computed from the exit info's op_array pointer. That pointer can be NULL (when current_frame is NULL at exit-point creation) or stale (when the underlying op_array is freed before the side trace compiles), producing an access violation inside zend_jit_escape_if_undef. Reported on PHP 8.5.5 Windows NTS. Drop the op_array parameter and emit a runtime lookup via zend_jit_orig_opline_handler() instead. That helper resolves the jit_extension through EX(func) at dispatch time, which is valid regardless of the compile-time op_array state. The gh21267 tests still pass, confirming the infinite-loop fix is preserved.
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.
Follow-up to #21368.
@vibbow reported an access violation in
zend_jit_escape_if_undefon PHP 8.5.5 VS17 x64 NTS (Windows + IIS + FastCGI), crashing at the fix I introduced in #21368:The crashing instruction is
mov rcx, [rax+rcx*8+0xD0], whereraxis a heap address and the byte at+0xD0is unmapped. On 64-bit NTS that offset matcheszend_op_array->reserved[zend_func_info_rid], which is exactly whatZEND_FUNC_INFO(op_array)expands to in my fix.Root cause
#21368 changed
zend_jit_escape_if_undefto dispatch directly toorig_handler, computed at JIT compile time fromexit_info->op_array. That pointer is unreliable:zend_jit_trace_get_exit_pointsetsop_array = NULLatext/opcache/jit/zend_jit_trace.c:164whenJIT_G(current_frame)is NULL at exit-point creation.+0xD0lands in released memory, which fits a freed/reused op_array.Either way,
ZEND_FUNC_INFO(op_array)dereferences a bad pointer.Fix
Use the existing
zend_jit_orig_opline_handler(jit)runtime helper instead. It emits IR that loadsEX(func)->reserved[rid]->offsetat dispatch time, adds it to the current IP, and loadsorig_handler.EX(func)is the currently-executing frame's function, so no compile-timeop_arrayis needed.zend_jit_trace_exit_stubalready uses this exact pattern atzend_jit_ir.c:2525.I dropped the
op_arrayparameter fromzend_jit_escape_if_undefand updated the call site inzend_jit_trace_deoptimization.Verification
gh21267.phptandgh21267_blacklist.phptboth still pass, confirming the original infinite-loop fix is preserved.Reproducer
I tried to build a native Linux reproducer and couldn't trigger the NULL/stale
op_arraypath through synthetic stress, opcache invalidation, or trace-buffer manipulation. The race looks specific to long-running FastCGI workers on Windows where opcache eviction crosses with side-trace compilation. The crash dump analysis is unambiguous and the runtime-lookup fix eliminates the class of issue.