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 ce817caadaa..4b4b0910e5f 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -313,9 +313,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; } @@ -328,8 +330,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 42ec228fd34..6f6a8263894 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -121,7 +121,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) } zend_object *old_exception; - const zend_op *old_opline_before_exception; + const zend_op *old_opline_before_exception = NULL; if (destructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) { if (EG(current_execute_data)) { @@ -156,14 +156,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; } } @@ -171,8 +172,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 {