diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/sp_config.h | 2 | ||||
| -rw-r--r-- | src/sp_config_keywords.c | 23 | ||||
| -rw-r--r-- | src/sp_disabled_functions.c | 14 | ||||
| -rw-r--r-- | src/tests/broken_conf_mutually_exclusive4.phpt | 2 | ||||
| -rw-r--r-- | src/tests/config/disabled_functions_invalid_pos.ini | 1 | ||||
| -rw-r--r-- | src/tests/config/disabled_functions_pos.ini | 1 | ||||
| -rw-r--r-- | src/tests/disabled_functions_param_invalid_pos.phpt | 14 | ||||
| -rw-r--r-- | src/tests/disabled_functions_param_pos.phpt | 12 |
8 files changed, 62 insertions, 7 deletions
diff --git a/src/sp_config.h b/src/sp_config.h index 0877ebb..c005206 100644 --- a/src/sp_config.h +++ b/src/sp_config.h | |||
| @@ -77,6 +77,7 @@ typedef struct { | |||
| 77 | char *param; | 77 | char *param; |
| 78 | pcre *r_param; | 78 | pcre *r_param; |
| 79 | sp_php_type param_type; | 79 | sp_php_type param_type; |
| 80 | int pos; | ||
| 80 | 81 | ||
| 81 | char *ret; | 82 | char *ret; |
| 82 | pcre *r_ret; | 83 | pcre *r_ret; |
| @@ -183,6 +184,7 @@ typedef struct { | |||
| 183 | #define SP_TOKEN_RET_TYPE ".ret_type(" | 184 | #define SP_TOKEN_RET_TYPE ".ret_type(" |
| 184 | #define SP_TOKEN_VALUE ".value(" | 185 | #define SP_TOKEN_VALUE ".value(" |
| 185 | #define SP_TOKEN_VALUE_REGEXP ".value_r(" | 186 | #define SP_TOKEN_VALUE_REGEXP ".value_r(" |
| 187 | #define SP_TOKEN_VALUE_ARG_POS ".pos(" | ||
| 186 | 188 | ||
| 187 | // cookies encryption | 189 | // cookies encryption |
| 188 | #define SP_TOKEN_NAME ".cookie(" | 190 | #define SP_TOKEN_NAME ".cookie(" |
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index 29f1bfc..097d08b 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c | |||
| @@ -144,7 +144,9 @@ int parse_cookie_encryption(char *line) { | |||
| 144 | int parse_disabled_functions(char *line) { | 144 | int parse_disabled_functions(char *line) { |
| 145 | int ret = 0; | 145 | int ret = 0; |
| 146 | bool enable = true, disable = false; | 146 | bool enable = true, disable = false; |
| 147 | char *pos = NULL; | ||
| 147 | sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); | 148 | sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); |
| 149 | df->pos = -1; | ||
| 148 | 150 | ||
| 149 | sp_config_functions sp_config_funcs_disabled_functions[] = { | 151 | sp_config_functions sp_config_funcs_disabled_functions[] = { |
| 150 | {parse_empty, SP_TOKEN_ENABLE, &(enable)}, | 152 | {parse_empty, SP_TOKEN_ENABLE, &(enable)}, |
| @@ -169,6 +171,7 @@ int parse_disabled_functions(char *line) { | |||
| 169 | {parse_regexp, SP_TOKEN_RET_REGEXP, &(df->r_ret)}, | 171 | {parse_regexp, SP_TOKEN_RET_REGEXP, &(df->r_ret)}, |
| 170 | {parse_php_type, SP_TOKEN_RET_TYPE, &(df->ret_type)}, | 172 | {parse_php_type, SP_TOKEN_RET_TYPE, &(df->ret_type)}, |
| 171 | {parse_str, SP_TOKEN_LOCAL_VAR, &(df->var)}, | 173 | {parse_str, SP_TOKEN_LOCAL_VAR, &(df->var)}, |
| 174 | {parse_str, SP_TOKEN_VALUE_ARG_POS, &(pos)}, | ||
| 172 | {0}}; | 175 | {0}}; |
| 173 | 176 | ||
| 174 | ret = parse_keywords(sp_config_funcs_disabled_functions, line); | 177 | ret = parse_keywords(sp_config_funcs_disabled_functions, line); |
| @@ -201,10 +204,10 @@ int parse_disabled_functions(char *line) { | |||
| 201 | "'.r_filename' and '.filename' are mutually exclusive on line %zu.", | 204 | "'.r_filename' and '.filename' are mutually exclusive on line %zu.", |
| 202 | line, sp_line_no); | 205 | line, sp_line_no); |
| 203 | return -1; | 206 | return -1; |
| 204 | } else if (df->r_param && df->param) { | 207 | } else if (1 < ((df->r_param?1:0) + (df->param?1:0) + ((-1 != df->pos)?1:0))) { |
| 205 | sp_log_err("config", | 208 | sp_log_err("config", |
| 206 | "Invalid configuration line: 'sp.disabled_functions%s':" | 209 | "Invalid configuration line: 'sp.disabled_functions%s':" |
| 207 | "'.r_param' and '.param' are mutually exclusive on line %zu.", | 210 | "'.r_param', '.param' and '.pos' are mutually exclusive on line %zu.", |
| 208 | line, sp_line_no); | 211 | line, sp_line_no); |
| 209 | return -1; | 212 | return -1; |
| 210 | } else if (df->r_ret && df->ret) { | 213 | } else if (df->r_ret && df->ret) { |
| @@ -233,6 +236,22 @@ int parse_disabled_functions(char *line) { | |||
| 233 | return -1; | 236 | return -1; |
| 234 | } | 237 | } |
| 235 | 238 | ||
| 239 | if (pos) { | ||
| 240 | errno = 0; | ||
| 241 | char *endptr; | ||
| 242 | df->pos = strtol(pos, &endptr, 10); | ||
| 243 | if (errno != 0 || endptr == pos) { | ||
| 244 | sp_log_err("config", "Failed to parse arg '%s' of `pos` on line %zu.", | ||
| 245 | pos, sp_line_no); | ||
| 246 | return -1; | ||
| 247 | } | ||
| 248 | |||
| 249 | // We'll never have a function with more than 128 params | ||
| 250 | if (df->pos > 128) { | ||
| 251 | df->pos = 128; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 236 | if (df->function) { | 255 | if (df->function) { |
| 237 | df->functions_list = parse_functions_list(df->function); | 256 | df->functions_list = parse_functions_list(df->function); |
| 238 | } | 257 | } |
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index c8c723a..54a1906 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c | |||
| @@ -178,11 +178,17 @@ bool should_disable(zend_execute_data* execute_data) { | |||
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | /* Check if we filter on parameter value*/ | 180 | /* Check if we filter on parameter value*/ |
| 181 | if (config_node->param || config_node->r_param) { | 181 | if (config_node->param || config_node->r_param || (config_node->pos != -1)) { |
| 182 | const unsigned int nb_param = execute_data->func->common.num_args; | 182 | int nb_param = execute_data->func->common.num_args; |
| 183 | bool arg_matched = false; | 183 | bool arg_matched = false; |
| 184 | int i = 0; | ||
| 184 | 185 | ||
| 185 | for (unsigned int i = 0; i < nb_param; i++) { | 186 | if ((config_node->pos != -1) && (config_node->pos <= nb_param)) { |
| 187 | i = config_node->pos; | ||
| 188 | nb_param = (config_node->pos) + 1; | ||
| 189 | } | ||
| 190 | |||
| 191 | for (; i < nb_param; i++) { | ||
| 186 | arg_matched = false; | 192 | arg_matched = false; |
| 187 | if (ZEND_USER_CODE(execute_data->func->type)) { // yay consistency | 193 | if (ZEND_USER_CODE(execute_data->func->type)) { // yay consistency |
| 188 | arg_name = ZSTR_VAL(execute_data->func->common.arg_info[i].name); | 194 | arg_name = ZSTR_VAL(execute_data->func->common.arg_info[i].name); |
| @@ -197,7 +203,7 @@ bool should_disable(zend_execute_data* execute_data) { | |||
| 197 | (true == is_regexp_matching(config_node->r_param, arg_name)); | 203 | (true == is_regexp_matching(config_node->r_param, arg_name)); |
| 198 | 204 | ||
| 199 | /* This is the parameter name we're looking for. */ | 205 | /* This is the parameter name we're looking for. */ |
| 200 | if (true == arg_matching || true == pcre_matching) { | 206 | if (true == arg_matching || true == pcre_matching || (config_node->pos != -1)) { |
| 201 | zval* arg_value = ZEND_CALL_VAR_NUM(execute_data, i); | 207 | zval* arg_value = ZEND_CALL_VAR_NUM(execute_data, i); |
| 202 | 208 | ||
| 203 | if (config_node->param_type) { // Are we matching on the `type`? | 209 | if (config_node->param_type) { // Are we matching on the `type`? |
diff --git a/src/tests/broken_conf_mutually_exclusive4.phpt b/src/tests/broken_conf_mutually_exclusive4.phpt index 4e888f5..a60f3fa 100644 --- a/src/tests/broken_conf_mutually_exclusive4.phpt +++ b/src/tests/broken_conf_mutually_exclusive4.phpt | |||
| @@ -6,4 +6,4 @@ Broken configuration | |||
| 6 | sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive4.ini | 6 | sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive4.ini |
| 7 | --FILE-- | 7 | --FILE-- |
| 8 | --EXPECT-- | 8 | --EXPECT-- |
| 9 | [snuffleupagus][0.0.0.0][config][error] Invalid configuration line: 'sp.disabled_functions.function("system").param("id").value("42").param_r("^id$").drop();':'.r_param' and '.param' are mutually exclusive on line 1. \ No newline at end of file | 9 | [snuffleupagus][0.0.0.0][config][error] Invalid configuration line: 'sp.disabled_functions.function("system").param("id").value("42").param_r("^id$").drop();':'.r_param', '.param' and '.pos' are mutually exclusive on line 1. |
diff --git a/src/tests/config/disabled_functions_invalid_pos.ini b/src/tests/config/disabled_functions_invalid_pos.ini new file mode 100644 index 0000000..42988e4 --- /dev/null +++ b/src/tests/config/disabled_functions_invalid_pos.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.disable_function.function("system").pos("qwe").value("id").drop(); | |||
diff --git a/src/tests/config/disabled_functions_pos.ini b/src/tests/config/disabled_functions_pos.ini new file mode 100644 index 0000000..f96cf3d --- /dev/null +++ b/src/tests/config/disabled_functions_pos.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.disable_function.function("system").pos("0").value("id").drop(); | |||
diff --git a/src/tests/disabled_functions_param_invalid_pos.phpt b/src/tests/disabled_functions_param_invalid_pos.phpt new file mode 100644 index 0000000..91ddd93 --- /dev/null +++ b/src/tests/disabled_functions_param_invalid_pos.phpt | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | --TEST-- | ||
| 2 | Disable functions - match on argument's position | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/disabled_functions_invalid_pos.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | system("echo 1"); | ||
| 10 | ?> | ||
| 11 | --EXPECTF-- | ||
| 12 | [snuffleupagus][0.0.0.0][config][error] Failed to parse arg 'qwe' of `pos` on line 1. | ||
| 13 | 1 | ||
| 14 | |||
diff --git a/src/tests/disabled_functions_param_pos.phpt b/src/tests/disabled_functions_param_pos.phpt new file mode 100644 index 0000000..de578b2 --- /dev/null +++ b/src/tests/disabled_functions_param_pos.phpt | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | --TEST-- | ||
| 2 | Disable functions - match on argument's position | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/disabled_functions_pos.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | system("id"); | ||
| 10 | ?> | ||
| 11 | --EXPECTF-- | ||
| 12 | [snuffleupagus][0.0.0.0][disabled_function][drop] The call to the function 'system' in %a/disabled_functions_param_pos.php:%d has been disabled, because its argument 'command' content (id) matched a rule. | ||
