From 1f4159e504133b9c5499f090cc44ec4aa62dec53 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:17:11 +0200 Subject: [PATCH 1/3] [ci skip] NEWS Entry for 90f2e7607a. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index b56c9d8fb55..6d12cf0335d 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Opcache: . Added warning when JIT cannot be enabled. (danog) + . Fixed bug GH-8143 (Crashes in zend_accel_inheritance_cache_find since + upgrading to 8.1.3 due to corrupt on-disk file cache). (turchanov) 26 Oct 2023, PHP 8.1.25 From 71f14510f6643f9c0ba4dbb518a8ea75d093bc18 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Mon, 9 Oct 2023 11:46:55 +0300 Subject: [PATCH 2/3] Fix GH-11121: ReflectionFiber segfault Closes GH-12391. Co-authored-by: Aaron Piotrowski --- NEWS | 3 + Zend/zend_fibers.c | 6 +- .../tests/ReflectionFiber_bug_gh11121_1.phpt | 62 ++++++++++++++++++ .../tests/ReflectionFiber_bug_gh11121_2.phpt | 63 +++++++++++++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 ext/reflection/tests/ReflectionFiber_bug_gh11121_1.phpt create mode 100644 ext/reflection/tests/ReflectionFiber_bug_gh11121_2.phpt diff --git a/NEWS b/NEWS index 6d12cf0335d..b5c21e37a67 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.1.26 +- Fiber: + . Fixed bug GH-11121 (ReflectionFiber segfault). (danog, trowski, bwoebi) + - Opcache: . Added warning when JIT cannot be enabled. (danog) . Fixed bug GH-8143 (Crashes in zend_accel_inheritance_cache_find since diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index 59aa63ba21b..c80d65868d3 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -554,6 +554,10 @@ static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fibe { zend_fiber *previous = EG(active_fiber); + if (previous) { + previous->execute_data = EG(current_execute_data); + } + fiber->caller = EG(current_fiber_context); EG(active_fiber) = fiber; @@ -571,6 +575,7 @@ static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fib zend_fiber_context *caller = fiber->caller; fiber->previous = EG(current_fiber_context); fiber->caller = NULL; + fiber->execute_data = EG(current_execute_data); return zend_fiber_switch_to(caller, value, false); } @@ -741,7 +746,6 @@ ZEND_METHOD(Fiber, suspend) ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_RUNNING || fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED); - fiber->execute_data = EG(current_execute_data); fiber->stack_bottom->prev_execute_data = NULL; zend_fiber_transfer transfer = zend_fiber_suspend(fiber, value); diff --git a/ext/reflection/tests/ReflectionFiber_bug_gh11121_1.phpt b/ext/reflection/tests/ReflectionFiber_bug_gh11121_1.phpt new file mode 100644 index 00000000000..de0c9abec9e --- /dev/null +++ b/ext/reflection/tests/ReflectionFiber_bug_gh11121_1.phpt @@ -0,0 +1,62 @@ +--TEST-- +GH-11121: Segfault when using ReflectionFiber +--FILE-- +getTrace()); + }))->start(); +} + +$f = new Fiber(function() { f(); max(...[1,2,3,4,5,6,7,8,9,10,11,12]); g(); }); +$f->start(); +$f->resume(); + +?> +--EXPECTF-- +array(3) { + [0]=> + array(7) { + ["file"]=> + string(%d) "%sReflectionFiber_bug_gh11121_1.php" + ["line"]=> + int(10) + ["function"]=> + string(5) "start" + ["class"]=> + string(5) "Fiber" + ["object"]=> + object(Fiber)#3 (0) { + } + ["type"]=> + string(2) "->" + ["args"]=> + array(0) { + } + } + [1]=> + array(4) { + ["file"]=> + string(%d) "%sReflectionFiber_bug_gh11121_1.php" + ["line"]=> + int(13) + ["function"]=> + string(1) "g" + ["args"]=> + array(0) { + } + } + [2]=> + array(2) { + ["function"]=> + string(9) "{closure}" + ["args"]=> + array(0) { + } + } +} diff --git a/ext/reflection/tests/ReflectionFiber_bug_gh11121_2.phpt b/ext/reflection/tests/ReflectionFiber_bug_gh11121_2.phpt new file mode 100644 index 00000000000..b7affb2ca0b --- /dev/null +++ b/ext/reflection/tests/ReflectionFiber_bug_gh11121_2.phpt @@ -0,0 +1,63 @@ +--TEST-- +GH-11121: Segfault when using ReflectionFiber +--FILE-- +getTrace()); + }))->start(); +} + +$f = new Fiber(function() { f(); g(); }); +$f->start(); +$f->resume(); + +?> +--EXPECTF-- +array(3) { + [0]=> + array(7) { + ["file"]=> + string(%d) "%sReflectionFiber_bug_gh11121_2.php" + ["line"]=> + int(11) + ["function"]=> + string(5) "start" + ["class"]=> + string(5) "Fiber" + ["object"]=> + object(Fiber)#3 (0) { + } + ["type"]=> + string(2) "->" + ["args"]=> + array(0) { + } + } + [1]=> + array(4) { + ["file"]=> + string(%d) "%sReflectionFiber_bug_gh11121_2.php" + ["line"]=> + int(14) + ["function"]=> + string(1) "g" + ["args"]=> + array(0) { + } + } + [2]=> + array(2) { + ["function"]=> + string(9) "{closure}" + ["args"]=> + array(0) { + } + } +} From 7e4a3236d92bc4bcad9ad6661d96f3da92d9c4d3 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 11 Oct 2023 00:11:16 +0200 Subject: [PATCH 3/3] Fix GH-12392: Segmentation fault on SoapClient::__getTypes There are two issues: - UAF because the hashmap resized while being iterated over, yet the local variables used internally in the macros are not updated. - The hashmap being iterated over is modified: entries are deleted after other entries have been added. This causes the deletion to fail sometimes because indices of buckets have shifted. Fix it by using a while loop iteration and HashPosition position tracker instead. Issue exists on PHP 8.1 too, but is much harder to trigger. The test file reproduces the issue reliably on PHP 8.2 and up. Closes GH-12409. --- NEWS | 4 +++ ext/soap/php_schema.c | 18 +++++++---- ext/soap/tests/gh12392.phpt | 28 +++++++++++++++++ ext/soap/tests/gh12392.wsdl | 61 +++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 ext/soap/tests/gh12392.phpt create mode 100644 ext/soap/tests/gh12392.wsdl diff --git a/NEWS b/NEWS index b5c21e37a67..0ba555c819b 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ PHP NEWS . Fixed bug GH-8143 (Crashes in zend_accel_inheritance_cache_find since upgrading to 8.1.3 due to corrupt on-disk file cache). (turchanov) +- SOAP: + . Fixed bug GH-12392 (Segmentation fault on SoapClient::__getTypes). + (nielsdos) + 26 Oct 2023, PHP 8.1.25 - Core: diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index e93679a55ea..521c5d0f1d9 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -2261,17 +2261,23 @@ static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type) schema_content_model_fixup(ctx, type->model); } if (type->attributes) { - zend_string *str_key; - zend_ulong index; + HashPosition pos; + zend_hash_internal_pointer_reset_ex(type->attributes, &pos); - ZEND_HASH_FOREACH_KEY_PTR(type->attributes, index, str_key, attr) { - if (str_key) { + while ((attr = zend_hash_get_current_data_ptr_ex(type->attributes, &pos)) != NULL) { + zend_string *str_key; + zend_ulong index; + + if (zend_hash_get_current_key_ex(type->attributes, &str_key, &index, &pos) == HASH_KEY_IS_STRING) { schema_attribute_fixup(ctx, attr); + zend_result result = zend_hash_move_forward_ex(type->attributes, &pos); + ZEND_ASSERT(result == SUCCESS); } else { schema_attributegroup_fixup(ctx, attr, type->attributes); - zend_hash_index_del(type->attributes, index); + zend_result result = zend_hash_index_del(type->attributes, index); + ZEND_ASSERT(result == SUCCESS); } - } ZEND_HASH_FOREACH_END(); + } } } diff --git a/ext/soap/tests/gh12392.phpt b/ext/soap/tests/gh12392.phpt new file mode 100644 index 00000000000..8a234ba025b --- /dev/null +++ b/ext/soap/tests/gh12392.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-12392 (Segmentation fault on SoapClient::__getTypes) +--EXTENSIONS-- +soap +--FILE-- + WSDL_CACHE_NONE]); +echo 'Client created!' . "\n"; + +$types = $client->__getTypes(); +echo 'Got types!' . "\n"; + +var_dump($types); + +?> +--EXPECT-- +Client created! +Got types! +array(1) { + [0]=> + string(62) "struct dummy { + string foo; + string a; + string b; + string c; +}" +} diff --git a/ext/soap/tests/gh12392.wsdl b/ext/soap/tests/gh12392.wsdl new file mode 100644 index 00000000000..5e9a7ea094f --- /dev/null +++ b/ext/soap/tests/gh12392.wsdl @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +