summaryrefslogtreecommitdiff
path: root/src/sp_execute.c
diff options
context:
space:
mode:
authorBen Fuhrmannek2021-09-23 12:23:40 +0200
committerBen Fuhrmannek2021-09-23 12:23:40 +0200
commit54c352c1b5aa08b187dd1e52e544709cad2b0fee (patch)
treed15bf0f484c6baa1f2718e625e0d49f6fb488507 /src/sp_execute.c
parent887e1c9d44fbcf5f23a928269034593b8521aaba (diff)
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
Diffstat (limited to 'src/sp_execute.c')
-rw-r--r--src/sp_execute.c64
1 files changed, 23 insertions, 41 deletions
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,
8 8
9// FIXME handle symlink 9// FIXME handle symlink
10ZEND_COLD static inline void terminate_if_writable(const char *filename) { 10ZEND_COLD static inline void terminate_if_writable(const char *filename) {
11 const sp_config_readonly_exec *config_ro_exec = 11 const sp_config_readonly_exec *config_ro_exec = &(SPCFG(readonly_exec));
12 SNUFFLEUPAGUS_G(config).config_readonly_exec;
13 12
14 if (0 == access(filename, W_OK)) { 13 if (0 == access(filename, W_OK)) {
15 if (config_ro_exec->dump) { 14 if (config_ro_exec->dump) {
@@ -43,21 +42,18 @@ inline static void is_builtin_matching(
43 return; 42 return;
44 } 43 }
45 44
46 should_disable_ht( 45 should_disable_ht(EG(current_execute_data), function_name, param_value, param_name, SPCFG(disabled_functions_reg).disabled_functions, ht);
47 EG(current_execute_data), function_name, param_value, param_name,
48 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions,
49 ht);
50} 46}
51 47
52static void ZEND_HOT 48static void ZEND_HOT
53is_in_eval_and_whitelisted(const zend_execute_data *execute_data) { 49is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
54 const sp_config_eval *config_eval = SNUFFLEUPAGUS_G(config).config_eval; 50 const sp_config_eval *config_eval = &(SPCFG(eval));
55 51
56 if (EXPECTED(0 == SNUFFLEUPAGUS_G(in_eval))) { 52 if (EXPECTED(0 == SPG(in_eval))) {
57 return; 53 return;
58 } 54 }
59 55
60 if (EXPECTED(NULL == SNUFFLEUPAGUS_G(config).config_eval->whitelist)) { 56 if (EXPECTED(NULL == config_eval->whitelist)) {
61 return; 57 return;
62 } 58 }
63 59
@@ -113,50 +109,45 @@ zend_string *get_eval_filename(const char *const filename) {
113} 109}
114 110
115static inline void sp_orig_execute(zend_execute_data *execute_data) { 111static inline void sp_orig_execute(zend_execute_data *execute_data) {
116 SNUFFLEUPAGUS_G(execution_depth)++; 112 SPG(execution_depth)++;
117 if (SNUFFLEUPAGUS_G(execution_depth) > SNUFFLEUPAGUS_G(config).max_execution_depth && SNUFFLEUPAGUS_G(config).max_execution_depth > 0) { 113 if (SPCFG(max_execution_depth) > 0 && SPG(execution_depth) > SPCFG(max_execution_depth)) {
118 sp_log_drop("execute", "Maximum recursion limit reached. Script terminated."); 114 sp_log_drop("execute", "Maximum recursion limit reached. Script terminated.");
119 } 115 }
120 orig_execute_ex(execute_data); 116 orig_execute_ex(execute_data);
121 SNUFFLEUPAGUS_G(execution_depth)--; 117 SPG(execution_depth)--;
122} 118}
123 119
124static void sp_execute_ex(zend_execute_data *execute_data) { 120static void sp_execute_ex(zend_execute_data *execute_data) {
125 is_in_eval_and_whitelisted(execute_data); 121 is_in_eval_and_whitelisted(execute_data);
126 const HashTable *config_disabled_functions = 122 const HashTable *config_disabled_functions = SPCFG(disabled_functions);
127 SNUFFLEUPAGUS_G(config).config_disabled_functions;
128 123
129 if (!execute_data) { 124 if (!execute_data) {
130 return; // LCOV_EXCL_LINE 125 return; // LCOV_EXCL_LINE
131 } 126 }
132 127
133 if (UNEXPECTED(EX(func)->op_array.type == ZEND_EVAL_CODE)) { 128 if (UNEXPECTED(EX(func)->op_array.type == ZEND_EVAL_CODE)) {
134 const sp_list_node *config = zend_hash_str_find_ptr( 129 const sp_list_node *config = zend_hash_str_find_ptr(config_disabled_functions, ZEND_STRL("eval"));
135 config_disabled_functions, "eval", sizeof("eval") - 1);
136 130
137 zend_string *filename = get_eval_filename(zend_get_executed_filename()); 131 zend_string *filename = get_eval_filename(zend_get_executed_filename());
138 is_builtin_matching(filename, "eval", NULL, config, 132 is_builtin_matching(filename, "eval", NULL, config, config_disabled_functions);
139 config_disabled_functions);
140 zend_string_release(filename); 133 zend_string_release(filename);
141 134
142 SNUFFLEUPAGUS_G(in_eval)++; 135 SPG(in_eval)++;
143 sp_orig_execute(execute_data); 136 sp_orig_execute(execute_data);
144 SNUFFLEUPAGUS_G(in_eval)--; 137 SPG(in_eval)--;
145 return; 138 return;
146 } 139 }
147 140
148 if (NULL != EX(func)->op_array.filename) { 141 if (NULL != EX(func)->op_array.filename) {
149 if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { 142 if (SPCFG(readonly_exec).enable) {
150 terminate_if_writable(ZSTR_VAL(EX(func)->op_array.filename)); 143 terminate_if_writable(ZSTR_VAL(EX(func)->op_array.filename));
151 } 144 }
152 } 145 }
153 146
154 if (SNUFFLEUPAGUS_G(config).hook_execute) { 147 if (SPG(hook_execute)) {
155 char *function_name = get_complete_function_path(execute_data); 148 char *function_name = get_complete_function_path(execute_data);
156 zval ret_val; 149 zval ret_val;
157 const sp_list_node *config_disabled_functions_reg = 150 const sp_list_node *config_disabled_functions_reg = SPCFG(disabled_functions_reg).disabled_functions;
158 SNUFFLEUPAGUS_G(config)
159 .config_disabled_functions_reg->disabled_functions;
160 151
161 if (!function_name) { 152 if (!function_name) {
162 sp_orig_execute(execute_data); 153 sp_orig_execute(execute_data);
@@ -195,11 +186,7 @@ static void sp_execute_ex(zend_execute_data *execute_data) {
195 186
196 sp_orig_execute(execute_data); 187 sp_orig_execute(execute_data);
197 188
198 should_drop_on_ret_ht( 189 should_drop_on_ret_ht(EX(return_value), function_name, SPCFG(disabled_functions_reg_ret).disabled_functions, SPCFG(disabled_functions_ret), execute_data);
199 EX(return_value), function_name,
200 SNUFFLEUPAGUS_G(config)
201 .config_disabled_functions_reg_ret->disabled_functions,
202 SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, execute_data);
203 efree(function_name); 190 efree(function_name);
204 191
205 if (EX(return_value) == &ret_val) { 192 if (EX(return_value) == &ret_val) {
@@ -231,41 +218,36 @@ static int sp_stream_open(const char *filename, zend_file_handle *handle) {
231 } 218 }
232 219
233 zend_string *zend_filename = zend_string_init(filename, strlen(filename), 0); 220 zend_string *zend_filename = zend_string_init(filename, strlen(filename), 0);
234 const HashTable *disabled_functions_hooked = 221 const HashTable *disabled_functions_hooked = SPCFG(disabled_functions_hooked);
235 SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked;
236 222
237 switch (data->opline->opcode) { 223 switch (data->opline->opcode) {
238 case ZEND_INCLUDE_OR_EVAL: 224 case ZEND_INCLUDE_OR_EVAL:
239 if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { 225 if (SPCFG(readonly_exec).enable) {
240 terminate_if_writable(filename); 226 terminate_if_writable(filename);
241 } 227 }
242 switch (data->opline->extended_value) { 228 switch (data->opline->extended_value) {
243 case ZEND_INCLUDE: 229 case ZEND_INCLUDE:
244 is_builtin_matching( 230 is_builtin_matching(
245 zend_filename, "include", "inclusion path", 231 zend_filename, "include", "inclusion path",
246 zend_hash_str_find_ptr(disabled_functions_hooked, "include", 232 zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("include")),
247 sizeof("include") - 1),
248 disabled_functions_hooked); 233 disabled_functions_hooked);
249 break; 234 break;
250 case ZEND_REQUIRE: 235 case ZEND_REQUIRE:
251 is_builtin_matching( 236 is_builtin_matching(
252 zend_filename, "require", "inclusion path", 237 zend_filename, "require", "inclusion path",
253 zend_hash_str_find_ptr(disabled_functions_hooked, "require", 238 zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("require")),
254 sizeof("require") - 1),
255 disabled_functions_hooked); 239 disabled_functions_hooked);
256 break; 240 break;
257 case ZEND_REQUIRE_ONCE: 241 case ZEND_REQUIRE_ONCE:
258 is_builtin_matching( 242 is_builtin_matching(
259 zend_filename, "require_once", "inclusion path", 243 zend_filename, "require_once", "inclusion path",
260 zend_hash_str_find_ptr(disabled_functions_hooked, "require_once", 244 zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("require_once")),
261 sizeof("require_once") - 1),
262 disabled_functions_hooked); 245 disabled_functions_hooked);
263 break; 246 break;
264 case ZEND_INCLUDE_ONCE: 247 case ZEND_INCLUDE_ONCE:
265 is_builtin_matching( 248 is_builtin_matching(
266 zend_filename, "include_once", "inclusion path", 249 zend_filename, "include_once", "inclusion path",
267 zend_hash_str_find_ptr(disabled_functions_hooked, "include_once", 250 zend_hash_str_find_ptr(disabled_functions_hooked, ZEND_STRL("include_once")),
268 sizeof("include_once") - 1),
269 disabled_functions_hooked); 251 disabled_functions_hooked);
270 break; 252 break;
271 EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE 253 EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE