From 436225969c85449d3352c91b972a5e31828f68f0 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 21 Jun 2016 16:18:39 +0200 Subject: php 5.4: backport patch from 5.5.37 (wip) --- bug66387.patch | 57 +++++++++++++++++++++++++++++ bug72275.patch | 59 ++++++++++++++++++++++++++++++ bug72340.patch | 66 +++++++++++++++++++++++++++++++++ bug72400.patch | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ php.spec | 16 +++++++- 5 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 bug66387.patch create mode 100644 bug72275.patch create mode 100644 bug72340.patch create mode 100644 bug72400.patch diff --git a/bug66387.patch b/bug66387.patch new file mode 100644 index 0000000..51291ab --- /dev/null +++ b/bug66387.patch @@ -0,0 +1,57 @@ +Backported from 5.5.37 for 5.4 by Remi Collet + + +From f96ebb098697908641c6d37e1149cde1f90417fd Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Mon, 20 Jul 2015 23:24:55 +0200 +Subject: [PATCH] Fix #66387: Stack overflow with imagefilltoborder + +The stack overflow is caused by the recursive algorithm in combination with a +very large negative coordinate passed to gdImageFillToBorder(). As there is +already a clipping for large positive coordinates to the width and height of +the image, it seems to be consequent to clip to zero also. +--- + ext/gd/libgd/gd.c | 4 ++++ + ext/gd/tests/bug66387.phpt | 15 +++++++++++++++ + 2 files changed, 19 insertions(+) + create mode 100644 ext/gd/tests/bug66387.phpt + +diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c +index d73f094..2c63aac 100644 +--- a/ext/gd/libgd/gd.c ++++ b/ext/gd/libgd/gd.c +@@ -1770,9 +1770,13 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color) + + if (x >= im->sx) { + x = im->sx - 1; ++ } else if (x < 0) { ++ x = 0; + } + if (y >= im->sy) { + y = im->sy - 1; ++ } else if (y < 0) { ++ y = 0; + } + + for (i = x; i >= 0; i--) { +diff --git a/ext/gd/tests/bug66387.phpt b/ext/gd/tests/bug66387.phpt +new file mode 100644 +index 0000000..79c49a5 +--- /dev/null ++++ b/ext/gd/tests/bug66387.phpt +@@ -0,0 +1,15 @@ ++--TEST-- ++Bug #66387 (Stack overflow with imagefilltoborder) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECT-- ++ready diff --git a/bug72275.patch b/bug72275.patch new file mode 100644 index 0000000..d28651e --- /dev/null +++ b/bug72275.patch @@ -0,0 +1,59 @@ +Backported from 5.5.37 for 5.4 by Remi Collet + + +From 489fd56fe37bf40a662931c2b4d5baa918f13e37 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 13 Jun 2016 23:12:47 -0700 +Subject: [PATCH] Fix bug #72275: don't allow smart_str to overflow int + +--- + ext/standard/php_smart_str.h | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/ext/standard/php_smart_str.h b/ext/standard/php_smart_str.h +index 1872fa8..fc1a753 100644 +--- a/ext/standard/php_smart_str.h ++++ b/ext/standard/php_smart_str.h +@@ -63,6 +63,9 @@ + newlen = (d)->len + (n); \ + if (newlen >= (d)->a) { \ + (d)->a = newlen + SMART_STR_PREALLOC; \ ++ if (UNEXPECTED((d)->a >= INT_MAX)) { \ ++ zend_error(E_ERROR, "String size overflow"); \ ++ } \ + SMART_STR_DO_REALLOC(d, what); \ + } \ + } \ +@@ -148,17 +151,17 @@ + * for GCC compatible compilers, e.g. + * + * #define f(..) ({char *r;..;__r;}) +- */ +- ++ */ ++ + static inline char *smart_str_print_long(char *buf, long num) { +- char *r; +- smart_str_print_long4(buf, num, unsigned long, r); ++ char *r; ++ smart_str_print_long4(buf, num, unsigned long, r); + return r; + } + + static inline char *smart_str_print_unsigned(char *buf, long num) { +- char *r; +- smart_str_print_unsigned4(buf, num, unsigned long, r); ++ char *r; ++ smart_str_print_unsigned4(buf, num, unsigned long, r); + return r; + } + +@@ -168,7 +171,7 @@ static inline char *smart_str_print_unsigned(char *buf, long num) { + smart_str_print##func##4 (__b + sizeof(__b) - 1, (num), vartype, __t); \ + smart_str_appendl_ex((dest), __t, __b + sizeof(__b) - 1 - __t, (type)); \ + } while (0) +- ++ + #define smart_str_append_unsigned_ex(dest, num, type) \ + smart_str_append_generic_ex((dest), (num), (type), unsigned long, _unsigned) + diff --git a/bug72340.patch b/bug72340.patch new file mode 100644 index 0000000..39646e5 --- /dev/null +++ b/bug72340.patch @@ -0,0 +1,66 @@ +Backported from 5.5.37 for 5.4 by Remi Collet + + +From a44c89e8af7c2410f4bfc5e097be2a5d0639a60c Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 12 Jun 2016 23:18:23 -0700 +Subject: [PATCH] Fix bug #72340: Double Free Courruption in wddx_deserialize + +--- + ext/wddx/tests/bug72340.phpt | 24 ++++++++++++++++++++++++ + ext/wddx/wddx.c | 4 ++++ + 2 files changed, 28 insertions(+) + create mode 100644 ext/wddx/tests/bug72340.phpt + +diff --git a/ext/wddx/tests/bug72340.phpt b/ext/wddx/tests/bug72340.phpt +new file mode 100644 +index 0000000..8d694ca +--- /dev/null ++++ b/ext/wddx/tests/bug72340.phpt +@@ -0,0 +1,24 @@ ++--TEST-- ++Bug #72340: Double Free Courruption in wddx_deserialize ++--SKIPIF-- ++ ++--FILE-- ++ ++ ++ ++ TEST ++ ++ ++ ++ ++EOF; ++$array = wddx_deserialize($xml); ++var_dump($array); ++?> ++--EXPECT-- ++array(0) { ++} +diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c +index da34246..311d6aa 100644 +--- a/ext/wddx/wddx.c ++++ b/ext/wddx/wddx.c +@@ -1096,6 +1096,9 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) + break; + + case ST_BOOLEAN: ++ if(!ent->data) { ++ break; ++ } + if (!strcmp(s, "true")) { + Z_LVAL_P(ent->data) = 1; + } else if (!strcmp(s, "false")) { +@@ -1104,6 +1107,7 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) + zval_ptr_dtor(&ent->data); + if (ent->varname) { + efree(ent->varname); ++ ent->varname = NULL; + } + ent->data = NULL; + } diff --git a/bug72400.patch b/bug72400.patch new file mode 100644 index 0000000..363a598 --- /dev/null +++ b/bug72400.patch @@ -0,0 +1,113 @@ +Backported from 5.5.37 for 5.4 by Remi Collet + + +From 88746d60ab3ad51797612ee62603bb3e08d4aac4 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Wed, 15 Jun 2016 21:46:46 -0700 +Subject: [PATCH] Fix bug #72400 and #72403 - prevent signed int overflows for + string lengths + +--- + ext/standard/string.c | 25 ++++++++++++-- + ext/standard/url.c | 96 +++++++++++++++++++++++++++------------------------ + 2 files changed, 72 insertions(+), 49 deletions(-) + +diff --git a/ext/standard/string.c b/ext/standard/string.c +index 63eede1..acb6a01 100644 +--- a/ext/standard/string.c ++++ b/ext/standard/string.c +@@ -137,6 +137,9 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t * + register unsigned char *result = NULL; + size_t i, j; + ++ if (UNEXPECTED(oldlen * 2 * sizeof(char) > INT_MAX)) { ++ zend_error(E_ERROR, "String size overflow"); ++ } + result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1); + + for (i = j = 0; i < oldlen; i++) { +@@ -2602,6 +2605,7 @@ PHP_FUNCTION(quotemeta) + char *p, *q; + char c; + int old_len; ++ size_t new_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &old, &old_len) == FAILURE) { + return; +@@ -2636,8 +2640,13 @@ PHP_FUNCTION(quotemeta) + } + } + *q = 0; ++ new_len = q - str; ++ if (UNEXPECTED(new_len > INT_MAX)) { ++ efree(str); ++ zend_error(E_ERROR, "String size overflow"); ++ } + +- RETURN_STRINGL(erealloc(str, q - str + 1), q - str, 0); ++ RETURN_STRINGL(erealloc(str, new_len + 1), new_len, 0); + } + /* }}} */ + +@@ -3539,7 +3548,7 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s + char *source, *target; + char *end; + char c; +- int newlen; ++ size_t newlen; + + if (!wlength) { + wlength = strlen(what); +@@ -3570,11 +3579,15 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s + } + *target = 0; + newlen = target - new_str; ++ if (UNEXPECTED(newlen > INT_MAX)) { ++ efree(new_str); ++ zend_error(E_ERROR, "String size overflow"); ++ } + if (target - new_str < length * 4) { + new_str = erealloc(new_str, newlen + 1); + } + if (new_length) { +- *new_length = newlen; ++ *new_length = (int)newlen; + } + if (should_free) { + STR_FREE((char*)str); +@@ -3626,6 +3639,9 @@ PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_f + + *target = 0; + *new_length = target - new_str; ++ if (UNEXPECTED(*new_length < 0)) { ++ zend_error(E_ERROR, "String size overflow"); ++ } + if (should_free) { + STR_FREE(str); + } +@@ -4329,6 +4345,9 @@ PHP_FUNCTION(nl2br) + size_t repl_len = is_xhtml ? (sizeof("
") - 1) : (sizeof("
") - 1); + + new_length = str_len + repl_cnt * repl_len; ++ if (UNEXPECTED(new_length > INT_MAX)) { ++ zend_error(E_ERROR, "String size overflow"); ++ } + tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1); + } + +diff --git a/ext/standard/url.c b/ext/standard/url.c +index 27a216a..fc3f080 100644 +--- a/ext/standard/url.c ++++ b/ext/standard/url.c +@@ -626,6 +626,10 @@ PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length) + if (new_length) { + *new_length = y; + } ++ if (UNEXPECTED(y > INT_MAX)) { ++ efree(str); ++ zend_error(E_ERROR, "String size overflow"); ++ } + return ((char *) str); + } + /* }}} */ + diff --git a/php.spec b/php.spec index 6f3cd34..cbb96a3 100644 --- a/php.spec +++ b/php.spec @@ -119,7 +119,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: 5.4.45 -Release: 9%{?dist} +Release: 10%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -211,6 +211,10 @@ Patch228: bug72114.patch Patch229: bugoverflow.patch Patch230: bug72135.patch Patch231: bug72241.patch +Patch232: bug66387.patch +Patch233: bug72340.patch +Patch234: bug72275.patch +Patch235: bug72400.patch # Fixes for tests (300+) # Backported from 5.5 @@ -880,6 +884,10 @@ support for using the enchant library to PHP. %patch229 -p1 -b .bugoverflow %patch230 -p1 -b .bug72135 %patch231 -p1 -b .bug72241 +%patch232 -p1 -b .bug66387 +%patch233 -p1 -b .bug72340 +%patch234 -p1 -b .bug72275 +%patch235 -p1 -b .bug72400 # Fixes for tests %patch300 -p1 -b .datetests1 @@ -1703,6 +1711,12 @@ EOF %changelog +* Tue Jun 21 2016 Remi Collet 5.4.45-10 +- Fix #66387: Stack overflow with imagefilltoborder +- Fix #72340: Double Free Courruption in wddx_deserialize +- Fix #72275: don't allow smart_str to overflow int +- Fix #72400 and #72403: prevent signed int overflows for string lengths + * Sun May 29 2016 Remi Collet 5.4.45-9 - Fix #71331: Uninitialized pointer in phar_make_dirstream CVE-2016-4343 -- cgit