summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Fuhrmannek2021-12-14 14:29:43 +0100
committerBen Fuhrmannek2021-12-14 14:29:43 +0100
commit4a45ba42b609d48c8297456d67cc8d955073b567 (patch)
tree947bd03955cd9e8c141f133ab12d3a84bd62611e /src
parent1746eb1013af60d8524a42fb3431446a5933a646 (diff)
fix: include class name in eval whitelist matching
Diffstat (limited to 'src')
-rw-r--r--src/sp_disabled_functions.c17
-rw-r--r--src/sp_execute.c29
-rw-r--r--src/sp_utils.c15
-rw-r--r--src/sp_utils.h8
4 files changed, 25 insertions, 44 deletions
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 216f696..1d9c6c7 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -512,19 +512,13 @@ static void hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) {
512 512
513ZEND_FUNCTION(eval_blacklist_callback) { 513ZEND_FUNCTION(eval_blacklist_callback) {
514 zif_handler orig_handler; 514 zif_handler orig_handler;
515 const char* current_function_name = get_active_function_name(TSRMLS_C); 515 char* current_function_name = get_complete_function_path(EG(current_execute_data));
516 zend_string* tmp =
517 zend_string_init(current_function_name, strlen(current_function_name), 0);
518 516
519 if (true == check_is_in_eval_whitelist(tmp)) { 517 if (!current_function_name || true == check_is_in_eval_whitelist(current_function_name)) {
520 zend_string_release(tmp);
521 goto whitelisted; 518 goto whitelisted;
522 } 519 }
523 zend_string_release(tmp);
524 520
525 if (SPG(in_eval) > 0) { 521 if (SPG(in_eval) > 0) {
526 // zend_string* filename = get_eval_filename(zend_get_executed_filename());
527 // const int line_number = zend_get_executed_lineno(TSRMLS_C);
528 const sp_config_eval* config_eval = &(SPCFG(eval)); 522 const sp_config_eval* config_eval = &(SPCFG(eval));
529 523
530 if (config_eval->dump) { 524 if (config_eval->dump) {
@@ -535,13 +529,12 @@ ZEND_FUNCTION(eval_blacklist_callback) {
535 } else { 529 } else {
536 sp_log_drop("eval", "A call to '%s' was tried in eval. dropping it.", current_function_name); 530 sp_log_drop("eval", "A call to '%s' was tried in eval. dropping it.", current_function_name);
537 } 531 }
538 // efree(filename);
539 } 532 }
540 533
541whitelisted: 534whitelisted:
542 orig_handler = zend_hash_str_find_ptr( 535
543 SPG(sp_eval_blacklist_functions_hook), current_function_name, 536 orig_handler = zend_hash_str_find_ptr(SPG(sp_eval_blacklist_functions_hook), current_function_name, strlen(current_function_name));
544 strlen(current_function_name)); 537 efree(current_function_name);
545 orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); 538 orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
546} 539}
547 540
diff --git a/src/sp_execute.c b/src/sp_execute.c
index f540119..0474fc8 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -48,8 +48,7 @@ inline static void is_builtin_matching(
48 should_disable_ht(EG(current_execute_data), function_name, param_value, param_name, SPCFG(disabled_functions_reg).disabled_functions, ht); 48 should_disable_ht(EG(current_execute_data), function_name, param_value, param_name, SPCFG(disabled_functions_reg).disabled_functions, ht);
49} 49}
50 50
51static void ZEND_HOT 51static void ZEND_HOT is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
52is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
53 const sp_config_eval *config_eval = &(SPCFG(eval)); 52 const sp_config_eval *config_eval = &(SPCFG(eval));
54 53
55 if (EXPECTED(0 == SPG(in_eval))) { 54 if (EXPECTED(0 == SPG(in_eval))) {
@@ -60,35 +59,29 @@ is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
60 return; 59 return;
61 } 60 }
62 61
63 if (zend_is_executing() && !EG(current_execute_data)->func) { 62 if (zend_is_executing() && !EX(func)) {
64 return; // LCOV_EXCL_LINE 63 return; // LCOV_EXCL_LINE
65 } 64 }
66 65
67 if (UNEXPECTED(!(execute_data->func->common.function_name))) { 66 char *function_name = get_complete_function_path(execute_data);
67 if (!function_name) {
68 return; 68 return;
69 } 69 }
70 70
71 zend_string const *const current_function = EX(func)->common.function_name; 71 if (UNEXPECTED(false == check_is_in_eval_whitelist(function_name))) {
72
73 if (EXPECTED(NULL != current_function)) {
74 if (UNEXPECTED(false == check_is_in_eval_whitelist(current_function))) {
75 if (config_eval->dump) { 72 if (config_eval->dump) {
76 sp_log_request(config_eval->dump, config_eval->textual_representation); 73 sp_log_request(config_eval->dump, config_eval->textual_representation);
77 } 74 }
78 if (config_eval->simulation) { 75 if (config_eval->simulation) {
79 sp_log_simulation( 76 sp_log_simulation("Eval_whitelist", "The function '%s' isn't in the eval whitelist, logging its call.", function_name);
80 "Eval_whitelist", 77 goto out;
81 "The function '%s' isn't in the eval whitelist, logging its call.",
82 ZSTR_VAL(current_function));
83 return;
84 } else { 78 } else {
85 sp_log_drop( 79 sp_log_drop("Eval_whitelist", "The function '%s' isn't in the eval whitelist, dropping its call.", function_name);
86 "Eval_whitelist",
87 "The function '%s' isn't in the eval whitelist, dropping its call.",
88 ZSTR_VAL(current_function));
89 } 80 }
90 } 81 }
91 } 82 // }
83out:
84 efree(function_name);
92} 85}
93 86
94/* This function gets the filename in which `eval()` is called from, 87/* This function gets the filename in which `eval()` is called from,
diff --git a/src/sp_utils.c b/src/sp_utils.c
index b53ddcb..034aaf4 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -1,12 +1,5 @@
1#include "php_snuffleupagus.h" 1#include "php_snuffleupagus.h"
2 2
3bool sp_zend_string_equals(const zend_string* s1, const zend_string* s2) {
4 // We can't use `zend_string_equals` here because it doesn't work on
5 // `const` zend_string.
6 return ZSTR_LEN(s1) == ZSTR_LEN(s2) &&
7 !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1));
8}
9
10static const char* default_ipaddr = "0.0.0.0"; 3static const char* default_ipaddr = "0.0.0.0";
11const char* get_ipaddr() { 4const char* get_ipaddr() {
12 const char* client_ip = getenv("REMOTE_ADDR"); 5 const char* client_ip = getenv("REMOTE_ADDR");
@@ -155,8 +148,8 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
155 char* const complete_path_function = get_complete_function_path(current); 148 char* const complete_path_function = get_complete_function_path(current);
156 if (complete_path_function) { 149 if (complete_path_function) {
157 const int current_line = zend_get_executed_lineno(TSRMLS_C); 150 const int current_line = zend_get_executed_lineno(TSRMLS_C);
158 fprintf(file, "STACKTRACE: %s:%d\n", complete_path_function, 151 fprintf(file, "STACKTRACE: %s:%d\n", complete_path_function, current_line);
159 current_line); 152 efree(complete_path_function);
160 } 153 }
161 current = current->prev_execute_data; 154 current = current->prev_execute_data;
162 } 155 }
@@ -468,7 +461,7 @@ void unhook_functions(HashTable *ht) {
468 ZEND_HASH_FOREACH_END_DEL(); 461 ZEND_HASH_FOREACH_END_DEL();
469} 462}
470 463
471bool check_is_in_eval_whitelist(const zend_string* const function_name) { 464bool check_is_in_eval_whitelist(const char* function_name) {
472 const sp_list_node* it = SPCFG(eval).whitelist; 465 const sp_list_node* it = SPCFG(eval).whitelist;
473 if (!it) { 466 if (!it) {
474 return false; 467 return false;
@@ -477,7 +470,7 @@ bool check_is_in_eval_whitelist(const zend_string* const function_name) {
477 /* yes, we could use a HashTable instead, but since the list is pretty 470 /* yes, we could use a HashTable instead, but since the list is pretty
478 * small, it doesn't make a difference in practise. */ 471 * small, it doesn't make a difference in practise. */
479 while (it && it->data) { 472 while (it && it->data) {
480 if (sp_zend_string_equals(function_name, (const zend_string*)(it->data))) { 473 if (sp_zend_string_equals_str((const zend_string*)(it->data), VAR_AND_LEN(function_name))) {
481 /* We've got a match, the function is whiteslited. */ 474 /* We've got a match, the function is whiteslited. */
482 return true; 475 return true;
483 } 476 }
diff --git a/src/sp_utils.h b/src/sp_utils.h
index a4694f2..0581363 100644
--- a/src/sp_utils.h
+++ b/src/sp_utils.h
@@ -85,8 +85,10 @@ void sp_log_disable_ret(const char *restrict, const zend_string *restrict,
85bool hook_function(const char *, HashTable *, zif_handler); 85bool hook_function(const char *, HashTable *, zif_handler);
86void unhook_functions(HashTable *ht); 86void unhook_functions(HashTable *ht);
87int hook_regexp(const sp_pcre *, HashTable *, zif_handler); 87int hook_regexp(const sp_pcre *, HashTable *, zif_handler);
88bool check_is_in_eval_whitelist(const zend_string *const function_name); 88bool check_is_in_eval_whitelist(const char* function_name);
89int sp_log_request(const zend_string *restrict folder, const zend_string *restrict text_repr); 89int sp_log_request(const zend_string *restrict folder, const zend_string *restrict text_repr);
90bool sp_zend_string_equals(const zend_string *s1, const zend_string *s2); 90#define sp_zend_string_equals(s1, s2) zend_string_equals((zend_string*)s1, (zend_string*)s2)
91 91static inline bool sp_zend_string_equals_str(const zend_string* s1, const char *str, size_t len) {
92 return (ZSTR_LEN(s1) == len && !memcmp(ZSTR_VAL(s1), str, len));
93}
92#endif /* SP_UTILS_H */ 94#endif /* SP_UTILS_H */