summaryrefslogtreecommitdiff
path: root/src/sp_disabled_functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sp_disabled_functions.c')
-rw-r--r--src/sp_disabled_functions.c334
1 files changed, 141 insertions, 193 deletions
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index c47b5cb..95e19ad 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -13,26 +13,26 @@ static void should_drop_on_ret(const zval* return_value,
13 zend_execute_data* execute_data); 13 zend_execute_data* execute_data);
14 14
15char* get_complete_function_path(zend_execute_data const* const execute_data) { 15char* get_complete_function_path(zend_execute_data const* const execute_data) {
16 if (zend_is_executing() && !EG(current_execute_data)->func) { 16 if (!execute_data) {
17 return NULL; // LCOV_EXCL_LINE 17 return NULL; // LCOV_EXCL_LINE
18 } 18 }
19 if (!(execute_data->func->common.function_name)) { 19 zend_function *func = execute_data->func;
20 if (!(func->common.function_name)) {
20 return NULL; 21 return NULL;
21 } 22 }
22 23
23 char const* class_name; 24 char const* const function_name = ZSTR_VAL(func->common.function_name);
24 char const* const function_name =
25 ZSTR_VAL(execute_data->func->common.function_name);
26 char* complete_path_function = NULL; 25 char* complete_path_function = NULL;
27 26
28 class_name = get_active_class_name(NULL); 27 if ((func->type == ZEND_USER_FUNCTION || func->type == ZEND_INTERNAL_FUNCTION) && func->common.scope) {
29 if (*class_name) { 28 char const* class_name = ZSTR_VAL(func->common.scope->name);
30 const size_t len = strlen(class_name) + 2 + strlen(function_name) + 1; 29 const size_t len = strlen(class_name) + 2 + strlen(function_name) + 1;
31 complete_path_function = emalloc(len); 30 complete_path_function = emalloc(len);
32 snprintf(complete_path_function, len, "%s::%s", class_name, function_name); 31 snprintf(complete_path_function, len, "%s::%s", class_name, function_name);
33 } else { 32 } else {
34 complete_path_function = estrdup(function_name); 33 complete_path_function = estrdup(function_name);
35 } 34 }
35
36 return complete_path_function; 36 return complete_path_function;
37} 37}
38 38
@@ -67,28 +67,22 @@ static bool is_functions_list_matching(zend_execute_data* execute_data,
67 return false; 67 return false;
68} 68}
69 69
70static bool is_local_var_matching( 70static bool is_local_var_matching(zend_execute_data* execute_data, const sp_disabled_function* const config_node) {
71 zend_execute_data* execute_data,
72 const sp_disabled_function* const config_node) {
73 zval* var_value = {0}; 71 zval* var_value = {0};
74 72
75 var_value = sp_get_var_value(execute_data, config_node->var, false); 73 var_value = sp_get_var_value(execute_data, config_node->var, false);
76 if (var_value) { 74 if (var_value) {
77 if (Z_TYPE_P(var_value) == IS_ARRAY) { 75 if (Z_TYPE_P(var_value) == IS_ARRAY) {
78 if (config_node->key || config_node->r_key) { 76 if (config_node->key || config_node->r_key) {
79 if (sp_match_array_key(var_value, config_node->key, 77 if (sp_match_array_key(var_value, config_node->key, config_node->r_key)) {
80 config_node->r_key)) {
81 return true; 78 return true;
82 } 79 }
83 } else if (sp_match_array_value(var_value, config_node->value, 80 } else if (sp_match_array_value(var_value, config_node->value, config_node->r_value)) {
84 config_node->r_value)) {
85 return true; 81 return true;
86 } 82 }
87 } else { 83 } else {
88 zend_string const* const var_value_str = 84 zend_string const* const var_value_str = sp_zval_to_zend_string(var_value);
89 sp_zval_to_zend_string(var_value); 85 bool match = sp_match_value(var_value_str, config_node->value, config_node->r_value);
90 bool match = sp_match_value(var_value_str, config_node->value,
91 config_node->r_value);
92 86
93 if (true == match) { 87 if (true == match) {
94 return true; 88 return true;
@@ -98,107 +92,105 @@ static bool is_local_var_matching(
98 return false; 92 return false;
99} 93}
100 94
95static inline const char* get_fn_arg_name(zend_function *fn, uint32_t i) {
96 if (fn->type == ZEND_USER_FUNCTION || (fn->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
97 return ZSTR_VAL(fn->op_array.arg_info[i].name);
98 } else {
99 return fn->internal_function.arg_info[i].name;
100 }
101}
102
101static bool is_param_matching(zend_execute_data* execute_data, 103static bool is_param_matching(zend_execute_data* execute_data,
102 sp_disabled_function const* const config_node, 104 sp_disabled_function const* const config_node,
103 const zend_string* builtin_param, 105 const zend_string* builtin_param,
104 const char* builtin_param_name, 106 const char* builtin_param_name,
105 const char** arg_name, 107 const char** arg_name,
106 const zend_string** arg_value_str) { 108 const zend_string** arg_value_str) {
107 int nb_param = ZEND_CALL_NUM_ARGS(execute_data); 109 // builtin functions
108 int i = 0;
109 zval* arg_value;
110
111 if (config_node->pos != -1) {
112 if (config_node->pos > nb_param - 1) {
113 char* complete_function_path = get_complete_function_path(execute_data);
114 sp_log_warn("config",
115 "It seems that you wrote a rule filtering on the "
116 "%d%s argument of the function '%s', but it takes only %d "
117 "arguments. "
118 "Matching on _all_ arguments instead.",
119 config_node->pos, GET_SUFFIX(config_node->pos),
120 complete_function_path, nb_param);
121 efree(complete_function_path);
122 } else {
123 i = config_node->pos;
124 nb_param = (config_node->pos) + 1;
125 }
126 }
127
128 if (builtin_param) { 110 if (builtin_param) {
129 /* We're matching on a language construct (here named "builtin"), 111 /* We're matching on a language construct (here named "builtin"),
130 * and they can only take a single argument, but PHP considers them 112 * and they can only take a single argument, but PHP considers them
131 * differently than functions arguments. */ 113 * differently than functions arguments. */
132 *arg_name = builtin_param_name; 114 *arg_name = builtin_param_name;
133 *arg_value_str = builtin_param; 115 *arg_value_str = builtin_param;
134 return sp_match_value(builtin_param, config_node->value, 116 return sp_match_value(builtin_param, config_node->value,
135 config_node->r_value); 117 config_node->r_value);
136 } else if (config_node->r_param || config_node->pos != -1) { 118 }
137 // We're matching on a function (and not a language construct)
138 for (; i < nb_param; i++) {
139 if (ZEND_USER_CODE(execute_data->func->type)) { // yay consistency
140 *arg_name = ZSTR_VAL(execute_data->func->common.arg_info[i].name);
141 } else {
142 *arg_name = execute_data->func->internal_function.arg_info[i].name;
143 }
144 const bool pcre_matching =
145 config_node->r_param &&
146 (true == sp_is_regexp_matching(config_node->r_param, *arg_name));
147 119
148 /* This is the parameter name we're looking for. */ 120 // safeguards
149 if (true == pcre_matching || config_node->pos != -1) { 121 if (!execute_data || !execute_data->func) {
150 arg_value = ZEND_CALL_ARG(execute_data, i + 1); 122 sp_log_debug("no execute data -> silently ignore parameter matching");
123 return false;
124 }
151 125
152 if (config_node->param_type) { // Are we matching on the `type`? 126 *arg_name = NULL;
153 if (config_node->param_type == Z_TYPE_P(arg_value)) { 127 int call_num_args = EX_NUM_ARGS();
154 return true; 128 zend_function *fn = execute_data->func;
155 } 129 int fn_num_args = fn->common.num_args;
156 } else if (Z_TYPE_P(arg_value) == IS_ARRAY) { 130
157 *arg_value_str = sp_zval_to_zend_string(arg_value); 131 if (!call_num_args) {
158 if (config_node->key || config_node->r_key) { 132 sp_log_debug("no call arguments -> return");
159 if (sp_match_array_key(arg_value, config_node->key, 133 return false; // no arguments to check
160 config_node->r_key)) { 134 }
161 return true; 135
162 } 136 if (config_node->pos > call_num_args - 1 || config_node->pos > fn_num_args) {
163 } else if (sp_match_array_value(arg_value, config_node->value, 137 // trying to match argument beyond last given argument OR beyond last declared argument.
164 config_node->r_value)) { 138 // this is perfectly normal for functions with
165 return true; 139 // (a) optional arguments
166 } 140 // (b) excess arguments
167 } else { 141 // (c) variadic arguments which are not supported
168 *arg_value_str = sp_zval_to_zend_string(arg_value); 142 return false;
169 if (sp_match_value(*arg_value_str, config_node->value, 143 }
170 config_node->r_value)) { 144
171 return true; 145 zval* arg_value = NULL;
172 } 146
173 } 147 if (config_node->pos > -1) {
174 } 148 if (config_node->pos < fn_num_args) {
149 *arg_name = get_fn_arg_name(fn, config_node->pos);
175 } 150 }
151 arg_value = ZEND_CALL_ARG(execute_data, config_node->pos + 1);
176 } else if (config_node->param) { 152 } else if (config_node->param) {
177 *arg_name = config_node->param->value; 153 *arg_name = config_node->param->value;
178 arg_value = sp_get_var_value(execute_data, config_node->param, true); 154 arg_value = sp_get_var_value(execute_data, config_node->param, true);
155 } else if (config_node->r_param) {
156 for (int i = 0; i < call_num_args; i++) {
157 *arg_name = get_fn_arg_name(fn, i);
158 if (true == sp_is_regexp_matching(config_node->r_param, *arg_name)) {
159 arg_value = ZEND_CALL_ARG(execute_data, i + 1);
160 }
161 }
162 }
163
164 if (!arg_value) {
165 sp_log_debug("no argument match -> return");
166 return false;
167 }
179 168
180 if (arg_value) { 169 if (config_node->param_type) {
181 *arg_value_str = sp_zval_to_zend_string(arg_value); 170 if (config_node->param_type == Z_TYPE_P(arg_value)) {
182 if (config_node->param_type) { // Are we matching on the `type`? 171 if (!(config_node->key || config_node->r_key || config_node->value || config_node->r_value)) { // Are we matching on the `type` only?
183 if (config_node->param_type == Z_TYPE_P(arg_value)) { 172 sp_log_debug("arg type match only.");
184 return true;
185 }
186 } else if (Z_TYPE_P(arg_value) == IS_ARRAY) {
187 if (config_node->key || config_node->r_key) {
188 if (sp_match_array_key(arg_value, config_node->key,
189 config_node->r_key)) {
190 return true;
191 }
192 } else if (sp_match_array_value(arg_value, config_node->value,
193 config_node->r_value)) {
194 return true;
195 }
196 } else if (sp_match_value(*arg_value_str, config_node->value,
197 config_node->r_value)) {
198 return true; 173 return true;
199 } 174 }
175 } else {
176 sp_log_debug("arg type mismatch -> return");
177 return false;
200 } 178 }
201 } 179 }
180
181 *arg_value_str = sp_zval_to_zend_string(arg_value);
182 if (Z_TYPE_P(arg_value) == IS_ARRAY) {
183 if (config_node->key || config_node->r_key) {
184 if (sp_match_array_key(arg_value, config_node->key, config_node->r_key)) {
185 return true;
186 }
187 } else if (sp_match_array_value(arg_value, config_node->value, config_node->r_value)) {
188 return true;
189 }
190 } else if (sp_match_value(*arg_value_str, config_node->value, config_node->r_value)) {
191 return true;
192 }
193
202 return false; 194 return false;
203} 195}
204 196
@@ -218,17 +210,15 @@ static zend_execute_data* is_file_matching(
218 return ex; // LCOV_EXCL_LINE 210 return ex; // LCOV_EXCL_LINE
219 } 211 }
220 ITERATE(ex); 212 ITERATE(ex);
221 if (zend_string_equals(ex->func->op_array.filename, 213 if (zend_string_equals(ex->func->op_array.filename, config_node->filename)) {
222 config_node->filename)) {
223 return ex; // LCOV_EXCL_LINE 214 return ex; // LCOV_EXCL_LINE
224 } 215 }
225 } else if (config_node->r_filename) { 216 } else if (config_node->r_filename) {
226 if (sp_is_regexp_matching_zend(config_node->r_filename, current_filename)) { 217 if (sp_is_regexp_matching_zstr(config_node->r_filename, current_filename)) {
227 return ex; 218 return ex;
228 } 219 }
229 ITERATE(ex); 220 ITERATE(ex);
230 if (sp_is_regexp_matching_zend(config_node->r_filename, 221 if (sp_is_regexp_matching_zstr(config_node->r_filename, ex->func->op_array.filename)) {
231 ex->func->op_array.filename)) {
232 return ex; 222 return ex;
233 } 223 }
234 } 224 }
@@ -267,7 +257,7 @@ void should_disable_ht(zend_execute_data* execute_data,
267 current_filename = zend_string_init(tmp, strlen(tmp), 0); 257 current_filename = zend_string_init(tmp, strlen(tmp), 0);
268 } 258 }
269 259
270 ht_entry = zend_hash_str_find_ptr(ht, function_name, strlen(function_name)); 260 ht_entry = zend_hash_str_find_ptr(ht, VAR_AND_LEN(function_name));
271 261
272 if (ht_entry) { 262 if (ht_entry) {
273 should_disable(execute_data, function_name, builtin_param, 263 should_disable(execute_data, function_name, builtin_param,
@@ -289,26 +279,22 @@ static void should_disable(zend_execute_data* execute_data,
289 char current_file_hash[SHA256_SIZE * 2 + 1] = {0}; 279 char current_file_hash[SHA256_SIZE * 2 + 1] = {0};
290 280
291 while (config) { 281 while (config) {
292 sp_disabled_function const* const config_node = 282 sp_disabled_function const* const config_node = (sp_disabled_function*)(config->data);
293 (sp_disabled_function*)(config->data);
294 const char* arg_name = NULL; 283 const char* arg_name = NULL;
295 const zend_string* arg_value_str = NULL; 284 const zend_string* arg_value_str = NULL;
296 285
297 /* The order matters, since when we have `config_node->functions_list`, 286 /* The order matters, since when we have `config_node->functions_list`,
298 we also do have `config_node->function` */ 287 we also do have `config_node->function` */
299 if (config_node->functions_list) { 288 if (config_node->functions_list) {
300 if (false == is_functions_list_matching(execute_data, 289 if (false == is_functions_list_matching(execute_data, config_node->functions_list)) {
301 config_node->functions_list)) {
302 goto next; 290 goto next;
303 } 291 }
304 } else if (config_node->function) { 292 } else if (config_node->function) {
305 if (0 != 293 if (0 != strcmp(ZSTR_VAL(config_node->function), complete_function_path)) {
306 strcmp(ZSTR_VAL(config_node->function), complete_function_path)) {
307 goto next; // LCOV_EXCL_LINE 294 goto next; // LCOV_EXCL_LINE
308 } 295 }
309 } else if (config_node->r_function) { 296 } else if (config_node->r_function) {
310 if (false == sp_is_regexp_matching(config_node->r_function, 297 if (false == sp_is_regexp_matching(config_node->r_function, complete_function_path)) {
311 complete_function_path)) {
312 goto next; 298 goto next;
313 } 299 }
314 } 300 }
@@ -320,8 +306,7 @@ static void should_disable(zend_execute_data* execute_data,
320 } 306 }
321 307
322 if (config_node->filename || config_node->r_filename) { 308 if (config_node->filename || config_node->r_filename) {
323 zend_execute_data* ex = 309 zend_execute_data* ex = is_file_matching(execute_data, config_node, current_filename);
324 is_file_matching(execute_data, config_node, current_filename);
325 if (!ex) { 310 if (!ex) {
326 goto next; 311 goto next;
327 } 312 }
@@ -344,8 +329,7 @@ static void should_disable(zend_execute_data* execute_data,
344 if ('\0' == current_file_hash[0]) { 329 if ('\0' == current_file_hash[0]) {
345 compute_hash(ZSTR_VAL(current_filename), current_file_hash); 330 compute_hash(ZSTR_VAL(current_filename), current_file_hash);
346 } 331 }
347 if (0 != strncmp(current_file_hash, ZSTR_VAL(config_node->hash), 332 if (0 != strncmp(current_file_hash, ZSTR_VAL(config_node->hash), SHA256_SIZE)) {
348 SHA256_SIZE)) {
349 goto next; 333 goto next;
350 } 334 }
351 } 335 }
@@ -366,9 +350,7 @@ static void should_disable(zend_execute_data* execute_data,
366 "Snuffleupagus doesn't support variadic functions yet, sorry. " 350 "Snuffleupagus doesn't support variadic functions yet, sorry. "
367 "Check https://github.com/jvoisin/snuffleupagus/issues/164 for " 351 "Check https://github.com/jvoisin/snuffleupagus/issues/164 for "
368 "details."); 352 "details.");
369 } else if (false == is_param_matching( 353 } else if (false == is_param_matching(execute_data, config_node, builtin_param, builtin_param_name, &arg_name, &arg_value_str)) {
370 execute_data, config_node, builtin_param, builtin_param_name,
371 &arg_name, &arg_value_str)) {
372 goto next; 354 goto next;
373 } 355 }
374 } 356 }
@@ -379,11 +361,9 @@ static void should_disable(zend_execute_data* execute_data,
379 } 361 }
380 362
381 if (config_node->functions_list) { 363 if (config_node->functions_list) {
382 sp_log_disable(ZSTR_VAL(config_node->function), arg_name, arg_value_str, 364 sp_log_disable(ZSTR_VAL(config_node->function), arg_name, arg_value_str, config_node);
383 config_node);
384 } else { 365 } else {
385 sp_log_disable(complete_function_path, arg_name, arg_value_str, 366 sp_log_disable(complete_function_path, arg_name, arg_value_str, config_node);
386 config_node);
387 } 367 }
388 368
389 next: 369 next:
@@ -418,7 +398,6 @@ static void should_drop_on_ret(const zval* return_value,
418 bool match_type = false, match_value = false; 398 bool match_type = false, match_value = false;
419 399
420 while (config) { 400 while (config) {
421 const zend_string* ret_value_str = NULL;
422 sp_disabled_function const* const config_node = 401 sp_disabled_function const* const config_node =
423 (sp_disabled_function*)(config->data); 402 (sp_disabled_function*)(config->data);
424 403
@@ -462,13 +441,18 @@ static void should_drop_on_ret(const zval* return_value,
462 } 441 }
463 } 442 }
464 443
465 ret_value_str = sp_zval_to_zend_string(return_value); 444 const zend_string* ret_value_str = NULL;
445 sp_php_type ret_type = SP_PHP_TYPE_NULL;
446
447 if (return_value) {
448 ret_value_str = sp_zval_to_zend_string(return_value);
449 ret_type = Z_TYPE_P(return_value);
450 }
466 451
467 match_type = (config_node->ret_type) && 452 match_type = (config_node->ret_type) &&
468 (config_node->ret_type == Z_TYPE_P(return_value)); 453 (config_node->ret_type == ret_type);
469 match_value = (config_node->ret || config_node->r_ret) && 454 match_value = return_value && (config_node->ret || config_node->r_ret) &&
470 (true == sp_match_value(ret_value_str, config_node->ret, 455 (true == sp_match_value(ret_value_str, config_node->ret, config_node->r_ret));
471 config_node->r_ret));
472 456
473 if (true == match_type || true == match_value) { 457 if (true == match_type || true == match_value) {
474 if (true == config_node->allow) { 458 if (true == config_node->allow) {
@@ -483,40 +467,28 @@ static void should_drop_on_ret(const zval* return_value,
483 467
484ZEND_FUNCTION(check_disabled_function) { 468ZEND_FUNCTION(check_disabled_function) {
485 zif_handler orig_handler; 469 zif_handler orig_handler;
486 const char* current_function_name = get_active_function_name(TSRMLS_C); 470 const char* current_function_name = get_active_function_name();
487 471
488 should_disable_ht( 472 should_disable_ht(execute_data, current_function_name, NULL, NULL, SPCFG(disabled_functions_reg).disabled_functions, SPCFG(disabled_functions_hooked));
489 execute_data, current_function_name, NULL, NULL,
490 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions,
491 SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked);
492 473
493 orig_handler = zend_hash_str_find_ptr( 474 orig_handler = zend_hash_str_find_ptr(SPG(disabled_functions_hook), VAR_AND_LEN(current_function_name));
494 SNUFFLEUPAGUS_G(disabled_functions_hook), current_function_name,
495 strlen(current_function_name));
496 orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); 475 orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
497 should_drop_on_ret_ht( 476
498 return_value, current_function_name, 477 should_drop_on_ret_ht(return_value, current_function_name, SPCFG(disabled_functions_reg_ret).disabled_functions, SPCFG(disabled_functions_ret_hooked), execute_data);
499 SNUFFLEUPAGUS_G(config)
500 .config_disabled_functions_reg_ret->disabled_functions,
501 SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked,
502 execute_data);
503} 478}
504 479
505static int hook_functions_regexp(const sp_list_node* config) { 480static int hook_functions_regexp(const sp_list_node* config) {
506 while (config && config->data) { 481 while (config && config->data) {
507 const zend_string* function_name = 482 const zend_string* function_name = ((sp_disabled_function*)config->data)->function;
508 ((sp_disabled_function*)config->data)->function; 483 sp_regexp *function_name_sp_regexp = ((sp_disabled_function*)config->data)->r_function;
509 const sp_pcre* function_name_regexp = 484 const sp_pcre* function_name_regexp = function_name_sp_regexp ? function_name_sp_regexp->re : NULL;
510 ((sp_disabled_function*)config->data)->r_function;
511 485
512 assert(function_name || function_name_regexp); 486 assert(function_name || function_name_regexp);
513 487
514 if (function_name) { 488 if (function_name) {
515 HOOK_FUNCTION(ZSTR_VAL(function_name), disabled_functions_hook, 489 HOOK_FUNCTION(ZSTR_VAL(function_name), disabled_functions_hook, PHP_FN(check_disabled_function));
516 PHP_FN(check_disabled_function));
517 } else { 490 } else {
518 HOOK_FUNCTION_BY_REGEXP(function_name_regexp, disabled_functions_hook, 491 HOOK_FUNCTION_BY_REGEXP(function_name_regexp, disabled_functions_hook, PHP_FN(check_disabled_function));
519 PHP_FN(check_disabled_function));
520 } 492 }
521 493
522 config = config->next; 494 config = config->next;
@@ -529,10 +501,8 @@ static void hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) {
529 zval* value; 501 zval* value;
530 502
531 ZEND_HASH_FOREACH_STR_KEY_VAL(to_hook_ht, key, value) { 503 ZEND_HASH_FOREACH_STR_KEY_VAL(to_hook_ht, key, value) {
532 bool hooked = HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, 504 bool hooked = HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, PHP_FN(check_disabled_function));
533 PHP_FN(check_disabled_function)); 505 bool is_builtin = check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data);
534 bool is_builtin =
535 check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data);
536 if (hooked || is_builtin) { 506 if (hooked || is_builtin) {
537 zend_symtable_add_new(hooked_ht, key, value); 507 zend_symtable_add_new(hooked_ht, key, value);
538 zend_hash_del(to_hook_ht, key); 508 zend_hash_del(to_hook_ht, key);
@@ -543,41 +513,29 @@ static void hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) {
543 513
544ZEND_FUNCTION(eval_blacklist_callback) { 514ZEND_FUNCTION(eval_blacklist_callback) {
545 zif_handler orig_handler; 515 zif_handler orig_handler;
546 const char* current_function_name = get_active_function_name(TSRMLS_C); 516 char* current_function_name = get_complete_function_path(EG(current_execute_data));
547 zend_string* tmp =
548 zend_string_init(current_function_name, strlen(current_function_name), 0);
549 517
550 if (true == check_is_in_eval_whitelist(tmp)) { 518 if (!current_function_name || true == check_is_in_eval_whitelist(current_function_name)) {
551 zend_string_release(tmp);
552 goto whitelisted; 519 goto whitelisted;
553 } 520 }
554 zend_string_release(tmp);
555 521
556 if (SNUFFLEUPAGUS_G(in_eval) > 0) { 522 if (SPG(in_eval) > 0) {
557 zend_string* filename = get_eval_filename(zend_get_executed_filename()); 523 const sp_config_eval* config_eval = &(SPCFG(eval));
558 const int line_number = zend_get_executed_lineno(TSRMLS_C);
559 const sp_config_eval* config_eval = SNUFFLEUPAGUS_G(config).config_eval;
560 524
561 if (config_eval->dump) { 525 if (config_eval->dump) {
562 sp_log_request(config_eval->dump, config_eval->textual_representation, 526 sp_log_request(config_eval->dump, config_eval->textual_representation);
563 SP_TOKEN_EVAL_BLACKLIST);
564 } 527 }
565 if (config_eval->simulation) { 528 if (config_eval->simulation) {
566 sp_log_simulation("eval", 529 sp_log_simulation("eval", "A call to '%s' was tried in eval. logging it.", current_function_name);
567 "A call to %s was tried in eval, in %s:%d, logging it.",
568 current_function_name, ZSTR_VAL(filename), line_number);
569 } else { 530 } else {
570 sp_log_drop("eval", 531 sp_log_drop("eval", "A call to '%s' was tried in eval. dropping it.", current_function_name);
571 "A call to %s was tried in eval, in %s:%d, dropping it.",
572 current_function_name, ZSTR_VAL(filename), line_number);
573 } 532 }
574 efree(filename);
575 } 533 }
576 534
577whitelisted: 535whitelisted:
578 orig_handler = zend_hash_str_find_ptr( 536
579 SNUFFLEUPAGUS_G(sp_eval_blacklist_functions_hook), current_function_name, 537 orig_handler = zend_hash_str_find_ptr(SPG(sp_eval_blacklist_functions_hook), current_function_name, strlen(current_function_name));
580 strlen(current_function_name)); 538 efree(current_function_name);
581 orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); 539 orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
582} 540}
583 541
@@ -586,26 +544,19 @@ int hook_disabled_functions(void) {
586 544
587 int ret = SUCCESS; 545 int ret = SUCCESS;
588 546
589 hook_functions(SNUFFLEUPAGUS_G(config).config_disabled_functions, 547 hook_functions(SPCFG(disabled_functions), SPCFG(disabled_functions_hooked));
590 SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked); 548 hook_functions(SPCFG(disabled_functions_ret), SPCFG(disabled_functions_ret_hooked));
591
592 hook_functions(SNUFFLEUPAGUS_G(config).config_disabled_functions_ret,
593 SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked);
594 549
595 ret |= hook_functions_regexp( 550 ret |= hook_functions_regexp(SPCFG(disabled_functions_reg).disabled_functions);
596 SNUFFLEUPAGUS_G(config)
597 .config_disabled_functions_reg->disabled_functions);
598 551
599 ret |= hook_functions_regexp( 552 ret |= hook_functions_regexp(SPCFG(disabled_functions_reg_ret).disabled_functions);
600 SNUFFLEUPAGUS_G(config)
601 .config_disabled_functions_reg_ret->disabled_functions);
602 553
603 if (NULL != SNUFFLEUPAGUS_G(config).config_eval->blacklist) { 554 if (NULL != SPCFG(eval).blacklist) {
604 sp_list_node* it = SNUFFLEUPAGUS_G(config).config_eval->blacklist; 555 sp_list_node* it = SPCFG(eval).blacklist;
605 556
606 while (it) { 557 while (it) {
607 hook_function(ZSTR_VAL((zend_string*)it->data), 558 hook_function(ZSTR_VAL((zend_string*)it->data),
608 SNUFFLEUPAGUS_G(sp_eval_blacklist_functions_hook), 559 SPG(sp_eval_blacklist_functions_hook),
609 PHP_FN(eval_blacklist_callback)); 560 PHP_FN(eval_blacklist_callback));
610 it = it->next; 561 it = it->next;
611 } 562 }
@@ -622,10 +573,7 @@ int hook_echo(const char* str, size_t str_length) {
622#endif 573#endif
623 zend_string* zs = zend_string_init(str, str_length, 0); 574 zend_string* zs = zend_string_init(str, str_length, 0);
624 575
625 should_disable_ht( 576 should_disable_ht(EG(current_execute_data), "echo", zs, NULL, SPCFG(disabled_functions_reg).disabled_functions, SPCFG(disabled_functions_hooked));
626 EG(current_execute_data), "echo", zs, NULL,
627 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions,
628 SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked);
629 577
630 zend_string_release(zs); 578 zend_string_release(zs);
631 579