From 08f21d8b878b6c1490e6d6bb3d44aa640a88e9ca Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sat, 4 Jul 2020 17:56:03 +0200 Subject: Factorize how snuffleupagus gets client's ip addr --- src/sp_disabled_functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 4807955..a6fc194 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -327,7 +327,7 @@ static void should_disable(zend_execute_data* execute_data, } if (config_node->cidr) { - char* client_ip = getenv("REMOTE_ADDR"); + const char* client_ip = get_ipaddr(); if (client_ip && false == cidr_match(client_ip, config_node->cidr)) { goto next; } -- cgit v1.3 From 55087da4701ddfbf4728b3670d8e46c07b4df881 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sat, 4 Jul 2020 17:58:13 +0200 Subject: Run clang-format on the codebase --- src/sp_disabled_functions.c | 2 +- src/sp_network_utils.c | 3 ++- src/sp_sloppy.c | 4 ++-- src/sp_unserialize.c | 1 - src/sp_utils.c | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index a6fc194..c46ee58 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -357,7 +357,7 @@ static void should_disable(zend_execute_data* execute_data, #else execute_data->func->op_array.arg_info->is_variadic #endif - ){ + ) { sp_log_warn( "disable_function", "Snuffleupagus doesn't support variadic functions yet, sorry. " diff --git a/src/sp_network_utils.c b/src/sp_network_utils.c index 1811d98..dc92969 100644 --- a/src/sp_network_utils.c +++ b/src/sp_network_utils.c @@ -17,7 +17,8 @@ static inline bool cidr4_match(const struct in_addr addr, static inline bool cidr6_match(const struct in6_addr address, const struct in6_addr network, uint8_t bits) { -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__APPLE__) const uint32_t *a = address.__u6_addr.__u6_addr32; const uint32_t *n = network.__u6_addr.__u6_addr32; #else diff --git a/src/sp_sloppy.c b/src/sp_sloppy.c index 88052bb..b4212ca 100644 --- a/src/sp_sloppy.c +++ b/src/sp_sloppy.c @@ -3,8 +3,8 @@ ZEND_API zend_op_array* (*orig_zend_compile_file)(zend_file_handle* file_handle, int type) = NULL; #if PHP_VERSION_ID >= 80000 -ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string, - const char* filename) = NULL; +ZEND_API zend_op_array* (*orig_zend_compile_string)( + zval* source_string, const char* filename) = NULL; #else ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string, char* filename) = NULL; diff --git a/src/sp_unserialize.c b/src/sp_unserialize.c index f265ce6..29706c9 100644 --- a/src/sp_unserialize.c +++ b/src/sp_unserialize.c @@ -1,6 +1,5 @@ #include "php_snuffleupagus.h" - PHP_FUNCTION(sp_serialize) { zif_handler orig_handler; diff --git a/src/sp_utils.c b/src/sp_utils.c index 1bd37fe..2665c28 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c @@ -37,8 +37,8 @@ void sp_log_msg(char const* feature, int type, const char* fmt, ...) { const char* error_filename = zend_get_executed_filename(); int syslog_level = (type == SP_LOG_DROP) ? LOG_ERR : LOG_INFO; int error_lineno = zend_get_executed_lineno(TSRMLS_C); - syslog(syslog_level, "[snuffleupagus][%s][%s] %s in %s on line %d", client_ip, feature, msg, - error_filename, error_lineno); + syslog(syslog_level, "[snuffleupagus][%s][%s] %s in %s on line %d", + client_ip, feature, msg, error_filename, error_lineno); closelog(); if (type == SP_LOG_DROP) { zend_bailout(); -- cgit v1.3 From 043d9897b4d6879f9a91dbd0ccdb476649731f7c Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sun, 12 Jul 2020 22:35:48 +0200 Subject: One more const --- src/sp_disabled_functions.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index c46ee58..f35f5ca 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -87,7 +87,8 @@ static bool is_local_var_matching( return true; } } else { - const zend_string* var_value_str = sp_zval_to_zend_string(var_value); + zend_string const* const var_value_str = + sp_zval_to_zend_string(var_value); bool match = sp_match_value(var_value_str, config_node->value, config_node->r_value); -- cgit v1.3 From e8d3cd9b26f0b4d660e424f2657f11bbc01eb171 Mon Sep 17 00:00:00 2001 From: Giovanni Date: Wed, 22 Jul 2020 09:28:42 +0200 Subject: refactoring sp_log_* (#340) Co-authored-by: Giovanni Dante Grazioli --- src/sp_crypt.c | 22 +++++++++++----------- src/sp_disabled_functions.c | 4 ++-- src/sp_execute.c | 12 ++++++------ src/sp_unserialize.c | 9 +++------ src/sp_upload_validation.c | 8 ++++---- src/sp_utils.c | 30 ++++++++++++++---------------- src/sp_utils.h | 21 +++++++++++++++------ 7 files changed, 55 insertions(+), 51 deletions(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/sp_crypt.c b/src/sp_crypt.c index 42c1510..b353ebe 100644 --- a/src/sp_crypt.c +++ b/src/sp_crypt.c @@ -49,16 +49,16 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { if (ZSTR_LEN(debase64) < crypto_secretbox_NONCEBYTES) { if (true == simulation) { - sp_log_msg( - "cookie_encryption", SP_LOG_SIMULATION, + sp_log_simulation( + "cookie_encryption", "Buffer underflow tentative detected in cookie encryption handling " "for %s. Using the cookie 'as it' instead of decrypting it", hash_key ? ZSTR_VAL(hash_key->key) : "the session"); return ZEND_HASH_APPLY_KEEP; } else { // LCOV_EXCL_START - sp_log_msg( - "cookie_encryption", SP_LOG_DROP, + sp_log_drop( + "cookie_encryption", "Buffer underflow tentative detected in cookie encryption handling"); return ZEND_HASH_APPLY_REMOVE; // LCOV_EXCL_STOP @@ -69,15 +69,15 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { if (ZSTR_LEN(debase64) + (size_t)crypto_secretbox_ZEROBYTES < ZSTR_LEN(debase64)) { if (true == simulation) { - sp_log_msg( - "cookie_encryption", SP_LOG_SIMULATION, + sp_log_simulation( + "cookie_encryption", "Integer overflow tentative detected in cookie encryption handling " "for %s. Using the cookie 'as it' instead of decrypting it.", hash_key ? ZSTR_VAL(hash_key->key) : "the session"); return ZEND_HASH_APPLY_KEEP; } else { - sp_log_msg( - "cookie_encryption", SP_LOG_DROP, + sp_log_drop( + "cookie_encryption", "Integer overflow tentative detected in cookie encryption handling."); return ZEND_HASH_APPLY_REMOVE; } @@ -98,8 +98,8 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { if (-1 == ret) { if (true == simulation) { - sp_log_msg( - "cookie_encryption", SP_LOG_SIMULATION, + sp_log_simulation( + "cookie_encryption", "Something went wrong with the decryption of %s. Using the cookie " "'as it' instead of decrypting it", hash_key ? ZSTR_VAL(hash_key->key) : "the session"); @@ -107,7 +107,7 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { efree(backup); return ZEND_HASH_APPLY_KEEP; } else { - sp_log_msg("cookie_encryption", SP_LOG_WARN, + sp_log_warn("cookie_encryption", "Something went wrong with the decryption of %s", hash_key ? ZSTR_VAL(hash_key->key) : "the session"); efree(backup); diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index f35f5ca..a7136df 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -574,11 +574,11 @@ ZEND_FUNCTION(eval_blacklist_callback) { SP_TOKEN_EVAL_BLACKLIST); } if (config_eval->simulation) { - sp_log_msg("eval", SP_LOG_SIMULATION, + sp_log_simulation("eval", "A call to %s was tried in eval, in %s:%d, logging it.", current_function_name, ZSTR_VAL(filename), line_number); } else { - sp_log_msg("eval", SP_LOG_DROP, + sp_log_drop("eval", "A call to %s was tried in eval, in %s:%d, dropping it.", current_function_name, ZSTR_VAL(filename), line_number); } diff --git a/src/sp_execute.c b/src/sp_execute.c index 4eae874..73cc560 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c @@ -18,10 +18,10 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) { SP_TOKEN_READONLY_EXEC); } if (true == config_ro_exec->simulation) { - sp_log_msg("readonly_exec", SP_LOG_SIMULATION, + sp_log_simulation("readonly_exec", "Attempted execution of a writable file (%s).", filename); } else { - sp_log_msg("readonly_exec", SP_LOG_DROP, + sp_log_drop("readonly_exec", "Attempted execution of a writable file (%s).", filename); zend_bailout(); } @@ -79,14 +79,14 @@ is_in_eval_and_whitelisted(const zend_execute_data *execute_data) { SP_TOKEN_EVAL_WHITELIST); } if (config_eval->simulation) { - sp_log_msg( - "Eval_whitelist", SP_LOG_SIMULATION, + sp_log_simulation( + "Eval_whitelist", "The function '%s' isn't in the eval whitelist, logging its call.", ZSTR_VAL(current_function)); return; } else { - sp_log_msg( - "Eval_whitelist", SP_LOG_DROP, + sp_log_drop( + "Eval_whitelist", "The function '%s' isn't in the eval whitelist, dropping its call.", ZSTR_VAL(current_function)); } diff --git a/src/sp_unserialize.c b/src/sp_unserialize.c index 29706c9..8977dd9 100644 --- a/src/sp_unserialize.c +++ b/src/sp_unserialize.c @@ -61,8 +61,7 @@ PHP_FUNCTION(sp_unserialize) { /* 64 is the length of HMAC-256 */ if (buf_len < 64) { - sp_log_msg("unserialize", SP_LOG_DROP, - "The serialized object is too small."); + sp_log_drop("unserialize", "The serialized object is too small."); } hmac = buf + buf_len - 64; @@ -99,16 +98,14 @@ PHP_FUNCTION(sp_unserialize) { SP_TOKEN_UNSERIALIZE_HMAC); } if (true == config_unserialize->simulation) { - sp_log_msg("unserialize", SP_LOG_SIMULATION, "Invalid HMAC for %s", - serialized_str); + sp_log_simulation("unserialize", "Invalid HMAC for %s", serialized_str); if ((orig_handler = zend_hash_str_find_ptr( SNUFFLEUPAGUS_G(sp_internal_functions_hook), "unserialize", sizeof("unserialize") - 1))) { orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); } } else { - sp_log_msg("unserialize", SP_LOG_DROP, "Invalid HMAC for %s", - serialized_str); + sp_log_drop("unserialize", "Invalid HMAC for %s", serialized_str); } } efree(serialized_str); diff --git a/src/sp_upload_validation.c b/src/sp_upload_validation.c index 54b0481..4ee7bd7 100644 --- a/src/sp_upload_validation.c +++ b/src/sp_upload_validation.c @@ -13,7 +13,7 @@ int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra); int sp_rfc1867_callback_win(unsigned int event, void *event_data, void **extra) { - sp_log_msg("upload_validation", SP_LOG_SIMULATION, + sp_log_simulation("upload_validation", "The upload validation doesn't work for now on Windows yet, " "see https://github.com/jvoisin/snuffleupagus/issues/248 for " "details."); @@ -90,9 +90,9 @@ int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra) { if (WEXITSTATUS(waitstatus) != 0) { // Nope char *uri = getenv("REQUEST_URI"); int sim = config_upload->simulation; - sp_log_msg("upload_validation", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, - "The upload of %s on %s was rejected.", filename, - uri ? uri : "?"); + sp_log_auto("upload_validation", sim, + "The upload of %s on %s was rejected.", + filename, uri ? uri : "?"); } } ZEND_HASH_FOREACH_END(); diff --git a/src/sp_utils.c b/src/sp_utils.c index 146fe77..8032e0a 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c @@ -40,7 +40,7 @@ const char* get_ipaddr() { return default_ipaddr; } -void sp_log_msg(char const* restrict feature, int type, +void sp_log_msgf(char const* restrict feature, int level, int type, const char* restrict fmt, ...) { char* msg; va_list args; @@ -51,16 +51,14 @@ void sp_log_msg(char const* restrict feature, int type, const char* client_ip = get_ipaddr(); const char* logtype = NULL; - int bailout = type == SP_LOG_DROP; switch(type) { - case SP_LOG_SIMULATION: + case SP_TYPE_SIMULATION: logtype = "simulation"; - type = E_WARNING; break; - case SP_LOG_DROP: + case SP_TYPE_DROP: logtype = "drop"; - type = E_ERROR; break; + case SP_TYPE_LOG: default: logtype = "log"; break; @@ -69,20 +67,20 @@ void sp_log_msg(char const* restrict feature, int type, switch (SNUFFLEUPAGUS_G(config).log_media) { case SP_SYSLOG: { const char* error_filename = zend_get_executed_filename(); - int syslog_level = (type == E_ERROR) ? LOG_ERR : LOG_INFO; + int syslog_level = (level == E_ERROR) ? LOG_ERR : LOG_INFO; int error_lineno = zend_get_executed_lineno(TSRMLS_C); openlog(PHP_SNUFFLEUPAGUS_EXTNAME, LOG_PID, LOG_AUTH); syslog(syslog_level, "[snuffleupagus][%s][%s][%s] %s in %s on line %d", client_ip, feature, logtype, msg, error_filename, error_lineno); closelog(); - if (bailout) { + if (type == SP_TYPE_DROP) { zend_bailout(); } break; } case SP_ZEND: default: - zend_error(type, "[snuffleupagus][%s][%s][%s] %s", client_ip, feature, logtype, msg); + zend_error(level, "[snuffleupagus][%s][%s][%s] %s", client_ip, feature, logtype, msg); break; } } @@ -282,12 +280,12 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name, char_repr = zend_string_to_char(arg_value); } if (alias) { - sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, + sp_log_auto("disabled_function", sim, "Aborted execution on call of the function '%s', " "because its argument '%s' content (%s) matched the rule '%s'", path, arg_name, char_repr ? char_repr : "?", ZSTR_VAL(alias)); } else { - sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, + sp_log_auto("disabled_function", sim, "Aborted execution on call of the function '%s', " "because its argument '%s' content (%s) matched a rule", path, arg_name, char_repr ? char_repr : "?"); @@ -295,12 +293,12 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name, efree(char_repr); } else { if (alias) { - sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, + sp_log_auto("disabled_function", sim, "Aborted execution on call of the function '%s', " "because of the the rule '%s'", path, ZSTR_VAL(alias)); } else { - sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, + sp_log_auto("disabled_function", sim, "Aborted execution on call of the function '%s'", path); } } @@ -322,13 +320,13 @@ void sp_log_disable_ret(const char* restrict path, char_repr = zend_string_to_char(ret_value); } if (alias) { - sp_log_msg( - "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, + sp_log_auto( + "disabled_function", sim, "Aborted execution on return of the function '%s', " "because the function returned '%s', which matched the rule '%s'", path, char_repr ? char_repr : "?", ZSTR_VAL(alias)); } else { - sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, + sp_log_auto("disabled_function", sim, "Aborted execution on return of the function '%s', " "because the function returned '%s', which matched a rule", path, char_repr ? char_repr : "?"); diff --git a/src/sp_utils.h b/src/sp_utils.h index 91a5a20..744bbff 100644 --- a/src/sp_utils.h +++ b/src/sp_utils.h @@ -28,16 +28,25 @@ #define HOOK_FUNCTION_BY_REGEXP(regexp, hook_table, new_function) \ hook_regexp(regexp, SNUFFLEUPAGUS_G(hook_table), new_function) -#define SP_LOG_SIMULATION 0x100000 -#define SP_LOG_DROP 0x200000 +#define SP_TYPE_LOG (0) +#define SP_TYPE_DROP (1) +#define SP_TYPE_SIMULATION (2) + #define SP_LOG_DEBUG E_NOTICE #define SP_LOG_ERROR E_ERROR #define SP_LOG_WARN E_WARNING -#define sp_log_err(feature, ...) sp_log_msg(feature, SP_LOG_ERROR, __VA_ARGS__) -#define sp_log_warn(feature, ...) sp_log_msg(feature, SP_LOG_WARN, __VA_ARGS__) +#define sp_log_msg(feature, level, ...) sp_log_msgf(feature, level, SP_TYPE_LOG, __VA_ARGS__) +#define sp_log_drop(feature, ...) sp_log_msgf(feature, SP_LOG_ERROR, SP_TYPE_DROP, __VA_ARGS__) +#define sp_log_simulation(feature, ...) sp_log_msgf(feature, SP_LOG_WARN, SP_TYPE_SIMULATION, __VA_ARGS__) +#define sp_log_auto(feature, is_simulation, ...) sp_log_msgf(feature, \ + (is_simulation ? SP_LOG_WARN : SP_LOG_ERROR), \ + (is_simulation ? SP_TYPE_SIMULATION : SP_TYPE_DROP), __VA_ARGS__) + +#define sp_log_err(feature, ...) sp_log_msgf(feature, SP_LOG_ERROR, SP_TYPE_LOG, __VA_ARGS__) +#define sp_log_warn(feature, ...) sp_log_msgf(feature, SP_LOG_WARN, SP_TYPE_LOG, __VA_ARGS__) #ifdef SP_DEBUG -#define sp_log_debug(...) sp_log_msg("DEBUG", SP_LOG_DEBUG, __VA_ARGS__) +#define sp_log_debug(...) sp_log_msgf("DEBUG", SP_LOG_DEBUG, SP_TYPE_LOG, __VA_ARGS__) #else #define sp_log_debug(...) #endif @@ -45,7 +54,7 @@ #define GET_SUFFIX(x) (x == 1) ? "st" : ((x == 2) ? "nd" : "th") const char *get_ipaddr(); -void sp_log_msg(char const *restrict feature, int type, +void sp_log_msgf(char const *restrict feature, int level, int type, const char *restrict fmt, ...); int compute_hash(const char *const restrict filename, char *restrict file_hash); const zend_string *sp_zval_to_zend_string(const zval *); -- cgit v1.3 From a0d21a189cf04bb963dce93dcbd0bd9694584a0b Mon Sep 17 00:00:00 2001 From: jvoisin Date: Wed, 12 Aug 2020 08:48:59 +0000 Subject: Allow empty configuration (#342) This commit allows php to run (with a warning) if there is no specified snuffleupagus configuration, instead of refusing to start.--- src/php_snuffleupagus.h | 6 +++- src/snuffleupagus.c | 34 ++++++++++++++------ src/sp_crypt.c | 4 +-- src/sp_disabled_functions.c | 8 ++--- src/sp_execute.c | 5 +-- src/sp_upload_validation.c | 13 ++++---- src/sp_utils.c | 36 ++++++++++++---------- .../broken_conf_no_file_specified.phpt | 4 +-- src/tests/loading.phpt | 4 +-- 9 files changed, 69 insertions(+), 45 deletions(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h index 0849d36..6b0e210 100644 --- a/src/php_snuffleupagus.h +++ b/src/php_snuffleupagus.h @@ -62,6 +62,10 @@ typedef void (*zif_handler)(INTERNAL_FUNCTION_PARAMETERS); #define TSRMLS_C #endif +#define SP_CONFIG_VALID 1 +#define SP_CONFIG_INVALID 0 +#define SP_CONFIG_NONE -1 + #include "sp_pcre_compat.h" #include "sp_list.h" #include "sp_tree.h" @@ -101,7 +105,7 @@ extern zend_module_entry snuffleupagus_module_entry; ZEND_BEGIN_MODULE_GLOBALS(snuffleupagus) size_t in_eval; sp_config config; -bool is_config_valid; +int is_config_valid; // 1 = valid, 0 = invalid, -1 = none bool allow_broken_configuration; HashTable *disabled_functions_hook; HashTable *sp_internal_functions_hook; diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c index d62069c..7c69150 100644 --- a/src/snuffleupagus.c +++ b/src/snuffleupagus.c @@ -68,6 +68,7 @@ ZEND_DLEXPORT zend_extension zend_extension_entry = { STANDARD_ZEND_EXTENSION_PROPERTIES}; PHP_GINIT_FUNCTION(snuffleupagus) { + snuffleupagus_globals->is_config_valid = SP_CONFIG_NONE; snuffleupagus_globals->in_eval = 0; #define SP_INIT_HT(F) snuffleupagus_globals->F = \ @@ -186,8 +187,12 @@ PHP_RINIT_FUNCTION(snuffleupagus) { ZEND_TSRMLS_CACHE_UPDATE(); #endif - if (!SNUFFLEUPAGUS_G(allow_broken_configuration) && !SNUFFLEUPAGUS_G(is_config_valid)) { - sp_log_err("config", "Invalid configuration file"); + if (!SNUFFLEUPAGUS_G(allow_broken_configuration)) { + if (SNUFFLEUPAGUS_G(is_config_valid) == SP_CONFIG_INVALID ) { + sp_log_err("config", "Invalid configuration file"); + } else if (SNUFFLEUPAGUS_G(is_config_valid) == SP_CONFIG_NONE) { + sp_log_warn("config", "No configuration specificed via sp.configuration_file"); + } } // We need to disable wrappers loaded by extensions loaded after SNUFFLEUPAGUS. @@ -209,12 +214,23 @@ PHP_RINIT_FUNCTION(snuffleupagus) { PHP_RSHUTDOWN_FUNCTION(snuffleupagus) { return SUCCESS; } PHP_MINFO_FUNCTION(snuffleupagus) { + const char *valid_config; + switch(SNUFFLEUPAGUS_G(is_config_valid)) { + case SP_CONFIG_VALID: + valid_config = "yes"; + break; + case SP_CONFIG_INVALID: + valid_config = "invalid"; + break; + case SP_CONFIG_NONE: + default: + valid_config = "no"; + } php_info_print_table_start(); - php_info_print_table_row(2, "snuffleupagus support", "enabled"); + php_info_print_table_row(2, "snuffleupagus support", + SNUFFLEUPAGUS_G(is_config_valid)?"enabled":"disabled"); php_info_print_table_row(2, "Version", PHP_SNUFFLEUPAGUS_VERSION); - php_info_print_table_row( - 2, "Valid config", - (SNUFFLEUPAGUS_G(is_config_valid) == true) ? "yes" : "no"); + php_info_print_table_row( 2, "Valid config", valid_config); php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } @@ -234,14 +250,14 @@ static PHP_INI_MH(OnUpdateConfiguration) { int ret = glob(config_file, GLOB_NOCHECK, NULL, &globbuf); if (ret != 0) { - SNUFFLEUPAGUS_G(is_config_valid) = false; + SNUFFLEUPAGUS_G(is_config_valid) = SP_CONFIG_INVALID; globfree(&globbuf); return FAILURE; } for (size_t i = 0; globbuf.gl_pathv[i]; i++) { if (sp_parse_config(globbuf.gl_pathv[i]) != SUCCESS) { - SNUFFLEUPAGUS_G(is_config_valid) = false; + SNUFFLEUPAGUS_G(is_config_valid) = SP_CONFIG_INVALID; globfree(&globbuf); return FAILURE; } @@ -249,7 +265,7 @@ static PHP_INI_MH(OnUpdateConfiguration) { globfree(&globbuf); } - SNUFFLEUPAGUS_G(is_config_valid) = true; + SNUFFLEUPAGUS_G(is_config_valid) = SP_CONFIG_VALID; if ((SNUFFLEUPAGUS_G(config).config_sloppy->enable)) { hook_sloppy(); diff --git a/src/sp_crypt.c b/src/sp_crypt.c index b353ebe..c57ac0b 100644 --- a/src/sp_crypt.c +++ b/src/sp_crypt.c @@ -108,8 +108,8 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { return ZEND_HASH_APPLY_KEEP; } else { sp_log_warn("cookie_encryption", - "Something went wrong with the decryption of %s", - hash_key ? ZSTR_VAL(hash_key->key) : "the session"); + "Something went wrong with the decryption of %s", + hash_key ? ZSTR_VAL(hash_key->key) : "the session"); efree(backup); return ZEND_HASH_APPLY_REMOVE; } diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index a7136df..7be1c34 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -575,12 +575,12 @@ ZEND_FUNCTION(eval_blacklist_callback) { } if (config_eval->simulation) { sp_log_simulation("eval", - "A call to %s was tried in eval, in %s:%d, logging it.", - current_function_name, ZSTR_VAL(filename), line_number); + "A call to %s was tried in eval, in %s:%d, logging it.", + current_function_name, ZSTR_VAL(filename), line_number); } else { sp_log_drop("eval", - "A call to %s was tried in eval, in %s:%d, dropping it.", - current_function_name, ZSTR_VAL(filename), line_number); + "A call to %s was tried in eval, in %s:%d, dropping it.", + current_function_name, ZSTR_VAL(filename), line_number); } efree(filename); } diff --git a/src/sp_execute.c b/src/sp_execute.c index 73cc560..140e227 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c @@ -19,10 +19,11 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) { } if (true == config_ro_exec->simulation) { sp_log_simulation("readonly_exec", - "Attempted execution of a writable file (%s).", filename); + "Attempted execution of a writable file (%s).", + filename); } else { sp_log_drop("readonly_exec", - "Attempted execution of a writable file (%s).", filename); + "Attempted execution of a writable file (%s).", filename); zend_bailout(); } } else { diff --git a/src/sp_upload_validation.c b/src/sp_upload_validation.c index 4ee7bd7..f3ae311 100644 --- a/src/sp_upload_validation.c +++ b/src/sp_upload_validation.c @@ -13,10 +13,11 @@ int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra); int sp_rfc1867_callback_win(unsigned int event, void *event_data, void **extra) { - sp_log_simulation("upload_validation", - "The upload validation doesn't work for now on Windows yet, " - "see https://github.com/jvoisin/snuffleupagus/issues/248 for " - "details."); + sp_log_simulation( + "upload_validation", + "The upload validation doesn't work for now on Windows yet, " + "see https://github.com/jvoisin/snuffleupagus/issues/248 for " + "details."); return SUCCESS; } @@ -91,8 +92,8 @@ int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra) { char *uri = getenv("REQUEST_URI"); int sim = config_upload->simulation; sp_log_auto("upload_validation", sim, - "The upload of %s on %s was rejected.", - filename, uri ? uri : "?"); + "The upload of %s on %s was rejected.", filename, + uri ? uri : "?"); } } ZEND_HASH_FOREACH_END(); diff --git a/src/sp_utils.c b/src/sp_utils.c index 8032e0a..4c78ce5 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c @@ -41,7 +41,7 @@ const char* get_ipaddr() { } void sp_log_msgf(char const* restrict feature, int level, int type, - const char* restrict fmt, ...) { + const char* restrict fmt, ...) { char* msg; va_list args; @@ -51,7 +51,7 @@ void sp_log_msgf(char const* restrict feature, int level, int type, const char* client_ip = get_ipaddr(); const char* logtype = NULL; - switch(type) { + switch (type) { case SP_TYPE_SIMULATION: logtype = "simulation"; break; @@ -80,7 +80,8 @@ void sp_log_msgf(char const* restrict feature, int level, int type, } case SP_ZEND: default: - zend_error(level, "[snuffleupagus][%s][%s][%s] %s", client_ip, feature, logtype, msg); + zend_error(level, "[snuffleupagus][%s][%s][%s] %s", client_ip, feature, + logtype, msg); break; } } @@ -280,26 +281,27 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name, char_repr = zend_string_to_char(arg_value); } if (alias) { - sp_log_auto("disabled_function", sim, - "Aborted execution on call of the function '%s', " - "because its argument '%s' content (%s) matched the rule '%s'", - path, arg_name, char_repr ? char_repr : "?", ZSTR_VAL(alias)); + sp_log_auto( + "disabled_function", sim, + "Aborted execution on call of the function '%s', " + "because its argument '%s' content (%s) matched the rule '%s'", + path, arg_name, char_repr ? char_repr : "?", ZSTR_VAL(alias)); } else { sp_log_auto("disabled_function", sim, - "Aborted execution on call of the function '%s', " - "because its argument '%s' content (%s) matched a rule", - path, arg_name, char_repr ? char_repr : "?"); + "Aborted execution on call of the function '%s', " + "because its argument '%s' content (%s) matched a rule", + path, arg_name, char_repr ? char_repr : "?"); } efree(char_repr); } else { if (alias) { sp_log_auto("disabled_function", sim, - "Aborted execution on call of the function '%s', " - "because of the the rule '%s'", - path, ZSTR_VAL(alias)); + "Aborted execution on call of the function '%s', " + "because of the the rule '%s'", + path, ZSTR_VAL(alias)); } else { sp_log_auto("disabled_function", sim, - "Aborted execution on call of the function '%s'", path); + "Aborted execution on call of the function '%s'", path); } } } @@ -327,9 +329,9 @@ void sp_log_disable_ret(const char* restrict path, path, char_repr ? char_repr : "?", ZSTR_VAL(alias)); } else { sp_log_auto("disabled_function", sim, - "Aborted execution on return of the function '%s', " - "because the function returned '%s', which matched a rule", - path, char_repr ? char_repr : "?"); + "Aborted execution on return of the function '%s', " + "because the function returned '%s', which matched a rule", + path, char_repr ? char_repr : "?"); } efree(char_repr); } diff --git a/src/tests/broken_configuration/broken_conf_no_file_specified.phpt b/src/tests/broken_configuration/broken_conf_no_file_specified.phpt index 8b360d4..cb2d95f 100644 --- a/src/tests/broken_configuration/broken_conf_no_file_specified.phpt +++ b/src/tests/broken_configuration/broken_conf_no_file_specified.phpt @@ -6,5 +6,5 @@ Broken configuration - No configuration file specified --FILE-- --EXPECT-- -Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 -Could not startup. +Warning: [snuffleupagus][0.0.0.0][config][log] No configuration specificed via sp.configuration_file in Unknown on line 0 +1 diff --git a/src/tests/loading.phpt b/src/tests/loading.phpt index 761917a..2514ec5 100644 --- a/src/tests/loading.phpt +++ b/src/tests/loading.phpt @@ -7,5 +7,5 @@ Check for snuffleupagus presence echo "snuffleupagus extension is available"; ?> --EXPECT-- -Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 -Could not startup. +Warning: [snuffleupagus][0.0.0.0][config][log] No configuration specificed via sp.configuration_file in Unknown on line 0 +snuffleupagus extension is available -- cgit v1.3 From 5be9082f148ab546a0317a28ef5267bb797feb53 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sun, 29 Nov 2020 19:37:49 +0100 Subject: Make the `>` operator skip over functions --- doc/source/config.rst | 3 ++- src/sp_disabled_functions.c | 8 +++--- .../config_disabled_functions_chain_call_skip.ini | 1 + .../disabled_functions_chain_call_skip.phpt | 29 ++++++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/tests/disable_function/config/config_disabled_functions_chain_call_skip.ini create mode 100644 src/tests/disable_function/disabled_functions_chain_call_skip.phpt (limited to 'src/sp_disabled_functions.c') diff --git a/doc/source/config.rst b/doc/source/config.rst index dd30723..258b1ab 100644 --- a/doc/source/config.rst +++ b/doc/source/config.rst @@ -328,7 +328,8 @@ The ``function`` filter is able to do various dereferencing: - ``function("AwesomeNamespace\\my_function")`` will match the function ``my_function`` in the namespace ``AwesomeNamespace`` It's also able to have calltrace constrains: ``function(func1>func2)`` will -match only if ``func2`` is called **inside** of ``func1``. +match only if ``func2`` is called **inside** of ``func1``. Do note that their +might be other functions called between them. The ``param`` filter is able to do some dereferencing as well: diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 7be1c34..7e6ca6a 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -40,7 +40,7 @@ static bool is_functions_list_matching(zend_execute_data* execute_data, sp_list_node* functions_list) { zend_execute_data *orig_execute_data, *current; orig_execute_data = current = execute_data; - sp_list_node* it = functions_list; + sp_list_node const * it = functions_list; while (current) { if (it == NULL) { // every function in the list matched, we've got a match! @@ -50,7 +50,7 @@ static bool is_functions_list_matching(zend_execute_data* execute_data, EG(current_execute_data) = current; - char* complete_path_function = get_complete_function_path(current); + char* const complete_path_function = get_complete_function_path(current); if (!complete_path_function) { break; } @@ -59,10 +59,8 @@ static bool is_functions_list_matching(zend_execute_data* execute_data, if (0 == match) { it = it->next; - current = current->prev_execute_data; - } else { - break; } + current = current->prev_execute_data; } EG(current_execute_data) = orig_execute_data; diff --git a/src/tests/disable_function/config/config_disabled_functions_chain_call_skip.ini b/src/tests/disable_function/config/config_disabled_functions_chain_call_skip.ini new file mode 100644 index 0000000..4d2f68d --- /dev/null +++ b/src/tests/disable_function/config/config_disabled_functions_chain_call_skip.ini @@ -0,0 +1 @@ +sp.disable_function.function("a>c").simulation().drop(); diff --git a/src/tests/disable_function/disabled_functions_chain_call_skip.phpt b/src/tests/disable_function/disabled_functions_chain_call_skip.phpt new file mode 100644 index 0000000..9ff84b9 --- /dev/null +++ b/src/tests/disable_function/disabled_functions_chain_call_skip.phpt @@ -0,0 +1,29 @@ +--TEST-- +Disable functions by matching the calltrace, with a superfluous function in between +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/config_disabled_functions_chain_call_skip.ini +--FILE-- + +--EXPECTF-- +I'm in the `a` function! +I'm in the `b` function! + +Warning: [snuffleupagus][0.0.0.0][disabled_function][simulation] Aborted execution on call of the function 'a>c' in %s/tests/disable_function/disabled_functions_chain_call_skip.php on line 12 +I'm in the `c` function! -- cgit v1.3 From 69719e42994c0e42ae45124acef7835955a5272d Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sun, 29 Nov 2020 20:46:48 +0100 Subject: Fix zend_write booking type The signature was changed in PHP8: https://github.com/php/php-src/commit/e15409b43cacf711608189c299191f2969ea331c --- src/sp_disabled_functions.c | 4 ++++ src/sp_disabled_functions.h | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 7e6ca6a..c5ea437 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -626,7 +626,11 @@ int hook_disabled_functions(void) { zend_write_func_t zend_write_default = NULL; +#if PHP_VERSION_ID >= 80000 +size_t hook_echo(const char* str, size_t str_length) { +#else int hook_echo(const char* str, size_t str_length) { +#endif zend_string* zs = zend_string_init(str, str_length, 0); should_disable_ht( diff --git a/src/sp_disabled_functions.h b/src/sp_disabled_functions.h index baf40dd..fd9b9b9 100644 --- a/src/sp_disabled_functions.h +++ b/src/sp_disabled_functions.h @@ -3,8 +3,12 @@ extern zend_write_func_t zend_write_default; -int hook_disabled_functions(void); +#if PHP_VERSION_ID >= 80000 +size_t hook_echo(const char *, size_t); +#else int hook_echo(const char *, size_t); +#endif +int hook_disabled_functions(void); void should_disable_ht(zend_execute_data *, const char *, const zend_string *, const char *, const sp_list_node *, const HashTable *); void should_drop_on_ret_ht(const zval *, const char *, -- cgit v1.3 From 837fbdb88a513500520f057d27bdfedd0d3995ca Mon Sep 17 00:00:00 2001 From: jvoisin Date: Fri, 1 Jan 2021 16:31:33 +0100 Subject: Constify a function --- src/sp_disabled_functions.c | 4 ++-- src/sp_pcre_compat.c | 6 ++++-- src/sp_pcre_compat.h | 1 - src/sp_sloppy.c | 3 ++- src/sp_utils.c | 3 ++- src/sp_utils.h | 3 ++- 6 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index c5ea437..41c9f23 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -40,7 +40,7 @@ static bool is_functions_list_matching(zend_execute_data* execute_data, sp_list_node* functions_list) { zend_execute_data *orig_execute_data, *current; orig_execute_data = current = execute_data; - sp_list_node const * it = functions_list; + sp_list_node const* it = functions_list; while (current) { if (it == NULL) { // every function in the list matched, we've got a match! @@ -60,7 +60,7 @@ static bool is_functions_list_matching(zend_execute_data* execute_data, if (0 == match) { it = it->next; } - current = current->prev_execute_data; + current = current->prev_execute_data; } EG(current_execute_data) = orig_execute_data; diff --git a/src/sp_pcre_compat.c b/src/sp_pcre_compat.c index d2efc71..b4d29f0 100644 --- a/src/sp_pcre_compat.c +++ b/src/sp_pcre_compat.c @@ -14,7 +14,8 @@ sp_pcre* sp_pcre_compile(const char* const pattern) { #else const char* pcre_error = NULL; int erroroffset; - ret = php_pcre_compile(pattern, PCRE_CASELESS, &pcre_error, &erroroffset, NULL); + ret = + php_pcre_compile(pattern, PCRE_CASELESS, &pcre_error, &erroroffset, NULL); #endif if (NULL == ret) { @@ -37,7 +38,8 @@ bool ZEND_HOT sp_is_regexp_matching_len(const sp_pcre* regexp, const char* str, ret = pcre2_match(regexp, (PCRE2_SPTR)str, len, 0, 0, match_data, NULL); #else int vec[30]; - ret = php_pcre_exec(regexp, NULL, str, len, 0, 0, vec, sizeof(vec) / sizeof(int)); + ret = php_pcre_exec(regexp, NULL, str, len, 0, 0, vec, + sizeof(vec) / sizeof(int)); #endif if (ret < 0) { diff --git a/src/sp_pcre_compat.h b/src/sp_pcre_compat.h index b70630d..11f7f7c 100644 --- a/src/sp_pcre_compat.h +++ b/src/sp_pcre_compat.h @@ -7,7 +7,6 @@ #undef pcre_exec #undef pcre_compile - #define PCRE2_CODE_UNIT_WIDTH 8 #if PHP_VERSION_ID >= 70300 #define SP_HAS_PCRE2 diff --git a/src/sp_sloppy.c b/src/sp_sloppy.c index d9c9e8d..f9ed718 100644 --- a/src/sp_sloppy.c +++ b/src/sp_sloppy.c @@ -26,7 +26,8 @@ static void modify_opcode(zend_op_array* opline) { } #if PHP_VERSION_ID >= 80000 -ZEND_API zend_op_array* sp_compile_string(zend_string* source_string, const char* filename) { +ZEND_API zend_op_array* sp_compile_string(zend_string* source_string, + const char* filename) { #else ZEND_API zend_op_array* sp_compile_string(zval* source_string, char* filename) { #endif diff --git a/src/sp_utils.c b/src/sp_utils.c index cb63037..04074bf 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c @@ -140,7 +140,8 @@ static int construct_filename(char* filename, } int sp_log_request(const zend_string* restrict folder, - const zend_string* restrict text_repr, char* from) { + const zend_string* restrict text_repr, + char const* const from) { FILE* file; const char* current_filename = zend_get_executed_filename(TSRMLS_C); const int current_line = zend_get_executed_lineno(TSRMLS_C); diff --git a/src/sp_utils.h b/src/sp_utils.h index 24c74bf..a883d6d 100644 --- a/src/sp_utils.h +++ b/src/sp_utils.h @@ -76,7 +76,8 @@ int hook_function(const char *, HashTable *, zif_handler); int hook_regexp(const sp_pcre *, HashTable *, zif_handler); bool check_is_in_eval_whitelist(const zend_string *const function_name); int sp_log_request(const zend_string *restrict folder, - const zend_string *restrict text_repr, char *from); + const zend_string *restrict text_repr, + char const *const from); bool sp_zend_string_equals(const zend_string *s1, const zend_string *s2); #endif /* SP_UTILS_H */ -- cgit v1.3 From 467f965bf178b1c4d60ddac87af14718f6013bab Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sat, 30 Jan 2021 21:19:29 +0100 Subject: Improve a bit type diversity --- src/sp_disabled_functions.c | 17 +++++++---------- src/sp_utils.c | 8 ++++---- src/sp_utils.h | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) (limited to 'src/sp_disabled_functions.c') diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 41c9f23..6a559c8 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -532,13 +532,13 @@ static int hook_functions_regexp(const sp_list_node* config) { return SUCCESS; } -static int hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) { +static void hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) { zend_string* key; zval* value; ZEND_HASH_FOREACH_STR_KEY_VAL(to_hook_ht, key, value) { - bool hooked = !HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, - PHP_FN(check_disabled_function)); + bool hooked = HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, + PHP_FN(check_disabled_function)); bool is_builtin = check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data); if (hooked || is_builtin) { @@ -547,7 +547,6 @@ static int hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) { } } ZEND_HASH_FOREACH_END(); - return SUCCESS; } ZEND_FUNCTION(eval_blacklist_callback) { @@ -595,13 +594,11 @@ int hook_disabled_functions(void) { int ret = SUCCESS; - ret |= - hook_functions(SNUFFLEUPAGUS_G(config).config_disabled_functions, - SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked); + hook_functions(SNUFFLEUPAGUS_G(config).config_disabled_functions, + SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked); - ret |= hook_functions( - SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, - SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked); + hook_functions(SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, + SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked); ret |= hook_functions_regexp( SNUFFLEUPAGUS_G(config) diff --git a/src/sp_utils.c b/src/sp_utils.c index 147cc46..a7a3d27 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c @@ -394,10 +394,10 @@ bool sp_match_array_value(const zval* arr, const zend_string* to_match, return false; } -int hook_function(const char* original_name, HashTable* hook_table, - zif_handler new_function) { +bool hook_function(const char* original_name, HashTable* hook_table, + zif_handler new_function) { zend_internal_function* func; - bool ret = FAILURE; + bool ret = false; /* The `mb` module likes to hook functions, like strlen->mb_strlen, * so we have to hook both of them. */ @@ -416,7 +416,7 @@ int hook_function(const char* original_name, HashTable* hook_table, // LCOV_EXCL_STOP } func->handler = new_function; - ret = SUCCESS; + ret = true; } } diff --git a/src/sp_utils.h b/src/sp_utils.h index a883d6d..081f786 100644 --- a/src/sp_utils.h +++ b/src/sp_utils.h @@ -72,7 +72,7 @@ void sp_log_disable(const char *restrict, const char *restrict, const zend_string *restrict, const sp_disabled_function *); void sp_log_disable_ret(const char *restrict, const zend_string *restrict, const sp_disabled_function *); -int hook_function(const char *, HashTable *, zif_handler); +bool hook_function(const char *, HashTable *, zif_handler); int hook_regexp(const sp_pcre *, HashTable *, zif_handler); bool check_is_in_eval_whitelist(const zend_string *const function_name); int sp_log_request(const zend_string *restrict folder, -- cgit v1.3