From f7b7472301f800ca65f2d92dd3ef51bccaa243c8 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 26 Jan 2025 13:33:40 +0100 Subject: [PATCH] Fix GH-17577: JIT packed type guard crash When a guard check is created for a variable to check if it's a packed array, it is possible that there was no prior type check for that variable. This happens in the global scope for example when the variable aliases. In the test, this causes a dereference of address 8 because the integer element in `$a` is interpreted as an array address. This patch adds a check to see if the guard is handled. If we were not able to determine or guard the type then we also cannot know the array is packed. --- ext/opcache/jit/zend_jit_trace.c | 3 +++ ext/opcache/tests/jit/gh17577.phpt | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 ext/opcache/tests/jit/gh17577.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 5d824c207d18f..c138a5bcb0acb 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4162,12 +4162,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } if ((info & MAY_BE_PACKED_GUARD) != 0 + && (info & MAY_BE_GUARD) == 0 && (trace_buffer->stop == ZEND_JIT_TRACE_STOP_LOOP || trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL || trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) && (ssa->vars[i].use_chain != -1 || (ssa->vars[i].phi_use_chain && !(ssa->var_info[ssa->vars[i].phi_use_chain->ssa_var].type & MAY_BE_PACKED_GUARD)))) { + ZEND_ASSERT(STACK_TYPE(stack, i) == IS_ARRAY); + if (!zend_jit_packed_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), info)) { goto jit_failure; } diff --git a/ext/opcache/tests/jit/gh17577.phpt b/ext/opcache/tests/jit/gh17577.phpt new file mode 100644 index 0000000000000..2eac2d05e432d --- /dev/null +++ b/ext/opcache/tests/jit/gh17577.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-17577 (JIT packed type guard crash) +--EXTENSIONS-- +opcache +--INI-- +opcache.jit_buffer_size=16M +opcache.jit_hot_func=1 +--FILE-- + +--EXPECTF-- +Warning: Trying to access array offset on int in %s on line %d + +Warning: Trying to access array offset on int in %s on line %d + +Warning: Trying to access array offset on int in %s on line %d