From 54c352c1b5aa08b187dd1e52e544709cad2b0fee Mon Sep 17 00:00:00 2001 From: Ben Fuhrmannek Date: Thu, 23 Sep 2021 12:23:40 +0200 Subject: config is stack allocated now + some code improvements (see details) * for easier memory manegement, the entire sp_config struct was merged into snuffleupagus_globals and allocated on stack where possible * SNUFFLEUPAGUS_G() can be written as SPG(), which is faster to type and easier to read * execution_depth is re-initialized to 0 for each request * function calls with inline string and length parameters consistently use ZEND_STRL instead of sizeof()-1 * execution is actually hooked if recursion protection is enabled * some line breaks were removed to make the code more readable --- src/sp_execute.c | 64 ++++++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 41 deletions(-) (limited to 'src/sp_execute.c') diff --git a/src/sp_execute.c b/src/sp_execute.c index 41257ad..ccb7508 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c @@ -8,8 +8,7 @@ static int (*orig_zend_stream_open)(const char *filename, // FIXME handle symlink ZEND_COLD static inline void terminate_if_writable(const char *filename) { - const sp_config_readonly_exec *config_ro_exec = - SNUFFLEUPAGUS_G(config).config_readonly_exec; + const sp_config_readonly_exec *config_ro_exec = &(SPCFG(readonly_exec)); if (0 == access(filename, W_OK)) { if (config_ro_exec->dump) { @@ -43,21 +42,18 @@ inline static void is_builtin_matching( return; } - should_disable_ht( - EG(current_execute_data), function_name, param_value, param_name, - SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions, - ht); + should_disable_ht(EG(current_execute_data), function_name, param_value, param_name, SPCFG(disabled_functions_reg).disabled_functions, ht); } static void ZEND_HOT is_in_eval_and_whitelisted(const zend_execute_data *execute_data) { - const sp_config_eval *config_eval = SNUFFLEUPAGUS_G(config).config_eval; + const sp_config_eval *config_eval = &(SPCFG(eval)); - if (EXPECTED(0 == SNUFFLEUPAGUS_G(in_eval))) { + if (EXPECTED(0 == SPG(in_eval))) { return; } - if (EXPECTED(NULL == SNUFFLEUPAGUS_G(config).config_eval->whitelist)) { + if (EXPECTED(NULL == config_eval->whitelist)) { return; } @@ -113,50 +109,45 @@ zend_string *get_eval_filename(const char *const filename) { } static inline void sp_orig_execute(zend_execute_data *execute_data) { - SNUFFLEUPAGUS_G(execution_depth)++; - if (SNUFFLEUPAGUS_G(execution_depth) > SNUFFLEUPAGUS_G(config).max_execution_depth && SNUFFLEUPAGUS_G(config).max_execution_depth > 0) { + SPG(execution_depth)++; + if (SPCFG(max_execution_depth) > 0 && SPG(execution_depth) > SPCFG(max_execution_depth)) { sp_log_drop("execute", "Maximum recursion limit reached. Script terminated."); } orig_execute_ex(execute_data); - SNUFFLEUPAGUS_G(execution_depth)--; + SPG(execution_depth)--; } static void sp_execute_ex(zend_execute_data *execute_data) { is_in_eval_and_whitelisted(execute_data); - const HashTable *config_disabled_functions = - SNUFFLEUPAGUS_G(config).config_disabled_functions; + const HashTable *config_disabled_functions = SPCFG(disabled_functions); if (!execute_data) { return; // LCOV_EXCL_LINE } if (UNEXPECTED(EX(func)->op_array.type == ZEND_EVAL_CODE)) { - const sp_list_node *config = zend_hash_str_find_ptr( - config_disabled_functions, "eval", sizeof("eval") - 1); + const sp_list_node *config = zend_hash_str_find_ptr(config_disabled_functions, ZEND_STRL("eval")); zend_string *filename = get_eval_filename(zend_get_executed_filename()); - is_builtin_matching(filename, "eval", NULL, config, - config_disabled_functions); + is_builtin_matching(filename, "eval", NULL, config, config_disabled_functions); zend_string_release(filename); - SNUFFLEUPAGUS_G(in_eval)++; + SPG(in_eval)++; sp_orig_execute(execute_data); - SNUFFLEUPAGUS_G(in_eval)--; + SPG(in_eval)--; return; } if (NULL != EX(func)->op_array.filename) { - if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { + if (SPCFG(readonly_exec).enable) { terminate_if_writable(ZSTR_VAL(EX(func)->op_array.filename)); } } - if (SNUFFLEUPAGUS_G(config).hook_execute) { + if (SPG(hook_execute)) { char *function_name = get_complete_function_path(execute_data); zval ret_val; - const sp_list_node *config_disabled_functions_reg = - SNUFFLEUPAGUS_G(config) - .config_disabled_functions_reg->disabled_functions; + const sp_list_node *config_disabled_functions_reg = SPCFG(disabled_functions_reg).disabled_functions; if (!function_name) { sp_orig_execute(execute_data); @@ -195,11 +186,7 @@ static void sp_execute_ex(zend_execute_data *execute_data) { sp_orig_execute(execute_data); - should_drop_on_ret_ht( - EX(return_value), function_name, - SNUFFLEUPAGUS_G(config) - .config_disabled_functions_reg_ret->disabled_functions, - SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, execute_data); + should_drop_on_ret_ht(EX(return_value), function_name, SPCFG(disabled_functions_reg_ret).disabled_functions, SPCFG(disabled_functions_ret), execute_data); efree(function_name); if (EX(return_value) == &ret_val) { @@ -231,41 +218,36 @@ static int sp_stream_open(const char *filename, zend_file_handle *handle) { } zend_string *zend_filename = zend_string_init(filename, strlen(filename), 0); - const HashTable *disabled_functions_hooked = - SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked; + const HashTable *disabled_functions_hooked = SPCFG(disabled_functions_hooked); switch (data->opline->opcode) { case ZEND_INCLUDE_OR_EVAL: - if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { + if (SPCFG(readonly_exec).enable) { terminate_if_writable(filename); } switch (data->opline->extended_value) { case ZEND_INCLUDE: is_builtin_matching( zend_filename, "include", "inclusion path", - zend_hash_str_find_ptr(disabled_functions_hooked, "include", - sizeof("include") - 1), + zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("include")), disabled_functions_hooked); break; case ZEND_REQUIRE: is_builtin_matching( zend_filename, "require", "inclusion path", - zend_hash_str_find_ptr(disabled_functions_hooked, "require", - sizeof("require") - 1), + zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("require")), disabled_functions_hooked); break; case ZEND_REQUIRE_ONCE: is_builtin_matching( zend_filename, "require_once", "inclusion path", - zend_hash_str_find_ptr(disabled_functions_hooked, "require_once", - sizeof("require_once") - 1), + zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("require_once")), disabled_functions_hooked); break; case ZEND_INCLUDE_ONCE: is_builtin_matching( zend_filename, "include_once", "inclusion path", - zend_hash_str_find_ptr(disabled_functions_hooked, "include_once", - sizeof("include_once") - 1), + zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("include_once")), disabled_functions_hooked); break; EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE -- cgit v1.3