From 79aaeeafe5904307ac582efe2aa42f21a4d82a21 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 18 Nov 2024 14:27:08 +0300 Subject: [PATCH 1/3] Fix GH-16829: Segmentation fault with opcache.jit=tracing enabled on aarch64 --- ext/opcache/jit/zend_jit_vm_helpers.c | 10 +++++++++- ext/opcache/tests/jit/gh16829.phpt | 14 ++++++++++++++ ext/opcache/tests/jit/gh16829_1.inc | 16 ++++++++++++++++ ext/opcache/tests/jit/gh16829_2.inc | 23 +++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/gh16829.phpt create mode 100644 ext/opcache/tests/jit/gh16829_1.inc create mode 100644 ext/opcache/tests/jit/gh16829_2.inc diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index e37a0ef3af892..3e9ae93c106c8 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -925,7 +925,15 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array); if (UNEXPECTED(!jit_extension) || UNEXPECTED(!(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE))) { - stop = ZEND_JIT_TRACE_STOP_INTERPRETER; +#ifdef HAVE_GCC_GLOBAL_REGS + if (execute_data->prev_execute_data != prev_execute_data) { +#else + if (rc < 0) { +#endif + stop = ZEND_JIT_TRACE_STOP_RETURN; + } else { + stop = ZEND_JIT_TRACE_STOP_INTERPRETER; + } break; } offset = jit_extension->offset; diff --git a/ext/opcache/tests/jit/gh16829.phpt b/ext/opcache/tests/jit/gh16829.phpt new file mode 100644 index 0000000000000..174a265cedea7 --- /dev/null +++ b/ext/opcache/tests/jit/gh16829.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-16829 (Segmentation fault with opcache.jit=tracing enabled on aarch64) +--INI-- +opcache.jit_buffer_size=32M +--EXTENSIONS-- +opcache +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/gh16829_1.inc b/ext/opcache/tests/jit/gh16829_1.inc new file mode 100644 index 0000000000000..2ba48f414195a --- /dev/null +++ b/ext/opcache/tests/jit/gh16829_1.inc @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/ext/opcache/tests/jit/gh16829_2.inc b/ext/opcache/tests/jit/gh16829_2.inc new file mode 100644 index 0000000000000..8fddb035431ba --- /dev/null +++ b/ext/opcache/tests/jit/gh16829_2.inc @@ -0,0 +1,23 @@ + \ No newline at end of file From 71403558d35dba50ee4d6699da99ae6d9b945c05 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 18 Nov 2024 15:34:55 +0300 Subject: [PATCH 2/3] Fixed test --- ext/opcache/tests/jit/gh16829.phpt | 4 ++-- ext/opcache/tests/jit/gh16829_1.inc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/opcache/tests/jit/gh16829.phpt b/ext/opcache/tests/jit/gh16829.phpt index 174a265cedea7..d8bee06c90fcf 100644 --- a/ext/opcache/tests/jit/gh16829.phpt +++ b/ext/opcache/tests/jit/gh16829.phpt @@ -6,8 +6,8 @@ opcache.jit_buffer_size=32M opcache --FILE-- DONE --EXPECT-- diff --git a/ext/opcache/tests/jit/gh16829_1.inc b/ext/opcache/tests/jit/gh16829_1.inc index 2ba48f414195a..cc4411d827b75 100644 --- a/ext/opcache/tests/jit/gh16829_1.inc +++ b/ext/opcache/tests/jit/gh16829_1.inc @@ -1,6 +1,6 @@ Date: Thu, 14 Nov 2024 22:32:05 +0100 Subject: [PATCH 3/3] Fix get_object_vars() for non-hooked props in hooked prop iter The zend_hash_update_ind() variant unwraps indirects, rather than creating them. Don't use _zend_hash_append_ind() because the property might already exist. Fixes GH-16725 Closes GH-16805 --- NEWS | 2 ++ Zend/tests/gh16725.phpt | 27 +++++++++++++++++++++++++++ Zend/zend_property_hooks.c | 3 ++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/gh16725.phpt diff --git a/NEWS b/NEWS index 8cbaf1d7546fd..a457fe05e444a 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ PHP NEWS - Core: . Fail early in *nix configuration build script. (hakre) + . Fixed bug GH-16725 (Incorrect access check for non-hooked props in hooked + object iterator). (ilutov) - Curl: . Fixed bug GH-16723 (CURLMOPT_PUSHFUNCTION issues). (cmb) diff --git a/Zend/tests/gh16725.phpt b/Zend/tests/gh16725.phpt new file mode 100644 index 0000000000000..e9a2564fc0151 --- /dev/null +++ b/Zend/tests/gh16725.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-16725: Incorrect access check for non-hooked props in hooked object iterator +--FILE-- + 'bar'; } + + public function __construct( + private string $prop2, + ) {} + + public function jsonSerialize(): mixed { + return get_object_vars($this); + } +} + +$obj = new C('foo'); +var_dump(get_object_vars($obj)); +echo json_encode($obj); + +?> +--EXPECT-- +array(0) { +} +{"prop1":"bar","prop2":"foo"} diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c index 0286bc0c4486f..82ddf2f8835a0 100644 --- a/Zend/zend_property_hooks.c +++ b/Zend/zend_property_hooks.c @@ -89,7 +89,8 @@ static zend_array *zho_build_properties_ex(zend_object *zobj, bool check_access, if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) { HT_FLAGS(properties) |= HASH_FLAG_HAS_EMPTY_IND; } - zend_hash_update_ind(properties, property_name, OBJ_PROP(zobj, prop_info->offset)); + zval *tmp = zend_hash_lookup(properties, property_name); + ZVAL_INDIRECT(tmp, OBJ_PROP(zobj, prop_info->offset)); } skip_property: if (property_name != prop_info->name) {