[php-src] Issue #24398: JIT: segfault with opcache.jit=1201 when a hooked property is passed to a run-time-resolved function
| From: | waroad | Date: | Sun, 18 Oct 2026 06:45:04 +0000 |
| Subject: | [php-src] Issue #24398: JIT: segfault with opcache.jit=1201 when a hooked property is passed to a run-time-resolved function | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-253019@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/24398
Author: waroad
With the function JIT at level 1 (
opcache.jit=1201), passing a property with a
get hook as an argument to a function that is only known at run time (declared inside
an if, or a global function called unqualified from a namespace) crashes on the second
call.
```php
<?php
class Hook { public $p { get => 5; } }
if (true) { function take($x) { return $x; } }
function f($o) { return take($o->p); }
$h = new Hook;
f($h);
f($h);
```
```
php -n -d opcache.enable_cli=1 -d opcache.file_update_protection=0 -d opcache.jit_buffer_size=64M -d
opcache.jit=1201 red.php
```
On a UBSan build:
```
Zend/zend_vm_execute.h:30099:7: runtime error: applying non-zero offset 18446744073709551615 to null
pointer
#0 0x55637faec8c4 in ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER Zend/zend_vm_execute.h:30099
```
I expected no output, which is what opcache.jit=disable gives for the same script.
It reproduces at 17b6575a3dc4 (the latest upstream I checked): the UBSan build reports the error
above, the release build segfaults (exit 139, signal 11). It only happens at JIT optimization level
1: 1201, 1211, 1101 and 1251 crash; 1202, 1205, 1254 and tracing do not.
Looks like zend_jit() in ext/opcache/jit/zend_jit.c: for the level-1 path only
ZEND_FETCH_OBJ_R checks whether the VM handler entered a simple hook frame, while
ZEND_FETCH_OBJ_FUNC_ARG goes through the plain zend_jit_handler path and
the JIT code continues with the next opline (SEND_FUNC_ARG). This looks like the
level-1 counterpart of GH-21006 / GH-22857.
I can send a patch if that helps.
Found with an LLM-based testing tool; I used Claude to reduce it and look for the cause.