diff options
| -rw-r--r-- | src/sp_disabled_functions.c | 100 | ||||
| -rw-r--r-- | src/sp_disabled_functions.h | 8 | ||||
| -rw-r--r-- | src/sp_execute.c | 41 |
3 files changed, 64 insertions, 85 deletions
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index b5cbe14..c483612 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c | |||
| @@ -5,6 +5,18 @@ | |||
| 5 | 5 | ||
| 6 | ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) | 6 | ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) |
| 7 | 7 | ||
| 8 | static void should_disable(zend_execute_data* execute_data, | ||
| 9 | const char* complete_function_path, | ||
| 10 | const zend_string* builtin_param, | ||
| 11 | const char* builtin_param_name, | ||
| 12 | const sp_list_node* config, | ||
| 13 | const zend_string* current_filename); | ||
| 14 | |||
| 15 | static void should_drop_on_ret(const zval* return_value, | ||
| 16 | const sp_list_node* config, | ||
| 17 | const char* complete_function_path, | ||
| 18 | zend_execute_data* execute_data); | ||
| 19 | |||
| 8 | char* get_complete_function_path(zend_execute_data const* const execute_data) { | 20 | char* get_complete_function_path(zend_execute_data const* const execute_data) { |
| 9 | if (zend_is_executing() && !EG(current_execute_data)->func) { | 21 | if (zend_is_executing() && !EG(current_execute_data)->func) { |
| 10 | return NULL; // LCOV_EXCL_LINE | 22 | return NULL; // LCOV_EXCL_LINE |
| @@ -249,17 +261,16 @@ static bool check_is_builtin_name( | |||
| 249 | return false; | 261 | return false; |
| 250 | } | 262 | } |
| 251 | 263 | ||
| 252 | bool should_disable_ht(zend_execute_data* execute_data, | 264 | void should_disable_ht(zend_execute_data* execute_data, |
| 253 | const char* function_name, | 265 | const char* function_name, |
| 254 | const zend_string* builtin_param, | 266 | const zend_string* builtin_param, |
| 255 | const char* builtin_param_name, | 267 | const char* builtin_param_name, |
| 256 | const sp_list_node* config, const HashTable* ht) { | 268 | const sp_list_node* config, const HashTable* ht) { |
| 257 | const sp_list_node* ht_entry = NULL; | 269 | const sp_list_node* ht_entry = NULL; |
| 258 | bool ret = false; | ||
| 259 | zend_string* current_filename; | 270 | zend_string* current_filename; |
| 260 | 271 | ||
| 261 | if (!execute_data) { | 272 | if (!execute_data) { |
| 262 | return false; // LCOV_EXCL_LINE | 273 | return; // LCOV_EXCL_LINE |
| 263 | } | 274 | } |
| 264 | 275 | ||
| 265 | if (UNEXPECTED(builtin_param && !strcmp(function_name, "eval"))) { | 276 | if (UNEXPECTED(builtin_param && !strcmp(function_name, "eval"))) { |
| @@ -271,24 +282,23 @@ bool should_disable_ht(zend_execute_data* execute_data, | |||
| 271 | 282 | ||
| 272 | ht_entry = zend_hash_str_find_ptr(ht, function_name, strlen(function_name)); | 283 | ht_entry = zend_hash_str_find_ptr(ht, function_name, strlen(function_name)); |
| 273 | 284 | ||
| 274 | if (ht_entry && | 285 | if (ht_entry) { |
| 275 | should_disable(execute_data, function_name, builtin_param, | 286 | should_disable(execute_data, function_name, builtin_param, |
| 276 | builtin_param_name, ht_entry, current_filename)) { | 287 | builtin_param_name, ht_entry, current_filename); |
| 277 | ret = true; | ||
| 278 | } else if (config && config->data) { | 288 | } else if (config && config->data) { |
| 279 | ret = should_disable(execute_data, function_name, builtin_param, | 289 | should_disable(execute_data, function_name, builtin_param, |
| 280 | builtin_param_name, config, current_filename); | 290 | builtin_param_name, config, current_filename); |
| 281 | } | 291 | } |
| 282 | 292 | ||
| 283 | efree(current_filename); | 293 | efree(current_filename); |
| 284 | return ret; | ||
| 285 | } | 294 | } |
| 286 | 295 | ||
| 287 | bool should_disable(zend_execute_data* execute_data, | 296 | static void should_disable(zend_execute_data* execute_data, |
| 288 | const char* complete_function_path, | 297 | const char* complete_function_path, |
| 289 | const zend_string* builtin_param, | 298 | const zend_string* builtin_param, |
| 290 | const char* builtin_param_name, const sp_list_node* config, | 299 | const char* builtin_param_name, |
| 291 | const zend_string* current_filename) { | 300 | const sp_list_node* config, |
| 301 | const zend_string* current_filename) { | ||
| 292 | char current_file_hash[SHA256_SIZE * 2 + 1] = {0}; | 302 | char current_file_hash[SHA256_SIZE * 2 + 1] = {0}; |
| 293 | 303 | ||
| 294 | while (config) { | 304 | while (config) { |
| @@ -381,7 +391,7 @@ bool should_disable(zend_execute_data* execute_data, | |||
| 381 | 391 | ||
| 382 | /* Everything matched.*/ | 392 | /* Everything matched.*/ |
| 383 | if (true == config_node->allow) { | 393 | if (true == config_node->allow) { |
| 384 | goto allow; | 394 | return; |
| 385 | } | 395 | } |
| 386 | 396 | ||
| 387 | if (config_node->functions_list) { | 397 | if (config_node->functions_list) { |
| @@ -391,43 +401,34 @@ bool should_disable(zend_execute_data* execute_data, | |||
| 391 | sp_log_disable(complete_function_path, arg_name, arg_value_str, | 401 | sp_log_disable(complete_function_path, arg_name, arg_value_str, |
| 392 | config_node); | 402 | config_node); |
| 393 | } | 403 | } |
| 394 | if (true == config_node->simulation) { | 404 | |
| 395 | goto next; | ||
| 396 | } else { // We've got a match, the function won't be executed | ||
| 397 | return true; | ||
| 398 | } | ||
| 399 | next: | 405 | next: |
| 400 | config = config->next; | 406 | config = config->next; |
| 401 | } | 407 | } |
| 402 | allow: | ||
| 403 | return false; | ||
| 404 | } | 408 | } |
| 405 | 409 | ||
| 406 | bool should_drop_on_ret_ht(const zval* return_value, const char* function_name, | 410 | void should_drop_on_ret_ht(const zval* return_value, const char* function_name, |
| 407 | const sp_list_node* config, const HashTable* ht, | 411 | const sp_list_node* config, const HashTable* ht, |
| 408 | zend_execute_data* execute_data) { | 412 | zend_execute_data* execute_data) { |
| 409 | const sp_list_node* ht_entry = NULL; | 413 | const sp_list_node* ht_entry = NULL; |
| 410 | bool ret = false; | ||
| 411 | 414 | ||
| 412 | if (!function_name) { | 415 | if (!function_name) { |
| 413 | return ret; | 416 | return; |
| 414 | } | 417 | } |
| 415 | 418 | ||
| 416 | ht_entry = zend_hash_str_find_ptr(ht, function_name, strlen(function_name)); | 419 | ht_entry = zend_hash_str_find_ptr(ht, function_name, strlen(function_name)); |
| 417 | 420 | ||
| 418 | if (ht_entry && | 421 | if (ht_entry) { |
| 419 | should_drop_on_ret(return_value, ht_entry, function_name, execute_data)) { | 422 | should_drop_on_ret(return_value, ht_entry, function_name, execute_data); |
| 420 | ret = true; | ||
| 421 | } else if (config && config->data) { | 423 | } else if (config && config->data) { |
| 422 | ret = should_drop_on_ret(return_value, config, function_name, execute_data); | 424 | should_drop_on_ret(return_value, config, function_name, execute_data); |
| 423 | } | 425 | } |
| 424 | |||
| 425 | return ret; | ||
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | bool should_drop_on_ret(const zval* return_value, const sp_list_node* config, | 428 | static void should_drop_on_ret(const zval* return_value, |
| 429 | const char* complete_function_path, | 429 | const sp_list_node* config, |
| 430 | zend_execute_data* execute_data) { | 430 | const char* complete_function_path, |
| 431 | zend_execute_data* execute_data) { | ||
| 431 | const char* current_filename = zend_get_executed_filename(TSRMLS_C); | 432 | const char* current_filename = zend_get_executed_filename(TSRMLS_C); |
| 432 | char current_file_hash[SHA256_SIZE * 2 + 1] = {0}; | 433 | char current_file_hash[SHA256_SIZE * 2 + 1] = {0}; |
| 433 | bool match_type = false, match_value = false; | 434 | bool match_type = false, match_value = false; |
| @@ -487,41 +488,34 @@ bool should_drop_on_ret(const zval* return_value, const sp_list_node* config, | |||
| 487 | 488 | ||
| 488 | if (true == match_type || true == match_value) { | 489 | if (true == match_type || true == match_value) { |
| 489 | if (true == config_node->allow) { | 490 | if (true == config_node->allow) { |
| 490 | return false; | 491 | return; |
| 491 | } | 492 | } |
| 492 | sp_log_disable_ret(complete_function_path, ret_value_str, config_node); | 493 | sp_log_disable_ret(complete_function_path, ret_value_str, config_node); |
| 493 | if (false == config_node->simulation) { | ||
| 494 | return true; | ||
| 495 | } | ||
| 496 | } | 494 | } |
| 497 | next: | 495 | next: |
| 498 | config = config->next; | 496 | config = config->next; |
| 499 | } | 497 | } |
| 500 | return false; | ||
| 501 | } | 498 | } |
| 502 | 499 | ||
| 503 | ZEND_FUNCTION(check_disabled_function) { | 500 | ZEND_FUNCTION(check_disabled_function) { |
| 504 | zif_handler orig_handler; | 501 | zif_handler orig_handler; |
| 505 | const char* current_function_name = get_active_function_name(TSRMLS_C); | 502 | const char* current_function_name = get_active_function_name(TSRMLS_C); |
| 506 | 503 | ||
| 507 | if (true == should_disable_ht( | 504 | should_disable_ht( |
| 508 | execute_data, current_function_name, NULL, NULL, | 505 | execute_data, current_function_name, NULL, NULL, |
| 509 | SNUFFLEUPAGUS_G(config) | 506 | SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions, |
| 510 | .config_disabled_functions_reg->disabled_functions, | 507 | SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked); |
| 511 | SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked)) { | ||
| 512 | } | ||
| 513 | 508 | ||
| 514 | orig_handler = zend_hash_str_find_ptr( | 509 | orig_handler = zend_hash_str_find_ptr( |
| 515 | SNUFFLEUPAGUS_G(disabled_functions_hook), current_function_name, | 510 | SNUFFLEUPAGUS_G(disabled_functions_hook), current_function_name, |
| 516 | strlen(current_function_name)); | 511 | strlen(current_function_name)); |
| 517 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 512 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
| 518 | if (true == should_drop_on_ret_ht( | 513 | should_drop_on_ret_ht( |
| 519 | return_value, current_function_name, | 514 | return_value, current_function_name, |
| 520 | SNUFFLEUPAGUS_G(config) | 515 | SNUFFLEUPAGUS_G(config) |
| 521 | .config_disabled_functions_reg_ret->disabled_functions, | 516 | .config_disabled_functions_reg_ret->disabled_functions, |
| 522 | SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked, | 517 | SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked, |
| 523 | execute_data)) { | 518 | execute_data); |
| 524 | } | ||
| 525 | } | 519 | } |
| 526 | 520 | ||
| 527 | static int hook_functions_regexp(const sp_list_node* config) { | 521 | static int hook_functions_regexp(const sp_list_node* config) { |
diff --git a/src/sp_disabled_functions.h b/src/sp_disabled_functions.h index b7901dd..3999aec 100644 --- a/src/sp_disabled_functions.h +++ b/src/sp_disabled_functions.h | |||
| @@ -5,15 +5,11 @@ extern zend_write_func_t zend_write_default; | |||
| 5 | 5 | ||
| 6 | int hook_disabled_functions(); | 6 | int hook_disabled_functions(); |
| 7 | int hook_echo(const char *, size_t); | 7 | int hook_echo(const char *, size_t); |
| 8 | bool should_disable(zend_execute_data *, const char *, const zend_string *, | 8 | void should_disable_ht(zend_execute_data *, const char *, const zend_string *, |
| 9 | const char *, const sp_list_node *, const zend_string *); | ||
| 10 | bool should_disable_ht(zend_execute_data *, const char *, const zend_string *, | ||
| 11 | const char *, const sp_list_node *, const HashTable *); | 9 | const char *, const sp_list_node *, const HashTable *); |
| 12 | bool should_drop_on_ret_ht(const zval *, const char *, | 10 | void should_drop_on_ret_ht(const zval *, const char *, |
| 13 | const sp_list_node *config, const HashTable *, | 11 | const sp_list_node *config, const HashTable *, |
| 14 | zend_execute_data *); | 12 | zend_execute_data *); |
| 15 | bool should_drop_on_ret(const zval *, const sp_list_node *config, const char *, | ||
| 16 | zend_execute_data *); | ||
| 17 | char *get_complete_function_path(zend_execute_data const *const); | 13 | char *get_complete_function_path(zend_execute_data const *const); |
| 18 | 14 | ||
| 19 | #endif /* __SP_DISABLE_FUNCTIONS_H */ | 15 | #endif /* __SP_DISABLE_FUNCTIONS_H */ |
diff --git a/src/sp_execute.c b/src/sp_execute.c index cc2d9b7..544d8c2 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c | |||
| @@ -49,13 +49,10 @@ inline static void is_builtin_matching( | |||
| 49 | return; | 49 | return; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | if (true == | 52 | should_disable_ht( |
| 53 | should_disable_ht(EG(current_execute_data), function_name, param_value, | 53 | EG(current_execute_data), function_name, param_value, param_name, |
| 54 | param_name, | 54 | SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions, |
| 55 | SNUFFLEUPAGUS_G(config) | 55 | ht); |
| 56 | .config_disabled_functions_reg->disabled_functions, | ||
| 57 | ht)) { | ||
| 58 | } | ||
| 59 | } | 56 | } |
| 60 | 57 | ||
| 61 | static void ZEND_HOT | 58 | static void ZEND_HOT |
| @@ -168,11 +165,9 @@ static void sp_execute_ex(zend_execute_data *execute_data) { | |||
| 168 | !execute_data->prev_execute_data->func || | 165 | !execute_data->prev_execute_data->func || |
| 169 | !ZEND_USER_CODE(execute_data->prev_execute_data->func->type) || | 166 | !ZEND_USER_CODE(execute_data->prev_execute_data->func->type) || |
| 170 | !execute_data->prev_execute_data->opline) { | 167 | !execute_data->prev_execute_data->opline) { |
| 171 | if (UNEXPECTED(true == should_disable_ht(execute_data, function_name, | 168 | should_disable_ht(execute_data, function_name, NULL, NULL, |
| 172 | NULL, NULL, | 169 | config_disabled_functions_reg, |
| 173 | config_disabled_functions_reg, | 170 | config_disabled_functions); |
| 174 | config_disabled_functions))) { | ||
| 175 | } | ||
| 176 | } else if ((execute_data->prev_execute_data->opline->opcode == | 171 | } else if ((execute_data->prev_execute_data->opline->opcode == |
| 177 | ZEND_DO_FCALL || | 172 | ZEND_DO_FCALL || |
| 178 | execute_data->prev_execute_data->opline->opcode == | 173 | execute_data->prev_execute_data->opline->opcode == |
| @@ -181,11 +176,9 @@ static void sp_execute_ex(zend_execute_data *execute_data) { | |||
| 181 | ZEND_DO_ICALL || | 176 | ZEND_DO_ICALL || |
| 182 | execute_data->prev_execute_data->opline->opcode == | 177 | execute_data->prev_execute_data->opline->opcode == |
| 183 | ZEND_DO_FCALL_BY_NAME)) { | 178 | ZEND_DO_FCALL_BY_NAME)) { |
| 184 | if (UNEXPECTED(true == should_disable_ht(execute_data, function_name, | 179 | should_disable_ht(execute_data, function_name, NULL, NULL, |
| 185 | NULL, NULL, | 180 | config_disabled_functions_reg, |
| 186 | config_disabled_functions_reg, | 181 | config_disabled_functions); |
| 187 | config_disabled_functions))) { | ||
| 188 | } | ||
| 189 | } | 182 | } |
| 190 | 183 | ||
| 191 | // When a function's return value isn't used, php doesn't store it in the | 184 | // When a function's return value isn't used, php doesn't store it in the |
| @@ -198,15 +191,11 @@ static void sp_execute_ex(zend_execute_data *execute_data) { | |||
| 198 | 191 | ||
| 199 | orig_execute_ex(execute_data); | 192 | orig_execute_ex(execute_data); |
| 200 | 193 | ||
| 201 | if (UNEXPECTED( | 194 | should_drop_on_ret_ht( |
| 202 | true == | 195 | EX(return_value), function_name, |
| 203 | should_drop_on_ret_ht( | 196 | SNUFFLEUPAGUS_G(config) |
| 204 | EX(return_value), function_name, | 197 | .config_disabled_functions_reg_ret->disabled_functions, |
| 205 | SNUFFLEUPAGUS_G(config) | 198 | SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, execute_data); |
| 206 | .config_disabled_functions_reg_ret->disabled_functions, | ||
| 207 | SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, | ||
| 208 | execute_data))) { | ||
| 209 | } | ||
| 210 | efree(function_name); | 199 | efree(function_name); |
| 211 | 200 | ||
| 212 | if (EX(return_value) == &ret_val) { | 201 | if (EX(return_value) == &ret_val) { |
