Skip to content

Commit ab89b9b

Browse files
committed
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 type check if a prior one was not inserted.
1 parent 2e02cdf commit ab89b9b

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4168,6 +4168,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
41684168
&& (ssa->vars[i].use_chain != -1
41694169
|| (ssa->vars[i].phi_use_chain
41704170
&& !(ssa->var_info[ssa->vars[i].phi_use_chain->ssa_var].type & MAY_BE_PACKED_GUARD)))) {
4171+
/* The variable type is not checked in all cases above, for example when alias != NO_ALIAS.
4172+
* We must emit a type check before dereferencing the array in zend_jit_packed_guard(). */
4173+
if ((info & MAY_BE_GUARD) != 0) {
4174+
if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), IS_ARRAY)) {
4175+
goto jit_failure;
4176+
}
4177+
info &= ~MAY_BE_GUARD;
4178+
}
4179+
41714180
if (!zend_jit_packed_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), info)) {
41724181
goto jit_failure;
41734182
}

ext/opcache/tests/jit/gh17577.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-17577 (JIT packed type guard crash)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit_buffer_size=16M
7+
opcache.jit_hot_func=1
8+
--FILE--
9+
<?php
10+
$a = array(
11+
array(1,2,3),
12+
0,
13+
);
14+
function my_dump($var) {
15+
}
16+
foreach($a as $b) {
17+
for ($i = 0; $i < 3; $i++) {
18+
my_dump($b[$i]);
19+
}
20+
}
21+
?>
22+
--EXPECTF--
23+
Warning: Trying to access array offset on int in %s on line %d
24+
25+
Warning: Trying to access array offset on int in %s on line %d
26+
27+
Warning: Trying to access array offset on int in %s on line %d

0 commit comments

Comments
 (0)