Skip to content

Commit 3664f4a

Browse files
committed
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fix phpGH-14082: Segmentation fault on unknown address 0x600000000018 in ext/opcache/jit/zend_jit.c
2 parents 56c4ddf + 1e3d92f commit 3664f4a

File tree

4 files changed

+81
-0
lines changed

4 files changed

+81
-0
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ PHP NEWS
2626
(nielsdos)
2727
. Fixed bug GH-18899 (JIT function crash when emitting undefined variable
2828
warning and opline is not set yet). (nielsdos)
29+
. Fixed bug GH-14082 (Segmentation fault on unknown address 0x600000000018
30+
in ext/opcache/jit/zend_jit.c). (nielsdos)
2931

3032
- Standard:
3133
. Fix misleading errors in printf(). (nielsdos)

ext/opcache/ZendAccelerator.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656

5757
#ifdef HAVE_JIT
5858
# include "jit/zend_jit.h"
59+
# include "Optimizer/zend_func_info.h"
60+
# include "Optimizer/zend_call_graph.h"
5961
#endif
6062

6163
#ifndef ZEND_WIN32
@@ -4471,6 +4473,39 @@ static void preload_load(size_t orig_map_ptr_static_last)
44714473
}
44724474
}
44734475

4476+
#if HAVE_JIT
4477+
static void zend_accel_clear_call_graph_ptrs(zend_op_array *op_array)
4478+
{
4479+
ZEND_ASSERT(ZEND_USER_CODE(op_array->type));
4480+
zend_func_info *info = ZEND_FUNC_INFO(op_array);
4481+
if (info) {
4482+
info->caller_info = NULL;
4483+
info->callee_info = NULL;
4484+
}
4485+
}
4486+
4487+
static void accel_reset_arena_info(zend_persistent_script *script)
4488+
{
4489+
zend_op_array *op_array;
4490+
zend_class_entry *ce;
4491+
4492+
zend_accel_clear_call_graph_ptrs(&script->script.main_op_array);
4493+
ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) {
4494+
zend_accel_clear_call_graph_ptrs(op_array);
4495+
} ZEND_HASH_FOREACH_END();
4496+
ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) {
4497+
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
4498+
if (op_array->scope == ce
4499+
&& op_array->type == ZEND_USER_FUNCTION
4500+
&& !(op_array->fn_flags & ZEND_ACC_ABSTRACT)
4501+
&& !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
4502+
zend_accel_clear_call_graph_ptrs(op_array);
4503+
}
4504+
} ZEND_HASH_FOREACH_END();
4505+
} ZEND_HASH_FOREACH_END();
4506+
}
4507+
#endif
4508+
44744509
static zend_result accel_preload(const char *config, bool in_child)
44754510
{
44764511
zend_file_handle file_handle;
@@ -4683,6 +4718,18 @@ static zend_result accel_preload(const char *config, bool in_child)
46834718
} ZEND_HASH_FOREACH_END();
46844719
ZCSG(saved_scripts)[i] = NULL;
46854720

4721+
#if HAVE_JIT
4722+
/* During persisting, the JIT may trigger and fill in the call graph.
4723+
* The call graph info is allocated on the arena which will be gone after preloading.
4724+
* To prevent invalid accesses during normal requests, the arena data should be cleared.
4725+
* This has to be done after all scripts have been persisted because shared op arrays between
4726+
* scripts can change the call graph. */
4727+
accel_reset_arena_info(ZCSG(preload_script));
4728+
for (zend_persistent_script **scripts = ZCSG(saved_scripts); *scripts; scripts++) {
4729+
accel_reset_arena_info(*scripts);
4730+
}
4731+
#endif
4732+
46864733
zend_shared_alloc_save_state();
46874734
accel_interned_strings_save_state();
46884735

ext/opcache/tests/jit/gh14082.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-14082 (Segmentation fault on unknown address 0x600000000018 in ext/opcache/jit/zend_jit.c)
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}/preload_gh14082.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+
Foo::test();
18+
echo "ok\n";
19+
?>
20+
--EXPECT--
21+
int(1)
22+
int(1)
23+
ok
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
class Foo {
3+
public static function test() {
4+
static $i = 0;
5+
var_dump(++$i);
6+
}
7+
}
8+
9+
Foo::test();

0 commit comments

Comments
 (0)