From 6f0ac316e6a12f7d897c9efd0363dd73dfda286a Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 11 2016 19:53:50 +0000 Subject: import php55-php-5.5.21-5.el7 --- diff --git a/SOURCES/php-5.5.21-CVE-2016-5385.patch b/SOURCES/php-5.5.21-CVE-2016-5385.patch new file mode 100644 index 0000000..e9cc6db --- /dev/null +++ b/SOURCES/php-5.5.21-CVE-2016-5385.patch @@ -0,0 +1,448 @@ +From 98b9dfaec95e6f910f125ed172cdbd25abd006ec Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 10 Jul 2016 16:17:54 -0700 +Subject: [PATCH] Fix for HTTP_PROXY issue. + +The following changes are made: +- _SERVER/_ENV only has HTTP_PROXY if the local environment has it, + and only one from the environment. +- getenv('HTTP_PROXY') only returns one from the local environment +- getenv has optional second parameter, telling it to only consider + local environment +--- + UPGRADING | 3 +++ + ext/standard/basic_functions.c | 17 +++++++------ + main/SAPI.c | 48 +++++++++++++++++++----------------- + main/php_variables.c | 56 ++++++++++++++++++++++++++++-------------- + 4 files changed, 76 insertions(+), 48 deletions(-) + +diff --git a/UPGRADING b/UPGRADING +index 7b51ae5..84a925a 100644 +--- a/UPGRADING ++++ b/UPGRADING +@@ -194,6 +194,9 @@ PHP 5.5 UPGRADE NOTES + - Since 5.5.4, fputcsv() has fifth parameter escape_char, allowing to + specify escape char. + ++- Since 5.5.38, getenv() has optional second parameter, making it only ++ consider local environment and not SAPI environment if true. ++ + 4a. unserialize() change + ------------------------ + +diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c +index 50b6bc7..8cbba14 100644 +--- a/ext/standard/basic_functions.c ++++ b/ext/standard/basic_functions.c +@@ -3544,7 +3544,7 @@ PHPAPI double php_get_inf(void) /* {{{ */ + + #define BASIC_ADD_SUBMODULE(module) \ + zend_hash_add_empty_element(&basic_submodules, #module, strlen(#module)); +- ++ + #define BASIC_RINIT_SUBMODULE(module) \ + if (zend_hash_exists(&basic_submodules, #module, strlen(#module))) { \ + PHP_RINIT(module)(INIT_FUNC_ARGS_PASSTHRU); \ +@@ -4013,21 +4013,24 @@ PHP_FUNCTION(long2ip) + * System Functions * + ********************/ + +-/* {{{ proto string getenv(string varname) ++/* {{{ proto string getenv(string varname[, bool local_only]) + Get the value of an environment variable */ + PHP_FUNCTION(getenv) + { + char *ptr, *str; + int str_len; ++ zend_bool local_only = 0; + +- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &str, &str_len, &local_only) == FAILURE) { + RETURN_FALSE; + } + +- /* SAPI method returns an emalloc()'d string */ +- ptr = sapi_getenv(str, str_len TSRMLS_CC); +- if (ptr) { +- RETURN_STRING(ptr, 0); ++ if (!local_only) { ++ /* SAPI method returns an emalloc()'d string */ ++ ptr = sapi_getenv(str, str_len TSRMLS_CC); ++ if (ptr) { ++ RETURN_STRING(ptr, 0); ++ } + } + #ifdef PHP_WIN32 + { +diff --git a/main/SAPI.c b/main/SAPI.c +index 0dd0b55..8a56c6d 100644 +--- a/main/SAPI.c ++++ b/main/SAPI.c +@@ -1,4 +1,4 @@ +-/* ++/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ +@@ -132,7 +132,7 @@ PHP_FUNCTION(header_register_callback) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback_func) == FAILURE) { + return; + } +- ++ + if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) { + efree(callback_name); + RETURN_FALSE; +@@ -160,10 +160,10 @@ static void sapi_run_header_callback(TSRMLS_D) + char *callback_name = NULL; + char *callback_error = NULL; + zval *retval_ptr = NULL; +- ++ + if (zend_fcall_info_init(SG(callback_func), 0, &fci, &SG(fci_cache), &callback_name, &callback_error TSRMLS_CC) == SUCCESS) { + fci.retval_ptr_ptr = &retval_ptr; +- ++ + error = zend_call_function(&fci, &SG(fci_cache) TSRMLS_CC); + if (error == FAILURE) { + goto callback_failed; +@@ -174,13 +174,13 @@ static void sapi_run_header_callback(TSRMLS_D) + callback_failed: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the sapi_header_callback"); + } +- ++ + if (callback_name) { + efree(callback_name); + } + if (callback_error) { + efree(callback_error); +- } ++ } + } + + SAPI_API void sapi_handle_post(void *arg TSRMLS_DC) +@@ -386,11 +386,11 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D) + if (SG(request_info).headers_read == 1) + return; + SG(request_info).headers_read = 1; +- zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), ++ zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), + (void (*)(void *)) sapi_free_header, 0); + SG(sapi_headers).send_default_content_type = 1; + +- /* SG(sapi_headers).http_response_code = 200; */ ++ /* SG(sapi_headers).http_response_code = 200; */ + SG(sapi_headers).http_status_line = NULL; + SG(sapi_headers).mimetype = NULL; + SG(read_post_bytes) = 0; +@@ -403,7 +403,7 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D) + SG(global_request_time) = 0; + + /* +- * It's possible to override this general case in the activate() callback, ++ * It's possible to override this general case in the activate() callback, + * if necessary. + */ + if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) { +@@ -465,8 +465,8 @@ SAPI_API void sapi_activate(TSRMLS_D) + * depending on given content type */ + sapi_read_post_data(TSRMLS_C); + } else { +- /* Any other method with content payload will fill $HTTP_RAW_POST_DATA +- * if it is enabled by always_populate_raw_post_data. ++ /* Any other method with content payload will fill $HTTP_RAW_POST_DATA ++ * if it is enabled by always_populate_raw_post_data. + * It's up to the webserver to decide whether to allow a method or not. */ + SG(request_info).content_type_dup = NULL; + if (sapi_module.default_post_reader) { +@@ -497,14 +497,14 @@ static void sapi_send_headers_free(TSRMLS_D) + SG(sapi_headers).http_status_line = NULL; + } + } +- ++ + SAPI_API void sapi_deactivate(TSRMLS_D) + { + zend_llist_destroy(&SG(sapi_headers).headers); + if (SG(request_info).post_data) { + efree(SG(request_info).post_data); + } else if (SG(server_context)) { +- if(sapi_module.read_post) { ++ if(sapi_module.read_post) { + /* make sure we've consumed all request input data */ + char dummy[SAPI_POST_BLOCK_SIZE]; + int read_bytes; +@@ -516,7 +516,7 @@ SAPI_API void sapi_deactivate(TSRMLS_D) + } + if (SG(request_info).raw_post_data) { + efree(SG(request_info).raw_post_data); +- } ++ } + if (SG(request_info).auth_user) { + efree(SG(request_info).auth_user); + } +@@ -574,7 +574,7 @@ static int sapi_extract_response_code(const char *header_line) + break; + } + } +- ++ + return code; + } + +@@ -594,7 +594,7 @@ static void sapi_update_response_code(int ncode TSRMLS_DC) + SG(sapi_headers).http_response_code = ncode; + } + +-/* ++/* + * since zend_llist_del_element only remove one matched item once, + * we should remove them by ourself + */ +@@ -630,7 +630,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo + { + sapi_header_line ctr = {0}; + int r; +- ++ + ctr.line = header_line; + ctr.line_len = header_line_len; + +@@ -724,7 +724,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) + } while(header_line_len && isspace(header_line[header_line_len-1])); + header_line[header_line_len]='\0'; + } +- ++ + if (op == SAPI_HEADER_DELETE) { + if (strchr(header_line, ':')) { + efree(header_line); +@@ -762,7 +762,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) + sapi_header.header_len = header_line_len; + + /* Check the header for a few cases that we have special support for in SAPI */ +- if (header_line_len>=5 ++ if (header_line_len>=5 + && !strncasecmp(header_line, "HTTP/", 5)) { + /* filter out the response code */ + sapi_update_response_code(sapi_extract_response_code(header_line) TSRMLS_CC); +@@ -821,8 +821,8 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) + /* Return a Found Redirect if one is not already specified */ + if (http_response_code) { /* user specified redirect code */ + sapi_update_response_code(http_response_code TSRMLS_CC); +- } else if (SG(request_info).proto_num > 1000 && +- SG(request_info).request_method && ++ } else if (SG(request_info).proto_num > 1000 && ++ SG(request_info).request_method && + strcmp(SG(request_info).request_method, "HEAD") && + strcmp(SG(request_info).request_method, "GET")) { + sapi_update_response_code(303 TSRMLS_CC); +@@ -1011,7 +1011,11 @@ SAPI_API struct stat *sapi_get_stat(TSRMLS_D) + + SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC) + { +- if (sapi_module.getenv) { ++ if (!strncasecmp(name, "HTTP_PROXY", name_len)) { ++ /* Ugly fix for HTTP_PROXY issue */ ++ return NULL; ++ } ++ if (sapi_module.getenv) { + char *value, *tmp = sapi_module.getenv(name, name_len TSRMLS_CC); + if (tmp) { + value = estrdup(tmp); +diff --git a/main/php_variables.c b/main/php_variables.c +index bf6b9f3..bbe57d3 100644 +--- a/main/php_variables.c ++++ b/main/php_variables.c +@@ -43,7 +43,7 @@ PHPAPI void php_register_variable_safe(char *var, char *strval, int str_len, zva + { + zval new_entry; + assert(strval != NULL); +- ++ + /* Prepare value */ + Z_STRLEN(new_entry) = str_len; + Z_STRVAL(new_entry) = estrndup(strval, Z_STRLEN(new_entry)); +@@ -81,7 +81,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars + while (*var_name && *var_name==' ') { + var_name++; + } +- ++ + /* + * Prepare variable name + */ +@@ -167,7 +167,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars + return; + } + *ip = 0; +- new_idx_len = strlen(index_s); ++ new_idx_len = strlen(index_s); + } + + if (!index) { +@@ -210,7 +210,7 @@ plain_var: + zval_ptr_dtor(&gpc_element); + } + } else { +- /* ++ /* + * According to rfc2965, more specific paths are listed above the less specific ones. + * If we encounter a duplicate cookie name, we should skip it, since it is not possible + * to have the same (plain text) cookie name for the same path and we should not overwrite +@@ -236,7 +236,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler) + + if (SG(request_info).post_data == NULL) { + return; +- } ++ } + + s = SG(request_info).post_data; + e = s + SG(request_info).post_data_length; +@@ -284,7 +284,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) + int free_buffer = 0; + char *strtok_buf = NULL; + long count = 0; +- ++ + switch (arg) { + case PARSE_POST: + case PARSE_GET: +@@ -357,9 +357,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) + separator = ";\0"; + break; + } +- ++ + var = php_strtok_r(res, separator, &strtok_buf); +- ++ + while (var) { + val = strchr(var, '='); + +@@ -454,11 +454,11 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC) + zval *arr, *argc, *tmp; + int count = 0; + char *ss, *space; +- ++ + if (!(SG(request_info).argc || track_vars_array)) { + return; + } +- ++ + ALLOC_INIT_ZVAL(arr); + array_init(arr); + +@@ -519,7 +519,7 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC) + Z_ADDREF_P(argc); + zend_hash_update(&EG(symbol_table), "argv", sizeof("argv"), &arr, sizeof(zval *), NULL); + zend_hash_update(&EG(symbol_table), "argc", sizeof("argc"), &argc, sizeof(zval *), NULL); +- } ++ } + if (track_vars_array) { + Z_ADDREF_P(arr); + Z_ADDREF_P(argc); +@@ -649,7 +649,7 @@ static zend_bool php_auto_globals_create_get(const char *name, uint name_len TSR + + zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); + Z_ADDREF_P(vars); +- ++ + return 0; /* don't rearm */ + } + +@@ -676,7 +676,7 @@ static zend_bool php_auto_globals_create_post(const char *name, uint name_len TS + + zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); + Z_ADDREF_P(vars); +- ++ + return 0; /* don't rearm */ + } + +@@ -699,7 +699,7 @@ static zend_bool php_auto_globals_create_cookie(const char *name, uint name_len + + zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); + Z_ADDREF_P(vars); +- ++ + return 0; /* don't rearm */ + } + +@@ -718,10 +718,26 @@ static zend_bool php_auto_globals_create_files(const char *name, uint name_len T + + zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); + Z_ADDREF_P(vars); +- ++ + return 0; /* don't rearm */ + } + ++/* Upgly hack to fix HTTP_PROXY issue */ ++static void check_http_proxy(HashTable *var_table) { ++ if (zend_hash_exists(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY"))) { ++ char *local_proxy = getenv("HTTP_PROXY"); ++ ++ if (!local_proxy) { ++ zend_hash_del(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")); ++ } else { ++ zval *local_zval; ++ ALLOC_INIT_ZVAL(local_zval); ++ ZVAL_STRING(local_zval, local_proxy, 1); ++ zend_hash_update(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY"), &local_zval, sizeof(zval **), NULL); ++ } ++ } ++} ++ + static zend_bool php_auto_globals_create_server(const char *name, uint name_len TSRMLS_DC) + { + if (PG(variables_order) && (strchr(PG(variables_order),'S') || strchr(PG(variables_order),'s'))) { +@@ -730,7 +746,7 @@ static zend_bool php_auto_globals_create_server(const char *name, uint name_len + if (PG(register_argc_argv)) { + if (SG(request_info).argc) { + zval **argc, **argv; +- ++ + if (zend_hash_find(&EG(symbol_table), "argc", sizeof("argc"), (void**)&argc) == SUCCESS && + zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void**)&argv) == SUCCESS) { + Z_ADDREF_PP(argc); +@@ -742,7 +758,7 @@ static zend_bool php_auto_globals_create_server(const char *name, uint name_len + php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC); + } + } +- ++ + } else { + zval *server_vars=NULL; + ALLOC_ZVAL(server_vars); +@@ -754,9 +770,10 @@ static zend_bool php_auto_globals_create_server(const char *name, uint name_len + PG(http_globals)[TRACK_VARS_SERVER] = server_vars; + } + ++ check_http_proxy(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER])); + zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL); + Z_ADDREF_P(PG(http_globals)[TRACK_VARS_SERVER]); +- ++ + return 0; /* don't rearm */ + } + +@@ -770,11 +787,12 @@ static zend_bool php_auto_globals_create_env(const char *name, uint name_len TSR + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_ENV]); + } + PG(http_globals)[TRACK_VARS_ENV] = env_vars; +- ++ + if (PG(variables_order) && (strchr(PG(variables_order),'E') || strchr(PG(variables_order),'e'))) { + php_import_environment_variables(PG(http_globals)[TRACK_VARS_ENV] TSRMLS_CC); + } + ++ check_http_proxy(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV])); + zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL); + Z_ADDREF_P(PG(http_globals)[TRACK_VARS_ENV]); + +-- +2.1.4 + diff --git a/SPECS/php.spec b/SPECS/php.spec index d3b87db..dca8da1 100644 --- a/SPECS/php.spec +++ b/SPECS/php.spec @@ -163,7 +163,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: 5.5.21 -Release: 4%{?dist} +Release: 5%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -231,6 +231,7 @@ Patch151: php-5.5.21-CVE-2015-2783.patch Patch152: php-5.5.21-CVE-2015-3329.patch Patch153: php-5.5.21-bug68819.patch Patch154: php-5.5.21-bug69152.patch +Patch155: php-5.5.21-CVE-2016-5385.patch # Fixes for tests @@ -913,6 +914,7 @@ support for using the enchant library to PHP. %patch152 -p1 -b .cve3329 %patch153 -p1 -b .bug68819 %patch154 -p1 -b .bug69152 +%patch155 -p1 -b .cve5385 # Prevent %%doc confusion over LICENSE files cp Zend/LICENSE Zend/ZEND_LICENSE @@ -1823,6 +1825,10 @@ fi %changelog +* Fri Jul 22 2016 Remi Collet - 5.5.21-5 +- don't set environmental variable based on user supplied Proxy + request header CVE-2016-5385 + * Wed Jun 10 2015 Remi Collet - 5.5.21-4 - fix more functions accept paths with NUL character #1213407