diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 5d824c207d18f..fa770975039ab 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4168,6 +4168,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par && (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)))) { + /* The variable type is not checked in all cases above, for example when alias != NO_ALIAS. + * We must emit a type check before dereferencing the array in zend_jit_packed_guard(). */ + if ((info & MAY_BE_GUARD) != 0) { + if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), IS_ARRAY)) { + goto jit_failure; + } + info &= ~MAY_BE_GUARD; + } + 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