Skip to content

Commit 34d8bef

Browse files
committed
Fix GH-17747: Exception on reading property in register-based FETCH_OBJ_R breaks JIT
When read_property fails, it may return `&EG(uninitialized_zval)`, and the exception is handled in the VM. The VM will try to `zval_ptr_dtor_nogc` the result, but the result was never set, resulting in dtor'ing garbage data. To solve this, we check when a different zval* was returned and initialize the result with UNDEF. We don't need to copy as the slow_ex handler return values are used directly in a register. Closes GH-17749.
1 parent 0e0d2d2 commit 34d8bef

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ PHP NEWS
4242
. Fixed bug GH-17654 (Multiple classes using same trait causes function
4343
JIT crash). (nielsdos)
4444
. Fixed bug GH-17577 (JIT packed type guard crash). (nielsdos, Dmitry)
45+
. Fixed bug GH-17747 (Exception on reading property in register-based
46+
FETCH_OBJ_R breaks JIT). (Dmitry, nielsdos)
4547

4648
- PHPDBG:
4749
. Partially fixed bug GH-17387 (Trivial crash in phpdbg lexer). (nielsdos)

ext/opcache/jit/zend_jit_ir.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14539,7 +14539,11 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
1453914539
}
1454014540

1454114541
if (may_throw) {
14542-
zend_jit_check_exception(jit);
14542+
if (Z_MODE(res_addr) == IS_REG) {
14543+
zend_jit_check_exception_undef_result(jit, opline);
14544+
} else {
14545+
zend_jit_check_exception(jit);
14546+
}
1454314547
}
1454414548

1454514549
return 1;

ext/opcache/tests/jit/gh17747.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-17747 (Exception on reading property in register-based FETCH_OBJ_R breaks JIT)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit=function
7+
--FILE--
8+
<?php
9+
class C {
10+
public int $a;
11+
public function test() {
12+
var_dump($this->a);
13+
}
14+
}
15+
$test = new C;
16+
$test->test();
17+
?>
18+
--EXPECTF--
19+
Fatal error: Uncaught Error: Typed property C::$a must not be accessed before initialization in %s:%d
20+
Stack trace:
21+
#0 %s(%d): C->test()
22+
#1 {main}
23+
thrown in %s on line %d

0 commit comments

Comments
 (0)