From 2852b94121ca1d892391921c57e8e460fe6d80ff Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:18:55 +0200 Subject: [PATCH] Fix GH-18639: Internal class aliases can break preloading + JIT ZEND_FUNC_INFO() can not be used on internal CE's. If preloading makes a CE that's an alias of an internal class, the invalid access happens when setting the FUNC_INFO. While we could check the class type to be of user code, we can just skip aliases altogether anyway which may be faster. --- ext/opcache/jit/zend_jit.c | 10 +++++++++- ext/opcache/tests/gh18639.phpt | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/gh18639.phpt diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 9adfe1719f626..7caa3387016e7 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -4628,8 +4628,16 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) || JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { zend_class_entry *ce; zend_op_array *op_array; + zval *zv; + + ZEND_HASH_MAP_FOREACH_VAL(&script->class_table, zv) { + if (Z_TYPE_P(zv) == IS_ALIAS_PTR) { + continue; + } + + ce = Z_PTR_P(zv); + ZEND_ASSERT(ce->type == ZEND_USER_CLASS); - ZEND_HASH_MAP_FOREACH_PTR(&script->class_table, ce) { ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (!ZEND_FUNC_INFO(op_array)) { void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); diff --git a/ext/opcache/tests/gh18639.phpt b/ext/opcache/tests/gh18639.phpt new file mode 100644 index 0000000000000..28424032931ab --- /dev/null +++ b/ext/opcache/tests/gh18639.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-18639 (Internal class aliases can break preloading + JIT) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1255 +opcache.jit_buffer_size=16M +opcache.preload={PWD}/preload_gh18567.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- + +--EXPECT-- +ok