Skip to content

Commit 8e731ca

Browse files
committed
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. Closes GH-18915.
1 parent 799ec7b commit 8e731ca

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ PHP NEWS
2020
- MbString:
2121
. Fixed bug GH-18901 (integer overflow mb_split). (nielsdos)
2222

23+
- Opcache:
24+
. Fixed bug GH-18639 (Internal class aliases can break preloading + JIT).
25+
(nielsdos)
26+
2327
- Standard:
2428
. Fix misleading errors in printf(). (nielsdos)
2529

ext/opcache/jit/zend_jit.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4628,8 +4628,16 @@ ZEND_EXT_API int zend_jit_script(zend_script *script)
46284628
|| JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
46294629
zend_class_entry *ce;
46304630
zend_op_array *op_array;
4631+
zval *zv;
4632+
4633+
ZEND_HASH_MAP_FOREACH_VAL(&script->class_table, zv) {
4634+
if (Z_TYPE_P(zv) == IS_ALIAS_PTR) {
4635+
continue;
4636+
}
4637+
4638+
ce = Z_PTR_P(zv);
4639+
ZEND_ASSERT(ce->type == ZEND_USER_CLASS);
46314640

4632-
ZEND_HASH_MAP_FOREACH_PTR(&script->class_table, ce) {
46334641
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
46344642
if (!ZEND_FUNC_INFO(op_array)) {
46354643
void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes);

ext/opcache/tests/gh18639.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-18639 (Internal class aliases can break preloading + JIT)
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.jit=1255
7+
opcache.jit_buffer_size=16M
8+
opcache.preload={PWD}/preload_gh18567.inc
9+
--EXTENSIONS--
10+
opcache
11+
--SKIPIF--
12+
<?php
13+
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
14+
?>
15+
--FILE--
16+
<?php
17+
echo "ok\n";
18+
?>
19+
--EXPECT--
20+
ok

0 commit comments

Comments
 (0)