From 3142dc0b525675616a9c1521053c9d5ddfe71108 Mon Sep 17 00:00:00 2001 From: Stefan Esser Date: Tue, 11 Feb 2014 16:45:02 +0100 Subject: Adapt suhosin to lots of changes in PHP 5.5 executor --- execute.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 95 insertions(+), 22 deletions(-) (limited to 'execute.c') diff --git a/execute.c b/execute.c index 23da839..5371d00 100644 --- a/execute.c +++ b/execute.c @@ -38,6 +38,10 @@ #include "sha256.h" +#if PHP_VERSION_ID >= 50500 +static void (*old_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); +static void suhosin_execute_ex(zend_execute_data *execute_data TSRMLS_DC); +#endif static void (*old_execute)(zend_op_array *op_array TSRMLS_DC); static void suhosin_execute(zend_op_array *op_array TSRMLS_DC); @@ -48,8 +52,13 @@ static void *(*zo_set_oe_ex)(void *ptr) = NULL; /*STATIC zend_op_array* (*old_compile_file)(zend_file_handle* file_handle, int type TSRMLS_DC); STATIC zend_op_array* suhosin_compile_file(zend_file_handle*, int TSRMLS_DC);*/ +#if PHP_VERSION_ID >= 50500 +static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); +static void (*old_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); +#else static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); static void (*old_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); +#endif extern zend_extension suhosin_zend_extension_entry; @@ -355,8 +364,14 @@ static int suhosin_detect_codetype(zend_op_array *op_array TSRMLS_DC) /* {{{ void suhosin_execute_ex(zend_op_array *op_array TSRMLS_DC) * This function provides a hook for execution */ +#if PHP_VERSION_ID > 50500 +static void suhosin_execute_ex(zend_execute_data *execute_data TSRMLS_DC) +{ + zend_op_array *op_array = execute_data->op_array; +#else static void suhosin_execute_ex(zend_op_array *op_array, int zo, long dummy TSRMLS_DC) { +#endif zend_op_array *new_op_array; int op_array_type, len; char *fn; @@ -462,7 +477,7 @@ static void suhosin_execute_ex(zend_op_array *op_array, int zo, long dummy TSRML SUHOSIN_G(execution_depth)++; if (SUHOSIN_G(max_execution_depth) && SUHOSIN_G(execution_depth) > SUHOSIN_G(max_execution_depth)) { - suhosin_log(S_EXECUTOR, "maximum execution depth reached - script terminated"); + suhosin_log(S_EXECUTOR|S_GETCALLER, "maximum execution depth reached - script terminated"); suhosin_bailout(TSRMLS_C); } @@ -509,7 +524,7 @@ not_evaled_code: switch (op_array_type) { case SUHOSIN_CODE_TYPE_EVAL: if (SUHOSIN_G(executor_disable_eval)) { - suhosin_log(S_EXECUTOR, "use of eval is forbidden by configuration"); + suhosin_log(S_EXECUTOR|S_GETCALLER, "use of eval is forbidden by configuration"); if (!SUHOSIN_G(simulation)) { zend_error(E_ERROR, "SUHOSIN - Use of eval is forbidden by configuration"); } @@ -518,7 +533,7 @@ not_evaled_code: case SUHOSIN_CODE_TYPE_REGEXP: if (SUHOSIN_G(executor_disable_emod)) { - suhosin_log(S_EXECUTOR, "use of preg_replace() with /e modifier is forbidden by configuration"); + suhosin_log(S_EXECUTOR|S_GETCALLER, "use of preg_replace() with /e modifier is forbidden by configuration"); if (!SUHOSIN_G(simulation)) { zend_error(E_ERROR, "SUHOSIN - Use of preg_replace() with /e modifier is forbidden by configuration"); } @@ -532,37 +547,37 @@ not_evaled_code: break; case SUHOSIN_CODE_TYPE_LONGNAME: - suhosin_log(S_INCLUDE, "Include filename ('%s') is too long", op_array->filename); + suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is too long", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_MANYDOTS: - suhosin_log(S_INCLUDE, "Include filename ('%s') contains too many '../'", op_array->filename); + suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') contains too many '../'", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_UPLOADED: - suhosin_log(S_INCLUDE, "Include filename is an uploaded file"); + suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename is an uploaded file"); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_0FILE: - suhosin_log(S_INCLUDE, "Include filename contains an ASCIIZ character"); + suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename contains an ASCIIZ character"); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_WRITABLE: - suhosin_log(S_INCLUDE, "Include filename ('%s') is writable by PHP process", op_array->filename); + suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is writable by PHP process", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_BLACKURL: - suhosin_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", op_array->filename); + suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is an URL that is forbidden by the blacklist", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_BADURL: - suhosin_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed", op_array->filename); + suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is an URL that is not allowed", op_array->filename); suhosin_bailout(TSRMLS_C); break; @@ -588,17 +603,22 @@ not_evaled_code: } continue_execution: +#if PHP_VERSION_ID >= 50500 + old_execute_ex (execute_data TSRMLS_CC); +#else if (zo) { old_execute_ZO (op_array, dummy TSRMLS_CC); } else { old_execute (op_array TSRMLS_CC); } +#endif /* nothing to do */ SUHOSIN_G(in_code_type) = orig_code_type; SUHOSIN_G(execution_depth)--; } /* }}} */ +#if PHP_VERSION_ID < 50500 /* {{{ void suhosin_execute(zend_op_array *op_array TSRMLS_DC) * This function provides a hook for execution */ static void suhosin_execute(zend_op_array *op_array TSRMLS_DC) @@ -613,11 +633,17 @@ static void suhosin_execute_ZO(zend_op_array *op_array, long dummy TSRMLS_DC) suhosin_execute_ex(op_array, 1, dummy TSRMLS_CC); } /* }}} */ +#endif - +#if PHP_VERSION_ID >= 50500 +#define IH_HANDLER_PARAMS_REST int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC +#define IH_HANDLER_PARAMS internal_function_handler *ih, IH_HANDLER_PARAMS_REST +#define IH_HANDLER_PARAM_PASSTHRU ih, ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC +#else #define IH_HANDLER_PARAMS_REST zend_execute_data *execute_data_ptr, int return_value_used, int ht, zval *return_value TSRMLS_DC #define IH_HANDLER_PARAMS internal_function_handler *ih, IH_HANDLER_PARAMS_REST #define IH_HANDLER_PARAM_PASSTHRU ih, execute_data_ptr, return_value_used, ht, return_value TSRMLS_CC +#endif HashTable ihandler_table; @@ -1541,13 +1567,38 @@ internal_function_handler ihandlers[] = { /* {{{ void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) * This function provides a hook for internal execution */ +#if PHP_VERSION_ID >= 50500 +#define EX_T(offset) (*EX_TMP_VAR(execute_data_ptr, offset)) + +static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC) +{ + zval *return_value; + zval **return_value_ptr; + zval *this_ptr; + int ht; + + if (fci) { + return_value = *fci->retval_ptr_ptr; + return_value_ptr = fci->retval_ptr_ptr; + this_ptr = fci->object_ptr; + ht = fci->param_count; + } else { + temp_variable *ret = &EX_T(execute_data_ptr->opline->result.var); + zend_function *fbc = execute_data_ptr->function_state.function; + return_value = ret->var.ptr; + return_value_ptr = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL; + this_ptr = execute_data_ptr->object; + ht = execute_data_ptr->opline->extended_value; + } +#else static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) { + zval *return_value; + int ht = execute_data_ptr->opline->extended_value; +#endif char *lcname; int function_name_strlen, free_lcname = 0; - zval *return_value; zend_class_entry *ce = NULL; - int ht; internal_function_handler *ih; #ifdef ZEND_ENGINE_2 @@ -1568,7 +1619,8 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re lcname[function_name_strlen] = 0; zend_str_tolower(lcname, function_name_strlen); } - + +#if PHP_VERSION_ID < 50500 #ifdef ZEND_ENGINE_2 # if PHP_VERSION_ID < 50400 return_value = (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr; @@ -1578,7 +1630,7 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re #else return_value = execute_data_ptr->Ts[execute_data_ptr->opline->result.u.var].var.ptr; #endif - ht = execute_data_ptr->opline->extended_value; +#endif SDEBUG("function: %s", lcname); @@ -1586,7 +1638,7 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re if (SUHOSIN_G(eval_whitelist) != NULL) { if (!zend_hash_exists(SUHOSIN_G(eval_whitelist), lcname, function_name_strlen+1)) { - suhosin_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); + suhosin_log(S_EXECUTOR|S_GETCALLER, "function outside of eval whitelist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { @@ -1595,7 +1647,7 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re } } else if (SUHOSIN_G(eval_blacklist) != NULL) { if (zend_hash_exists(SUHOSIN_G(eval_blacklist), lcname, function_name_strlen+1)) { - suhosin_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); + suhosin_log(S_EXECUTOR|S_GETCALLER, "function within eval blacklist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { @@ -1607,7 +1659,7 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re if (SUHOSIN_G(func_whitelist) != NULL) { if (!zend_hash_exists(SUHOSIN_G(func_whitelist), lcname, function_name_strlen+1)) { - suhosin_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); + suhosin_log(S_EXECUTOR|S_GETCALLER, "function outside of whitelist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { @@ -1616,7 +1668,7 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re } } else if (SUHOSIN_G(func_blacklist) != NULL) { if (zend_hash_exists(SUHOSIN_G(func_blacklist), lcname, function_name_strlen+1)) { - suhosin_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); + suhosin_log(S_EXECUTOR|S_GETCALLER, "function within blacklist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { @@ -1635,10 +1687,18 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re } if (retval == 0) { +#if PHP_VERSION_ID >= 50500 + old_execute_internal(execute_data_ptr, fci, return_value_used TSRMLS_CC); +#else old_execute_internal(execute_data_ptr, return_value_used TSRMLS_CC); +#endif } } else { +#if PHP_VERSION_ID >= 50500 + old_execute_internal(execute_data_ptr, fci, return_value_used TSRMLS_CC); +#else old_execute_internal(execute_data_ptr, return_value_used TSRMLS_CC); +#endif } if (free_lcname == 1) { efree(lcname); @@ -1678,13 +1738,19 @@ static int function_lookup(zend_extension *extension) void suhosin_hook_execute(TSRMLS_D) { internal_function_handler *ih; - + +#if PHP_VERSION_ID >= 50500 + old_execute_ex = zend_execute_ex; + zend_execute_ex = suhosin_execute_ex; +#else old_execute = zend_execute; zend_execute = suhosin_execute; +#endif /* old_compile_file = zend_compile_file; zend_compile_file = suhosin_compile_file; */ +#if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED if (zo_set_oe_ex == NULL) { zo_set_oe_ex = (void *)DL_FETCH_SYMBOL(NULL, "zend_optimizer_set_oe_ex"); } @@ -1695,6 +1761,7 @@ void suhosin_hook_execute(TSRMLS_D) if (zo_set_oe_ex != NULL) { old_execute_ZO = zo_set_oe_ex(suhosin_execute_ZO); } +#endif old_execute_internal = zend_execute_internal; if (old_execute_internal == NULL) { @@ -1729,12 +1796,18 @@ void suhosin_hook_execute(TSRMLS_D) */ void suhosin_unhook_execute() { +#if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED if (zo_set_oe_ex) { zo_set_oe_ex(old_execute_ZO); } - +#endif + +#if PHP_VERSION_ID >= 50500 + zend_execute_ex = old_execute_ex; +#else zend_execute = old_execute; - +#endif + /* zend_compile_file = old_compile_file; */ if (old_execute_internal == execute_internal) { -- cgit v1.3