Skip to content

Commit 4a98b36

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-18898: SEGV zend_jit_op_array_hot with property hooks and preloading
2 parents f6f0aed + 53f2aa9 commit 4a98b36

File tree

4 files changed

+131
-29
lines changed

4 files changed

+131
-29
lines changed

‎ext/opcache/jit/zend_jit.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,6 +3363,17 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
33633363
return FAILURE;
33643364
}
33653365

3366+
static void zend_jit_link_func_info(zend_op_array *op_array)
3367+
{
3368+
if (!ZEND_FUNC_INFO(op_array)) {
3369+
void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes);
3370+
3371+
if (jit_extension) {
3372+
ZEND_SET_FUNC_INFO(op_array, jit_extension);
3373+
}
3374+
}
3375+
}
3376+
33663377
int zend_jit_script(zend_script *script)
33673378
{
33683379
void *checkpoint;
@@ -3450,6 +3461,7 @@ int zend_jit_script(zend_script *script)
34503461
zend_class_entry *ce;
34513462
zend_op_array *op_array;
34523463
zval *zv;
3464+
zend_property_info *prop;
34533465

34543466
ZEND_HASH_MAP_FOREACH_VAL(&script->class_table, zv) {
34553467
if (Z_TYPE_P(zv) == IS_ALIAS_PTR) {
@@ -3460,14 +3472,21 @@ int zend_jit_script(zend_script *script)
34603472
ZEND_ASSERT(ce->type == ZEND_USER_CLASS);
34613473

34623474
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
3463-
if (!ZEND_FUNC_INFO(op_array)) {
3464-
void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes);
3475+
zend_jit_link_func_info(op_array);
3476+
} ZEND_HASH_FOREACH_END();
34653477

3466-
if (jit_extension) {
3467-
ZEND_SET_FUNC_INFO(op_array, jit_extension);
3478+
if (ce->num_hooked_props > 0) {
3479+
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
3480+
if (prop->hooks) {
3481+
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
3482+
if (prop->hooks[i]) {
3483+
op_array = &prop->hooks[i]->op_array;
3484+
zend_jit_link_func_info(op_array);
3485+
}
3486+
}
34683487
}
3469-
}
3470-
} ZEND_HASH_FOREACH_END();
3488+
} ZEND_HASH_FOREACH_END();
3489+
}
34713490
} ZEND_HASH_FOREACH_END();
34723491
}
34733492

‎ext/opcache/tests/jit/gh18898_1.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-18898 (SEGV zend_jit_op_array_hot with property hooks and preloading) - jit 1235
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.jit=1235
7+
opcache.jit_buffer_size=16M
8+
opcache.preload={PWD}/../gh18534_preload.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+
$test = new DummyModel;
18+
var_dump($test->dummyProperty2);
19+
echo "ok";
20+
?>
21+
--EXPECT--
22+
NULL
23+
ok

‎ext/opcache/tests/jit/gh18898_2.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-18898 (SEGV zend_jit_op_array_hot with property hooks and preloading) - jit 1233
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.jit=1233
7+
opcache.jit_buffer_size=16M
8+
opcache.preload={PWD}/../gh18534_preload.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+
$test = new DummyModel;
18+
var_dump($test->dummyProperty2);
19+
echo "ok";
20+
?>
21+
--EXPECT--
22+
NULL
23+
ok

‎ext/opcache/zend_persist.c

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,39 @@ void zend_update_parent_ce(zend_class_entry *ce)
12831283
}
12841284
}
12851285

