From 5193b37822269c19a58b86c8a6e1f8e90bd818e6 Mon Sep 17 00:00:00 2001 From: Ben Fuhrmannek Date: Thu, 17 Jul 2014 13:40:39 +0200 Subject: removed redundant implementations of protected varname check --- ex_imp.c | 59 +---------------------------------------------------------- ifilter.c | 54 ++++++------------------------------------------------ php_suhosin.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ ufilter.c | 52 ++-------------------------------------------------- 4 files changed, 59 insertions(+), 156 deletions(-) diff --git a/ex_imp.c b/ex_imp.c index 3325e43..40d40e0 100644 --- a/ex_imp.c +++ b/ex_imp.c @@ -443,6 +443,7 @@ PHP_FUNCTION(suhosin_extract) /* }}} */ + #if PHP_VERSION_ID >= 50300 static int copy_request_variable(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) { @@ -478,35 +479,6 @@ static int copy_request_variable(void *pDest TSRMLS_DC, int num_args, va_list ar return 0; } - if (Z_STRVAL(new_key)[0] == 'H') { - if ((strcmp(Z_STRVAL(new_key), "HTTP_GET_VARS")==0)|| - (strcmp(Z_STRVAL(new_key), "HTTP_POST_VARS")==0)|| - (strcmp(Z_STRVAL(new_key), "HTTP_POST_FILES")==0)|| - (strcmp(Z_STRVAL(new_key), "HTTP_ENV_VARS")==0)|| - (strcmp(Z_STRVAL(new_key), "HTTP_SERVER_VARS")==0)|| - (strcmp(Z_STRVAL(new_key), "HTTP_SESSION_VARS")==0)|| - (strcmp(Z_STRVAL(new_key), "HTTP_COOKIE_VARS")==0)|| - (strcmp(Z_STRVAL(new_key), "HTTP_RAW_POST_DATA")==0)) { - zval_dtor(&new_key); - return 0; - } - } else if (Z_STRVAL(new_key)[0] == '_') { - if ((strcmp(Z_STRVAL(new_key), "_COOKIE")==0)|| - (strcmp(Z_STRVAL(new_key), "_ENV")==0)|| - (strcmp(Z_STRVAL(new_key), "_FILES")==0)|| - (strcmp(Z_STRVAL(new_key), "_GET")==0)|| - (strcmp(Z_STRVAL(new_key), "_POST")==0)|| - (strcmp(Z_STRVAL(new_key), "_REQUEST")==0)|| - (strcmp(Z_STRVAL(new_key), "_SESSION")==0)|| - (strcmp(Z_STRVAL(new_key), "_SERVER")==0)) { - zval_dtor(&new_key); - return 0; - } - } else if (strcmp(Z_STRVAL(new_key), "GLOBALS")==0) { - zval_dtor(&new_key); - return 0; - } - zend_delete_global_variable(Z_STRVAL(new_key), Z_STRLEN(new_key) TSRMLS_CC); ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), Z_STRVAL(new_key), Z_STRLEN(new_key) + 1, *var, Z_REFCOUNT_PP(var) + 1, 0); @@ -554,35 +526,6 @@ static int copy_request_variable(void *pDest, int num_args, va_list args, zend_h return 0; } - if (new_key[0] == 'H') { - if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| - (strcmp(new_key, "HTTP_POST_VARS")==0)|| - (strcmp(new_key, "HTTP_POST_FILES")==0)|| - (strcmp(new_key, "HTTP_ENV_VARS")==0)|| - (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| - (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| - (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| - (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { - efree(new_key); - return 0; - } - } else if (new_key[0] == '_') { - if ((strcmp(new_key, "_COOKIE")==0)|| - (strcmp(new_key, "_ENV")==0)|| - (strcmp(new_key, "_FILES")==0)|| - (strcmp(new_key, "_GET")==0)|| - (strcmp(new_key, "_POST")==0)|| - (strcmp(new_key, "_REQUEST")==0)|| - (strcmp(new_key, "_SESSION")==0)|| - (strcmp(new_key, "_SERVER")==0)) { - efree(new_key); - return 0; - } - } else if (strcmp(new_key, "GLOBALS")==0) { - efree(new_key); - return 0; - } - #if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); #else diff --git a/ifilter.c b/ifilter.c index 7ac4637..65b48cd 100644 --- a/ifilter.c +++ b/ifilter.c @@ -29,6 +29,7 @@ #include "ext/standard/info.h" #include "php_suhosin.h" #include "php_variables.h" +#include "ext/standard/php_var.h" static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; @@ -619,47 +620,11 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ /* This is to protect several silly scripts that do globalizing themself */ - - switch (var_len) { - case 18: - if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; - break; - case 17: - if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; - break; - case 16: - if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; - if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; - break; - case 15: - if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; - break; - case 14: - if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; - break; - case 13: - if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; - if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; - break; - case 8: - if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; - if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; - break; - case 7: - if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; - if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; - if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; - break; - case 6: - if (memcmp(var, "_FILES", 6)==0) goto protected_varname; - break; - case 5: - if (memcmp(var, "_POST", 5)==0) goto protected_varname; - break; - case 4: - if (memcmp(var, "_ENV", 4)==0) goto protected_varname; - if (memcmp(var, "_GET", 4)==0) goto protected_varname; - break; + if (php_varname_check(var, var_len, 0 TSRMLS_CC) == FAILURE) { + suhosin_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); + if (!SUHOSIN_G(simulation)) { + return 0; + } } /* Okay let PHP register this variable */ @@ -681,13 +646,6 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v } return 1; -protected_varname: - suhosin_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); - if (!SUHOSIN_G(simulation)) { - return 0; - } else { - return 1; - } } /* }}} */ diff --git a/php_suhosin.h b/php_suhosin.h index 22e6df1..e89d02b 100644 --- a/php_suhosin.h +++ b/php_suhosin.h @@ -39,6 +39,10 @@ #endif #endif +#ifndef PHP_VERSION_ID +#define PHP_VERSION_ID (PHP_MAJOR_VERSION * 10000 + PHP_MINOR_VERSION * 100 + PHP_RELEASE_VERSION) +#endif + extern zend_module_entry suhosin_module_entry; #define phpext_suhosin_ptr &suhosin_module_entry @@ -66,6 +70,52 @@ PHP_MINFO_FUNCTION(suhosin); #include "ext/standard/basic_functions.h" +#if PHP_VERSION_ID < 50203 +static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */ +{ + if (name_len == sizeof("GLOBALS") && !memcmp(name, "GLOBALS", sizeof("GLOBALS"))) { + if (!silent) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite"); + } + return FAILURE; + } else if (name[0] == '_' && + ( + (name_len == sizeof("_GET") && !memcmp(name, "_GET", sizeof("_GET"))) || + (name_len == sizeof("_POST") && !memcmp(name, "_POST", sizeof("_POST"))) || + (name_len == sizeof("_COOKIE") && !memcmp(name, "_COOKIE", sizeof("_COOKIE"))) || + (name_len == sizeof("_ENV") && !memcmp(name, "_ENV", sizeof("_ENV"))) || + (name_len == sizeof("_SERVER") && !memcmp(name, "_SERVER", sizeof("_SERVER"))) || + (name_len == sizeof("_SESSION") && !memcmp(name, "_SESSION", sizeof("_SESSION"))) || + (name_len == sizeof("_FILES") && !memcmp(name, "_FILES", sizeof("_FILES"))) || + (name_len == sizeof("_REQUEST") && !memcmp(name, "_REQUEST", sizeof("_REQUEST"))) + ) + ) { + if (!silent) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted super-global (%s) variable overwrite", name); + } + return FAILURE; + } else if (name[0] == 'H' && + ( + (name_len == sizeof("HTTP_POST_VARS") && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"))) || + (name_len == sizeof("HTTP_GET_VARS") && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"))) || + (name_len == sizeof("HTTP_COOKIE_VARS") && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"))) || + (name_len == sizeof("HTTP_ENV_VARS") && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"))) || + (name_len == sizeof("HTTP_SERVER_VARS") && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"))) || + (name_len == sizeof("HTTP_SESSION_VARS") && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"))) || + (name_len == sizeof("HTTP_RAW_POST_DATA") && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"))) || + (name_len == sizeof("HTTP_POST_FILES") && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"))) + ) + ) { + if (!silent) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted long input array (%s) overwrite", name); + } + return FAILURE; + } + return SUCCESS; +} +/* }}} */ +#endif + ZEND_BEGIN_MODULE_GLOBALS(suhosin) zend_uint in_code_type; long execution_depth; diff --git a/ufilter.c b/ufilter.c index 6d9669f..6775ec1 100644 --- a/ufilter.c +++ b/ufilter.c @@ -30,60 +30,13 @@ #include "php_suhosin.h" #include "php_variables.h" #include "suhosin_rfc1867.h" +#include "ext/standard/php_var.h" PHP_SUHOSIN_API int (*old_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; #if !HAVE_RFC1867_CALLBACK PHP_SUHOSIN_API int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; #endif -static int is_protected_varname(char *var, int var_len) -{ - switch (var_len) { - case 18: - if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; - break; - case 17: - if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; - break; - case 16: - if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; - if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; - break; - case 15: - if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; - break; - case 14: - if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; - break; - case 13: - if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; - if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; - break; - case 8: - if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; - if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; - break; - case 7: - if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; - if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; - if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; - break; - case 6: - if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; - break; - case 5: - if (memcmp(var, "_POST", 5)==0) goto protected_varname2; - break; - case 4: - if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; - if (memcmp(var, "_GET", 4)==0) goto protected_varname2; - break; - } - - return 0; -protected_varname2: - return 1; -} /* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC */ @@ -180,8 +133,7 @@ static int check_fileupload_varname(char *varname) /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ /* This is to protect several silly scripts that do globalizing themself */ - - if (is_protected_varname(var, var_len)) { + if (php_varname_check(var, var_len, 0 TSRMLS_CC) == FAILURE) { suhosin_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); if (!SUHOSIN_G(simulation)) { goto return_failure; -- cgit v1.3