From ab117573cd6fef9b7df50e00df0cf2078b740b5c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 2 May 2013 09:38:00 +0200 Subject: [PATCH] fix possible null deref (detected by code coverity scan) --- sapi/fpm/fpm/fpm_main.c | 214 ++++++++++++++++++++-------------------- 1 file changed, 109 insertions(+), 105 deletions(-) diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 4e12c7d52f3..763327271fa 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1179,119 +1179,123 @@ static void init_request_info(TSRMLS_D) int len = script_path_translated_len; char *ptr; - while ((ptr = strrchr(pt, '/')) || (ptr = strrchr(pt, '\\'))) { - *ptr = 0; - if (stat(pt, &st) == 0 && S_ISREG(st.st_mode)) { - /* - * okay, we found the base script! - * work out how many chars we had to strip off; - * then we can modify PATH_INFO - * accordingly - * - * we now have the makings of - * PATH_INFO=/test - * SCRIPT_FILENAME=/docroot/info.php - * - * we now need to figure out what docroot is. - * if DOCUMENT_ROOT is set, this is easy, otherwise, - * we have to play the game of hide and seek to figure - * out what SCRIPT_NAME should be - */ - int ptlen = strlen(pt); - int slen = len - ptlen; - int pilen = env_path_info ? strlen(env_path_info) : 0; - int tflag = 0; - char *path_info; - if (apache_was_here) { - /* recall that PATH_INFO won't exist */ - path_info = script_path_translated + ptlen; - tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0)); - } else { - path_info = env_path_info ? env_path_info + pilen - slen : NULL; - tflag = (orig_path_info != path_info); - } - - if (tflag) { - if (orig_path_info) { - char old; - - _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC); - old = path_info[0]; - path_info[0] = 0; - if (!orig_script_name || - strcmp(orig_script_name, env_path_info) != 0) { - if (orig_script_name) { - _sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC); - } - SG(request_info).request_uri = _sapi_cgibin_putenv("SCRIPT_NAME", env_path_info TSRMLS_CC); - } else { - SG(request_info).request_uri = orig_script_name; - } - path_info[0] = old; - } - env_path_info = _sapi_cgibin_putenv("PATH_INFO", path_info TSRMLS_CC); - } - if (!orig_script_filename || - strcmp(orig_script_filename, pt) != 0) { - if (orig_script_filename) { - _sapi_cgibin_putenv("ORIG_SCRIPT_FILENAME", orig_script_filename TSRMLS_CC); - } - script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", pt TSRMLS_CC); - } - TRANSLATE_SLASHES(pt); - - /* figure out docroot - * SCRIPT_FILENAME minus SCRIPT_NAME - */ - if (env_document_root) { - int l = strlen(env_document_root); - int path_translated_len = 0; - char *path_translated = NULL; - - if (l && env_document_root[l - 1] == '/') { - --l; - } - - /* we have docroot, so we should have: - * DOCUMENT_ROOT=/docroot + if (pt) { + while ((ptr = strrchr(pt, '/')) || (ptr = strrchr(pt, '\\'))) { + *ptr = 0; + if (stat(pt, &st) == 0 && S_ISREG(st.st_mode)) { + /* + * okay, we found the base script! + * work out how many chars we had to strip off; + * then we can modify PATH_INFO + * accordingly + * + * we now have the makings of + * PATH_INFO=/test * SCRIPT_FILENAME=/docroot/info.php + * + * we now need to figure out what docroot is. + * if DOCUMENT_ROOT is set, this is easy, otherwise, + * we have to play the game of hide and seek to figure + * out what SCRIPT_NAME should be */ + int ptlen = strlen(pt); + int slen = len - ptlen; + int pilen = env_path_info ? strlen(env_path_info) : 0; + int tflag = 0; + char *path_info; + if (apache_was_here) { + /* recall that PATH_INFO won't exist */ + path_info = script_path_translated + ptlen; + tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0)); + } else { + path_info = env_path_info ? env_path_info + pilen - slen : NULL; + tflag = (orig_path_info != path_info); + } - /* PATH_TRANSLATED = DOCUMENT_ROOT + PATH_INFO */ - path_translated_len = l + (env_path_info ? strlen(env_path_info) : 0); - path_translated = (char *) emalloc(path_translated_len + 1); - memcpy(path_translated, env_document_root, l); - if (env_path_info) { - memcpy(path_translated + l, env_path_info, (path_translated_len - l)); - } - path_translated[path_translated_len] = '\0'; - if (orig_path_translated) { - _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC); - } - env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED", path_translated TSRMLS_CC); - efree(path_translated); - } else if ( env_script_name && - strstr(pt, env_script_name) - ) { - /* PATH_TRANSLATED = PATH_TRANSLATED - SCRIPT_NAME + PATH_INFO */ - int ptlen = strlen(pt) - strlen(env_script_name); - int path_translated_len = ptlen + (env_path_info ? strlen(env_path_info) : 0); - char *path_translated = NULL; + if (tflag) { + if (orig_path_info) { + char old; - path_translated = (char *) emalloc(path_translated_len + 1); - memcpy(path_translated, pt, ptlen); - if (env_path_info) { - memcpy(path_translated + ptlen, env_path_info, path_translated_len - ptlen); + _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC); + old = path_info[0]; + path_info[0] = 0; + if (!orig_script_name || + strcmp(orig_script_name, env_path_info) != 0) { + if (orig_script_name) { + _sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC); + } + SG(request_info).request_uri = _sapi_cgibin_putenv("SCRIPT_NAME", env_path_info TSRMLS_CC); + } else { + SG(request_info).request_uri = orig_script_name; + } + path_info[0] = old; + } + env_path_info = _sapi_cgibin_putenv("PATH_INFO", path_info TSRMLS_CC); } - path_translated[path_translated_len] = '\0'; - if (orig_path_translated) { - _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC); + if (!orig_script_filename || + strcmp(orig_script_filename, pt) != 0) { + if (orig_script_filename) { + _sapi_cgibin_putenv("ORIG_SCRIPT_FILENAME", orig_script_filename TSRMLS_CC); + } + script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", pt TSRMLS_CC); } - env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED", path_translated TSRMLS_CC); - efree(path_translated); + TRANSLATE_SLASHES(pt); + + /* figure out docroot + * SCRIPT_FILENAME minus SCRIPT_NAME + */ + if (env_document_root) { + int l = strlen(env_document_root); + int path_translated_len = 0; + char *path_translated = NULL; + + if (l && env_document_root[l - 1] == '/') { + --l; + } + + /* we have docroot, so we should have: + * DOCUMENT_ROOT=/docroot + * SCRIPT_FILENAME=/docroot/info.php + */ + + /* PATH_TRANSLATED = DOCUMENT_ROOT + PATH_INFO */ + path_translated_len = l + (env_path_info ? strlen(env_path_info) : 0); + path_translated = (char *) emalloc(path_translated_len + 1); + memcpy(path_translated, env_document_root, l); + if (env_path_info) { + memcpy(path_translated + l, env_path_info, (path_translated_len - l)); + } + path_translated[path_translated_len] = '\0'; + if (orig_path_translated) { + _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC); + } + env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED", path_translated TSRMLS_CC); + efree(path_translated); + } else if ( env_script_name && + strstr(pt, env_script_name) + ) { + /* PATH_TRANSLATED = PATH_TRANSLATED - SCRIPT_NAME + PATH_INFO */ + int ptlen = strlen(pt) - strlen(env_script_name); + int path_translated_len = ptlen + (env_path_info ? strlen(env_path_info) : 0); + char *path_translated = NULL; + + path_translated = (char *) emalloc(path_translated_len + 1); + memcpy(path_translated, pt, ptlen); + if (env_path_info) { + memcpy(path_translated + ptlen, env_path_info, path_translated_len - ptlen); + } + path_translated[path_translated_len] = '\0'; + if (orig_path_translated) { + _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC); + } + env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED", path_translated TSRMLS_CC); + efree(path_translated); + } + break; } - break; } + } else { + ptr = NULL; } if (!ptr) { /*