From 4b420dae109ee4ca511cbbba0c209ea5c30513b1 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Sat, 15 Oct 2016 10:17:16 +0200 Subject: PHP 5.5.38 with 15 security fix from 5.6.27 --- bug73284.patch | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 bug73284.patch (limited to 'bug73284.patch') diff --git a/bug73284.patch b/bug73284.patch new file mode 100644 index 0000000..5d06310 --- /dev/null +++ b/bug73284.patch @@ -0,0 +1,185 @@ +Backported from 5.6.27 by Remi. + + +From 21452a5401e9c7e34227b9241495f5839cfc3234 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Tue, 11 Oct 2016 14:14:43 -0700 +Subject: [PATCH] Fix bug #73284 - heap overflow in php_ereg_replace function + +--- + ext/ereg/ereg.c | 44 ++++++++++++++++++++++---------------------- + 1 file changed, 22 insertions(+), 22 deletions(-) + +diff --git a/ext/ereg/ereg.c b/ext/ereg/ereg.c +index 8eb833a..b645c0f 100644 +--- a/ext/ereg/ereg.c ++++ b/ext/ereg/ereg.c +@@ -29,7 +29,7 @@ + /* {{{ arginfo */ + ZEND_BEGIN_ARG_INFO_EX(arginfo_ereg, 0, 0, 2) + ZEND_ARG_INFO(0, pattern) +- ZEND_ARG_INFO(0, string) ++ ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(1, registers) /* ARRAY_INFO(1, registers, 1) */ + ZEND_END_ARG_INFO() + +@@ -41,8 +41,8 @@ ZEND_END_ARG_INFO() + + ZEND_BEGIN_ARG_INFO_EX(arginfo_split, 0, 0, 2) + ZEND_ARG_INFO(0, pattern) +- ZEND_ARG_INFO(0, string) +- ZEND_ARG_INFO(0, limit) ++ ZEND_ARG_INFO(0, string) ++ ZEND_ARG_INFO(0, limit) + ZEND_END_ARG_INFO() + + ZEND_BEGIN_ARG_INFO(arginfo_sql_regcase, 0) +@@ -204,7 +204,7 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags TSRMLS_DC + } + /* }}} */ + +-static void _free_ereg_cache(reg_cache *rc) ++static void _free_ereg_cache(reg_cache *rc) + { + regfree(&rc->preg); + } +@@ -309,7 +309,7 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) + if (icase) { + copts |= REG_ICASE; + } +- ++ + if (argc == 2) { + copts |= REG_NOSUB; + } +@@ -337,7 +337,7 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) + + /* allocate storage for (sub-)expression-matches */ + subs = (regmatch_t *)ecalloc(sizeof(regmatch_t),re.re_nsub+1); +- ++ + /* actually execute the regular expression */ + err = regexec(&re, string, re.re_nsub+1, subs, 0); + if (err && err != REG_NOMATCH) { +@@ -409,8 +409,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co + *nbuf, /* nbuf is used when we grow the buffer */ + *walkbuf; /* used to walk buf when replacing backrefs */ + const char *walk; /* used to walk replacement string for backrefs */ +- int buf_len; +- int pos, tmp, string_len, new_l; ++ size_t buf_len, new_l; ++ int pos, tmp, string_len; + int err, copts = 0; + + string_len = strlen(string); +@@ -434,8 +434,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co + + /* start with a buffer that is twice the size of the stringo + we're doing replacements in */ ++ buf = safe_emalloc(string_len, 2, 1); + buf_len = 2 * string_len + 1; +- buf = safe_emalloc(buf_len, sizeof(char), 0); + + err = pos = 0; + buf[0] = '\0'; +@@ -472,8 +472,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co + } + } + if (new_l + 1 > buf_len) { ++ nbuf = safe_emalloc(new_l + 1, 2, buf_len); + buf_len = 1 + buf_len + 2 * new_l; +- nbuf = emalloc(buf_len); + strncpy(nbuf, buf, buf_len - 1); + nbuf[buf_len - 1] = '\0'; + efree(buf); +@@ -491,7 +491,7 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co + if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1 + /* this next case shouldn't happen. it does. */ + && subs[walk[1] - '0'].rm_so <= subs[walk[1] - '0'].rm_eo) { +- ++ + tmp = subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so; + memcpy (walkbuf, &string[pos + subs[walk[1] - '0'].rm_so], tmp); + walkbuf += tmp; +@@ -510,8 +510,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co + } + new_l = strlen (buf) + 1; + if (new_l + 1 > buf_len) { ++ nbuf = safe_emalloc(new_l + 1, 2, buf_len); + buf_len = 1 + buf_len + 2 * new_l; +- nbuf = safe_emalloc(buf_len, sizeof(char), 0); + strncpy(nbuf, buf, buf_len-1); + efree(buf); + buf = nbuf; +@@ -526,7 +526,7 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co + new_l = strlen(buf) + strlen(&string[pos]); + if (new_l + 1 > buf_len) { + buf_len = new_l + 1; /* now we know exactly how long it is */ +- nbuf = safe_emalloc(buf_len, sizeof(char), 0); ++ nbuf = safe_emalloc(new_l, 1, 1); + strncpy(nbuf, buf, buf_len-1); + efree(buf); + buf = nbuf; +@@ -556,7 +556,7 @@ static void php_do_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase) + char *replace; + char *ret; + int arg_string_len; +- ++ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZs", &arg_pattern, &arg_replace, &arg_string, &arg_string_len) == FAILURE) { + return; + } +@@ -598,7 +598,7 @@ static void php_do_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase) + if (ret == (char *) -1) { + RETVAL_FALSE; + } else { +- RETVAL_STRING(ret, 1); ++ RETVAL_STRINGL_CHECK(ret, strlen(ret), 1); + STR_FREE(ret); + } + +@@ -664,9 +664,9 @@ static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase) + } else if (subs[0].rm_so == 0 && subs[0].rm_eo == 0) { + /* No more matches */ + regfree(&re); +- ++ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Regular Expression"); +- ++ + zend_hash_destroy(Z_ARRVAL_P(return_value)); + efree(Z_ARRVAL_P(return_value)); + RETURN_FALSE; +@@ -675,7 +675,7 @@ static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase) + + /* make a copy of the substring */ + size = subs[0].rm_so; +- ++ + /* add it to the array */ + add_next_index_stringl(return_value, strp, size, 1); + +@@ -701,7 +701,7 @@ static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase) + + /* otherwise we just have one last element to add to the array */ + size = endp - strp; +- ++ + add_next_index_stringl(return_value, strp, size, 1); + + regfree(&re); +@@ -738,9 +738,9 @@ PHP_EREG_API PHP_FUNCTION(sql_regcase) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &string_len) == FAILURE) { + return; + } +- ++ + tmp = safe_emalloc(string_len, 4, 1); +- ++ + for (i = j = 0; i < string_len; i++) { + c = (unsigned char) string[i]; + if ( j >= INT_MAX - 1 || (isalpha(c) && j >= INT_MAX - 4)) { +-- +2.1.4 + -- cgit