From c3ab6bd09164bd17f9dab09da47a045247210e34 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 20 Nov 2007 09:51:12 +0000 Subject: [PATCH] Fixed bug #43136 (possible crash on script execution timeout. The EG(function_state_ptr) is completely removed, EG(current_execute_data)->function_state must be used instead) --- NEWS | 3 +++ Zend/zend_API.c | 6 +++--- Zend/zend_execute.c | 1 + Zend/zend_execute_API.c | 17 +++++------------ Zend/zend_globals.h | 1 - Zend/zend_object_handlers.c | 4 ++-- Zend/zend_vm_def.h | 4 ---- Zend/zend_vm_execute.h | 10 +--------- Zend/zend_vm_execute.skl | 3 +-- ext/com_dotnet/com_com.c | 2 +- ext/com_dotnet/com_handlers.c | 2 +- ext/spl/php_spl.c | 3 --- 12 files changed, 18 insertions(+), 38 deletions(-) diff --git a/NEWS b/NEWS index 2e5fa50bc54..35a4ab7ec3e 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,9 @@ PHP NEWS - Fixed possible crash in ext/soap because of uninitialized value. (Zdash Urf) +- Fixed bug #43136 (possible crash on script execution timeout. + The EG(function_state_ptr) is completely removed, + EG(current_execute_data)->function_state must be used instead). (Dmitry) - Fixed bug #42848 (Status: header incorrect under FastCGI). (Dmitry) - Fixed bug #42773 (WSDL error causes HTTP 500 Response). (Dmitry) - Fixed bug #42737 (preg_split('//u') triggers a E_NOTICE with newlines). (Nuno) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 68bbfee8d3c..fbf73e8e760 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -689,7 +689,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl case '+': if (have_varargs) { if (!quiet) { - zend_function *active_function = EG(function_state_ptr)->function; + zend_function *active_function = EG(current_execute_data)->function_state.function; char *class_name = active_function->common.scope ? active_function->common.scope->name : ""; zend_error(E_WARNING, "%s%s%s(): only one varargs specifier (* or +) is permitted", class_name, @@ -709,7 +709,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl default: if (!quiet) { - zend_function *active_function = EG(function_state_ptr)->function; + zend_function *active_function = EG(current_execute_data)->function_state.function; char *class_name = active_function->common.scope ? active_function->common.scope->name : ""; zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters", class_name, @@ -732,7 +732,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) { if (!quiet) { - zend_function *active_function = EG(function_state_ptr)->function; + zend_function *active_function = EG(current_execute_data)->function_state.function; char *class_name = active_function->common.scope ? active_function->common.scope->name : ""; zend_error(E_WARNING, "%s%s%s() expects %s %d parameter%s, %d given", class_name, diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 2150e733147..7d0d3c2c890 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1425,6 +1425,7 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v } \ EG(in_execution) = EX(original_in_execution); \ EG(current_execute_data) = EX(prev_execute_data); \ + EG(opline_ptr) = NULL; \ ZEND_VM_RETURN() #include "zend_vm_execute.h" diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f5b984f5e78..c3169c430ad 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -340,11 +340,11 @@ ZEND_API char *get_active_class_name(char **space TSRMLS_DC) /* {{{ */ } return ""; } - switch (EG(function_state_ptr)->function->type) { + switch (EG(current_execute_data)->function_state.function->type) { case ZEND_USER_FUNCTION: case ZEND_INTERNAL_FUNCTION: { - zend_class_entry *ce = EG(function_state_ptr)->function->common.scope; + zend_class_entry *ce = EG(current_execute_data)->function_state.function->common.scope; if (space) { *space = ce ? "::" : ""; @@ -365,9 +365,9 @@ ZEND_API char *get_active_function_name(TSRMLS_D) /* {{{ */ if (!zend_is_executing(TSRMLS_C)) { return NULL; } - switch (EG(function_state_ptr)->function->type) { + switch (EG(current_execute_data)->function_state.function->type) { case ZEND_USER_FUNCTION: { - char *function_name = ((zend_op_array *) EG(function_state_ptr)->function)->function_name; + char *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name; if (function_name) { return function_name; @@ -377,7 +377,7 @@ ZEND_API char *get_active_function_name(TSRMLS_D) /* {{{ */ } break; case ZEND_INTERNAL_FUNCTION: - return ((zend_internal_function *) EG(function_state_ptr)->function)->function_name; + return ((zend_internal_function *) EG(current_execute_data)->function_state.function)->function_name; break; default: return NULL; @@ -625,7 +625,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_uint i; zval **original_return_value; HashTable *calling_symbol_table; - zend_function_state *original_function_state_ptr; zend_op_array *original_op_array; zend_op **original_opline_ptr; zend_class_entry *current_scope; @@ -969,9 +968,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_ptr_stack_2_push(&EG(argument_stack), (void *) (zend_uintptr_t) fci->param_count, NULL); - original_function_state_ptr = EG(function_state_ptr); - EG(function_state_ptr) = &EX(function_state); - current_scope = EG(scope); EG(scope) = calling_scope; @@ -1060,7 +1056,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zval_ptr_dtor(&method_name); zval_ptr_dtor(¶ms_array); } - EG(function_state_ptr) = original_function_state_ptr; if (EG(This)) { zval_ptr_dtor(&EG(This)); @@ -1193,7 +1188,6 @@ ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSR zval pv; zend_op_array *new_op_array; zend_op_array *original_active_op_array = EG(active_op_array); - zend_function_state *original_function_state_ptr = EG(function_state_ptr); zend_uchar original_handle_op_arrays; int retval; @@ -1245,7 +1239,6 @@ ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSR EG(no_extensions)=0; EG(opline_ptr) = original_opline_ptr; EG(active_op_array) = original_active_op_array; - EG(function_state_ptr) = original_function_state_ptr; destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); EG(return_value_ptr_ptr) = original_return_value_ptr_ptr; diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 47c684522e3..3fb08d0649b 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -162,7 +162,6 @@ struct _zend_executor_globals { zval error_zval; zval *error_zval_ptr; - zend_function_state *function_state_ptr; zend_ptr_stack arg_types_stack; /* symbol table cache */ diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index c1aae7249c3..017f3df635a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -647,7 +647,7 @@ static void zend_std_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { - zend_internal_function *func = (zend_internal_function *)EG(function_state_ptr)->function; + zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->function_state.function; zval *method_name_ptr, *method_args_ptr; zval *method_result_ptr = NULL; zend_class_entry *ce = Z_OBJCE_P(this_ptr); @@ -845,7 +845,7 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { - zend_internal_function *func = (zend_internal_function *)EG(function_state_ptr)->function; + zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->function_state.function; zval *method_name_ptr, *method_args_ptr; zval *method_result_ptr = NULL; zend_class_entry *ce = EG(scope); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 42f550430eb..7c20026c427 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2013,8 +2013,6 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) zend_execute_internal(EXECUTE_DATA, return_value_used TSRMLS_CC); } - EG(current_execute_data) = EXECUTE_DATA; - /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) { @@ -2093,7 +2091,6 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) } EX(function_state).function = (zend_function *) EX(op_array); - EG(function_state_ptr) = &EX(function_state); if (EG(This)) { if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) { @@ -3011,7 +3008,6 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); - EG(function_state_ptr) = &EX(function_state); destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); if (EG(exception)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d4782320b3f..a192406782a 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -75,7 +75,6 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) EG(opline_ptr) = &EX(opline); EX(function_state).function = (zend_function *) op_array; - EG(function_state_ptr) = &EX(function_state); while (1) { #ifdef ZEND_WIN32 @@ -85,7 +84,7 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) #endif if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) { - return; + return; } } @@ -196,8 +195,6 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) zend_execute_internal(execute_data, return_value_used TSRMLS_CC); } - EG(current_execute_data) = execute_data; - /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) { @@ -276,7 +273,6 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) } EX(function_state).function = (zend_function *) EX(op_array); - EG(function_state_ptr) = &EX(function_state); if (EG(This)) { if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) { @@ -1814,7 +1810,6 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); - EG(function_state_ptr) = &EX(function_state); destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); if (EG(exception)) { @@ -4893,7 +4888,6 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); - EG(function_state_ptr) = &EX(function_state); destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); if (EG(exception)) { @@ -8051,7 +8045,6 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); - EG(function_state_ptr) = &EX(function_state); destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); if (EG(exception)) { @@ -20980,7 +20973,6 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); - EG(function_state_ptr) = &EX(function_state); destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); if (EG(exception)) { diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl index 5fe8d9e6c83..1f6116b08a0 100644 --- a/Zend/zend_vm_execute.skl +++ b/Zend/zend_vm_execute.skl @@ -46,7 +46,6 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC) EG(opline_ptr) = &EX(opline); EX(function_state).function = (zend_function *) op_array; - EG(function_state_ptr) = &EX(function_state); while (1) { {%ZEND_VM_CONTINUE_LABEL%} @@ -57,7 +56,7 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC) #endif {%ZEND_VM_DISPATCH%} { - {%INTERNAL_EXECUTOR%} + {%INTERNAL_EXECUTOR%} } } diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index 60bccd96bba..cf6cf8d2831 100644 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -469,7 +469,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, HRESULT hr; VARIANT *vargs = NULL, *byref_vals = NULL; int i, byref_count = 0, j; - zend_internal_function *f = (zend_internal_function*)EG(function_state_ptr)->function; + zend_internal_function *f = (zend_internal_function*)EG(current_execute_data)->function_state.function; /* assumption: that the active function (f) is the function we generated for the engine */ if (!f || f->arg_info == NULL) { diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index 113e8b02f45..3bb57569776 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -255,7 +255,7 @@ static void function_dtor(void *pDest) static PHP_FUNCTION(com_method_handler) { Z_OBJ_HANDLER_P(getThis(), call_method)( - ((zend_internal_function*)EG(function_state_ptr)->function)->function_name, + ((zend_internal_function*)EG(current_execute_data)->function_state.function)->function_name, INTERNAL_FUNCTION_PARAM_PASSTHRU); } diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index b4cd28144ba..a9e6c96c5d9 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -267,7 +267,6 @@ PHP_FUNCTION(spl_autoload) zval **original_return_value = EG(return_value_ptr_ptr); zend_op **original_opline_ptr = EG(opline_ptr); zend_op_array *original_active_op_array = EG(active_op_array); - zend_function_state *original_function_state_ptr = EG(function_state_ptr); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &class_name, &class_name_len, &file_exts, &file_exts_len) == FAILURE) { RETURN_FALSE; @@ -283,7 +282,6 @@ PHP_FUNCTION(spl_autoload) EG(return_value_ptr_ptr) = original_return_value; EG(opline_ptr) = original_opline_ptr; EG(active_op_array) = original_active_op_array; - EG(function_state_ptr) = original_function_state_ptr; pos2 = strchr(pos1, ','); if (pos2) *pos2 = '\0'; if (spl_autoload(class_name, lc_name, class_name_len, pos1 TSRMLS_CC)) { @@ -300,7 +298,6 @@ PHP_FUNCTION(spl_autoload) EG(return_value_ptr_ptr) = original_return_value; EG(opline_ptr) = original_opline_ptr; EG(active_op_array) = original_active_op_array; - EG(function_state_ptr) = original_function_state_ptr; if (!found && !SPL_G(autoload_running)) { /* For internal errors, we generate E_ERROR, for direct calls an exception is thrown.