Skip to content

Commit f7b7472

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 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.
1 parent 2e02cdf commit f7b7472

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4162,12 +4162,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
41624162
}
41634163

41644164
if ((info & MAY_BE_PACKED_GUARD) != 0
4165+
&& (info & MAY_BE_GUARD) == 0
41654166
&& (trace_buffer->stop == ZEND_JIT_TRACE_STOP_LOOP
41664167
|| trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL
41674168
|| trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET)
41684169
&& (ssa->vars[i].use_chain != -1
41694170
|| (ssa->vars[i].phi_use_chain
41704171
&& !(ssa->var_info[ssa->vars[i].phi_use_chain->ssa_var].type & MAY_BE_PACKED_GUARD)))) {
4172+
ZEND_ASSERT(STACK_TYPE(stack, i) == IS_ARRAY);
4173+
41714174
if (!zend_jit_packed_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), info)) {
41724175
goto jit_failure;
41734176
}

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)