1286+
static void zend_accel_persist_jit_op_array(zend_op_array *op_array, zend_class_entry *ce)
1287+
{
1288+
if (op_array->type == ZEND_USER_FUNCTION) {
1289+
if (op_array->scope == ce
1290+
&& !(op_array->fn_flags & ZEND_ACC_ABSTRACT)
1291+
&& !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
1292+
zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
1293+
for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) {
1294+
zend_jit_op_array(op_array->dynamic_func_defs[i], ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
1295+
}
1296+
}
1297+
}
1298+
}
1299+
1300+
static void zend_accel_persist_link_func_info(zend_op_array *op_array, zend_class_entry *ce)
1301+
{
1302+
if (op_array->type == ZEND_USER_FUNCTION
1303+
&& !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) {
1304+
if ((op_array->scope != ce
1305+
|| (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE))
1306+
&& (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC
1307+
|| JIT_G(trigger) == ZEND_JIT_ON_PROF_REQUEST
1308+
|| JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS
1309+
|| JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE)) {
1310+
void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes);
1311+
1312+
if (jit_extension) {
1313+
ZEND_SET_FUNC_INFO(op_array, jit_extension);
1314+
}
1315+
}
1316+
}
1317+
}
1318+
12861319
static void zend_accel_persist_class_table(HashTable *class_table)
12871320
{
12881321
Bucket *p;
@@ -1309,44 +1342,48 @@ static void zend_accel_persist_class_table(HashTable *class_table)
13091342
if (JIT_G(on) && JIT_G(opt_level) <= ZEND_JIT_LEVEL_OPT_FUNCS &&
13101343
!ZCG(current_persistent_script)->corrupted) {
13111344
zend_op_array *op_array;
1345+
zend_property_info *prop;
13121346

13131347
ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) {
13141348
if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) {
13151349
ce = Z_PTR(p->val);
13161350
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
1317-
if (op_array->type == ZEND_USER_FUNCTION) {
1318-
if (op_array->scope == ce
1319-
&& !(op_array->fn_flags & ZEND_ACC_ABSTRACT)
1320-
&& !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
1321-
zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
1322-
for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) {
1323-
zend_jit_op_array(op_array->dynamic_func_defs[i], ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
1351+
zend_accel_persist_jit_op_array(op_array, ce);
1352+
} ZEND_HASH_FOREACH_END();
1353+
1354+
if (ce->num_hooked_props > 0) {
1355+
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
1356+
if (prop->hooks) {
1357+
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
1358+
if (prop->hooks[i]) {
1359+
op_array = &prop->hooks[i]->op_array;
1360+
zend_accel_persist_jit_op_array(op_array, ce);
1361+
}
13241362
}
13251363
}
1326-
}
1327-
} ZEND_HASH_FOREACH_END();
1364+
} ZEND_HASH_FOREACH_END();
1365+
}
13281366
}
13291367
} ZEND_HASH_FOREACH_END();
13301368
ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) {
13311369
if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) {
13321370
ce = Z_PTR(p->val);
13331371
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
1334-
if (op_array->type == ZEND_USER_FUNCTION
1335-
&& !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) {
1336-
if ((op_array->scope != ce
1337-
|| (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE))
1338-
&& (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC
1339-
|| JIT_G(trigger) == ZEND_JIT_ON_PROF_REQUEST
1340-
|| JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS
1341-
|| JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE)) {
1342-
void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes);
1343-
1344-
if (jit_extension) {
1345-
ZEND_SET_FUNC_INFO(op_array, jit_extension);
1372+
zend_accel_persist_link_func_info(op_array, ce);
1373+
} ZEND_HASH_FOREACH_END();
1374+
1375+
if (ce->num_hooked_props > 0) {
1376+
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
1377+
if (prop->hooks) {
1378+
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
1379+
if (prop->hooks[i]) {
1380+
op_array = &prop->hooks[i]->op_array;
1381+
zend_accel_persist_link_func_info(op_array, ce);
1382+
}
13461383
}
13471384
}
1348-
}
1349-
} ZEND_HASH_FOREACH_END();
1385+
} ZEND_HASH_FOREACH_END();
1386+
}
13501387
}
13511388
} ZEND_HASH_FOREACH_END();
13521389
}

0 commit comments

Comments
 (0)