From 5518165499498be880ed27b178df4d428c61a951 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 30 Oct 2025 14:04:09 +0100 Subject: [PATCH] Fix EG(current_execute_data) introduced in 1292037 Fixes OSS-Fuzz #456317305 --- Zend/tests/oss_fuzz_456317305.phpt | 25 +++++++++++++++++++++++++ Zend/zend_generators.c | 12 ++++++++---- Zend/zend_objects.c | 21 ++++++++++++--------- 3 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 Zend/tests/oss_fuzz_456317305.phpt diff --git a/Zend/tests/oss_fuzz_456317305.phpt b/Zend/tests/oss_fuzz_456317305.phpt new file mode 100644 index 00000000000..37e7c59e465 --- /dev/null +++ b/Zend/tests/oss_fuzz_456317305.phpt @@ -0,0 +1,25 @@ +--TEST-- +OSS-Fuzz #456317305: EG(current_execute_data) NULL pointer violation +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 [internal function]: C->__destruct() +#1 {main} + thrown in %s on line %d diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 84b40cfdc21..5ba215f788c 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -321,9 +321,11 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ zend_object *old_exception = NULL; const zend_op *old_opline_before_exception = NULL; if (EG(exception)) { - EG(current_execute_data)->opline = EG(opline_before_exception); + if (EG(current_execute_data)) { + EG(current_execute_data)->opline = EG(opline_before_exception); + old_opline_before_exception = EG(opline_before_exception); + } old_exception = EG(exception); - old_opline_before_exception = EG(opline_before_exception); EG(exception) = NULL; } @@ -335,8 +337,10 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ zend_generator_resume(generator); if (old_exception) { - EG(current_execute_data)->opline = EG(exception_op); - EG(opline_before_exception) = old_opline_before_exception; + if (EG(current_execute_data)) { + EG(current_execute_data)->opline = EG(exception_op); + EG(opline_before_exception) = old_opline_before_exception; + } if (EG(exception)) { zend_exception_set_previous(EG(exception), old_exception); } else { diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 30ea22c8de4..8d9bbcc6aa7 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -100,7 +100,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) if (destructor) { zend_object *old_exception; - const zend_op *old_opline_before_exception; + const zend_op *old_opline_before_exception = NULL; if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) { if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) { @@ -159,14 +159,15 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) if (EG(exception) == object) { zend_error_noreturn(E_CORE_ERROR, "Attempt to destruct pending exception"); } else { - if (EG(current_execute_data) - && EG(current_execute_data)->func - && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) { - zend_rethrow_exception(EG(current_execute_data)); + if (EG(current_execute_data)) { + if (EG(current_execute_data)->func + && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) { + zend_rethrow_exception(EG(current_execute_data)); + } + EG(current_execute_data)->opline = EG(opline_before_exception); + old_opline_before_exception = EG(opline_before_exception); } - EG(current_execute_data)->opline = EG(opline_before_exception); old_exception = EG(exception); - old_opline_before_exception = EG(opline_before_exception); EG(exception) = NULL; } } @@ -174,8 +175,10 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) zend_call_known_instance_method_with_0_params(destructor, object, NULL); if (old_exception) { - EG(current_execute_data)->opline = EG(exception_op); - EG(opline_before_exception) = old_opline_before_exception; + if (EG(current_execute_data)) { + EG(current_execute_data)->opline = EG(exception_op); + EG(opline_before_exception) = old_opline_before_exception; + } if (EG(exception)) { zend_exception_set_previous(EG(exception), old_exception); } else {