Skip to content

Commit fb95f5c

Browse files
committed
Fix GH-17257: SEGV ext/opcache/jit/zend_jit_vm_helpers.c
EX(opline) / opline can be stale if the IP is not stored, like in this case on a trace enter. We always need to make sure that the opline is up to date to make sure we don't use stale data.
1 parent ce322fd commit fb95f5c

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10110,20 +10110,17 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
1011010110
}
1011110111
}
1011210112
} else {
10113-
if (!trace || (trace->op == ZEND_JIT_TRACE_END
10114-
&& trace->stop == ZEND_JIT_TRACE_STOP_INTERPRETER)) {
10115-
ir_ref ip;
10113+
ir_ref ip;
1011610114

10117-
if (zend_accel_in_shm(func->op_array.opcodes)) {
10118-
ip = ir_CONST_ADDR(func->op_array.opcodes);
10119-
} else {
10120-
if (!func_ref) {
10121-
func_ref = ir_LOAD_A(jit_CALL(rx, func));
10122-
}
10123-
ip = ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes)));
10115+
if (zend_accel_in_shm(func->op_array.opcodes)) {
10116+
ip = ir_CONST_ADDR(func->op_array.opcodes);
10117+
} else {
10118+
if (!func_ref) {
10119+
func_ref = ir_LOAD_A(jit_CALL(rx, func));
1012410120
}
10125-
jit_LOAD_IP(jit, ip);
10121+
ip = ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes)));
1012610122
}
10123+
jit_LOAD_IP(jit, ip);
1012710124
if (GCC_GLOBAL_REGS) {
1012810125
ir_CALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_copy_extra_args_helper));
1012910126
} else {

ext/opcache/tests/jit/gh17257.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
GH-17257 (SEGV ext/opcache/jit/zend_jit_vm_helpers.c)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit_buffer_size=32M
7+
opcache.jit=1254
8+
opcache.jit_hot_func=1
9+
--FILE--
10+
<?php
11+
function get_const() {
12+
}
13+
function test() {
14+
call_user_func('get_const', 1); // need an extra arg to trigger the issue
15+
}
16+
function main(){
17+
for ($i = 0; $i < 10; $i++) {
18+
test();
19+
}
20+
echo "Done\n";
21+
}
22+
main();
23+
?>
24+
--EXPECT--
25+
Done

0 commit comments

Comments
 (0)