diff options
Diffstat (limited to 'bug73174.patch')
-rw-r--r-- | bug73174.patch | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/bug73174.patch b/bug73174.patch new file mode 100644 index 0000000..d67e3d9 --- /dev/null +++ b/bug73174.patch @@ -0,0 +1,76 @@ +Backported from 5.6.27 by Remi. + + +From 29e2a204fb42af061e66a9f847ffbc8f1d13897a Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Wed, 28 Sep 2016 22:29:25 -0700 +Subject: [PATCH] Fixed bug #73174 - heap overflow in php_pcre_replace_impl + +--- + ext/pcre/php_pcre.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c +index 7589a78..2a8ff19 100644 +--- a/ext/pcre/php_pcre.c ++++ b/ext/pcre/php_pcre.c +@@ -1040,8 +1040,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub + char **subpat_names; /* Array for named subpatterns */ + int num_subpats; /* Number of captured subpatterns */ + int size_offsets; /* Size of the offsets array */ +- int new_len; /* Length of needed storage */ +- int alloc_len; /* Actual allocated length */ ++ size_t new_len; /* Length of needed storage */ ++ size_t alloc_len; /* Actual allocated length */ + int eval_result_len=0; /* Length of the eval'ed or + function-returned string */ + int match_len; /* Length of the current match */ +@@ -1106,8 +1106,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub + + offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0); + +- alloc_len = 2 * subject_len + 1; +- result = safe_emalloc(alloc_len, sizeof(char), 0); ++ result = safe_emalloc(subject_len, 2*sizeof(char), 1); ++ alloc_len = 2 * (size_t)subject_len + 1; + + /* Initialize */ + match = NULL; +@@ -1172,8 +1172,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub + } + + if (new_len + 1 > alloc_len) { +- alloc_len = 1 + alloc_len + 2 * new_len; +- new_buf = emalloc(alloc_len); ++ new_buf = safe_emalloc(2, new_len + 1, alloc_len); ++ alloc_len = 1 + alloc_len + 2 * (size_t)new_len; + memcpy(new_buf, result, *result_len); + efree(result); + result = new_buf; +@@ -1236,8 +1236,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub + } else { + new_len = *result_len + subject_len - start_offset; + if (new_len + 1 > alloc_len) { +- alloc_len = new_len + 1; /* now we know exactly how long it is */ +- new_buf = safe_emalloc(alloc_len, sizeof(char), 0); ++ new_buf = safe_emalloc(new_len, sizeof(char), 1); ++ alloc_len = (size_t)new_len + 1; /* now we know exactly how long it is */ + memcpy(new_buf, result, *result_len); + efree(result); + result = new_buf; +@@ -1268,6 +1268,12 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub + efree(offsets); + efree(subpat_names); + ++ if(result && (size_t)(*result_len) > INT_MAX) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, max is %d", INT_MAX); ++ efree(result); ++ result = NULL; ++ } ++ + return result; + } + /* }}} */ +-- +2.1.4 + |