From e2958a432947f16a89f196171a572abc1c506154 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 23 Jun 2016 15:53:37 +0200 Subject: PHP 5.4.45 with security fix from 5.5.37 --- bug66387.patch | 57 ++++++++++++ bug72275.patch | 59 ++++++++++++ bug72298.patch | 93 +++++++++++++++++++ bug72339.patch | 127 ++++++++++++++++++++++++++ bug72340.patch | 66 ++++++++++++++ bug72400.patch | 113 +++++++++++++++++++++++ bug72402.patch | 284 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bug72433.patch | 113 +++++++++++++++++++++++ bug72434.patch | 78 ++++++++++++++++ bug72446.patch | 30 ++++++ bug72455.patch | 39 ++++++++ failed.txt | 7 +- php54.spec | 47 +++++++++- 13 files changed, 1109 insertions(+), 4 deletions(-) create mode 100644 bug66387.patch create mode 100644 bug72275.patch create mode 100644 bug72298.patch create mode 100644 bug72339.patch create mode 100644 bug72340.patch create mode 100644 bug72400.patch create mode 100644 bug72402.patch create mode 100644 bug72433.patch create mode 100644 bug72434.patch create mode 100644 bug72446.patch create mode 100644 bug72455.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/bug72298.patch b/bug72298.patch new file mode 100644 index 0000000..206578e --- /dev/null +++ b/bug72298.patch @@ -0,0 +1,93 @@ +From e9ac8954be9f7d988189df44578d759ffdea3512 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 18 Jun 2016 21:04:33 -0700 +Subject: [PATCH] Fix bug #72298 pass2_no_dither out-of-bounds access + +--- + ext/gd/libgd/gd_topal.c | 14 +++++++------- + ext/gd/tests/bug72298.phpt | 15 +++++++++++++++ + 2 files changed, 22 insertions(+), 7 deletions(-) + create mode 100644 ext/gd/tests/bug72298.phpt + +diff --git a/ext/gd/libgd/gd_topal.c b/ext/gd/libgd/gd_topal.c +index b9cb928..d8dda45 100644 +--- a/ext/gd/libgd/gd_topal.c ++++ b/ext/gd/libgd/gd_topal.c +@@ -43,7 +43,7 @@ + * If it is not working, it's not Thomas G. Lane's fault. + */ + +-/* ++/* + SETTING THIS ONE CAUSES STRIPED IMAGE + to be done: solve this + #define ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS +@@ -152,7 +152,7 @@ + * color space, and repeatedly splits the "largest" remaining box until we + * have as many boxes as desired colors. Then the mean color in each + * remaining box becomes one of the possible output colors. +- * ++ * + * The second pass over the image maps each input pixel to the closest output + * color (optionally after applying a Floyd-Steinberg dithering correction). + * This mapping is logically trivial, but making it go fast enough requires +@@ -1320,16 +1320,16 @@ pass2_no_dither (j_decompress_ptr cinfo, + #else + r = gdTrueColorGetRed (*inptr); + g = gdTrueColorGetGreen (*inptr); +- /* ++ /* + 2.0.24: inptr must not be incremented until after +- transparency check, if any. Thanks to "Super Pikeman." ++ transparency check, if any. Thanks to "Super Pikeman." + */ + b = gdTrueColorGetBlue (*inptr); + + /* If the pixel is transparent, we assign it the palette index that + * will later be added at the end of the palette as the transparent + * index. */ +- if ((oim->transparent >= 0) && (oim->transparent == *(inptr - 1))) ++ if ((oim->transparent >= 0) && (oim->transparent == *inptr)) + { + *outptr++ = nim->colorsTotal; + inptr++; +@@ -1795,7 +1795,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color + } + } else { + nim = oim; +- } ++ } + if (!oim->trueColor) + { + /* (Almost) nothing to do! */ +@@ -2004,7 +2004,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color + } + + /* Success! Get rid of the truecolor image data. */ +- if (!cimP) { ++ if (!cimP) { + oim->trueColor = 0; + /* Junk the truecolor pixels */ + for (i = 0; i < oim->sy; i++) +diff --git a/ext/gd/tests/bug72298.phpt b/ext/gd/tests/bug72298.phpt +new file mode 100644 +index 0000000..7fba241 +--- /dev/null ++++ b/ext/gd/tests/bug72298.phpt +@@ -0,0 +1,15 @@ ++--TEST-- ++Bug #72298: pass2_no_dither out-of-bounds access ++--SKIPIF-- ++ ++--FILE-- ++ ++DONE ++--EXPECT-- ++DONE +\ No newline at end of file diff --git a/bug72339.patch b/bug72339.patch new file mode 100644 index 0000000..da385e8 --- /dev/null +++ b/bug72339.patch @@ -0,0 +1,127 @@ +Backported from 5.5.37 for 5.4 by Remi Collet + + +From 7722455726bec8c53458a32851d2a87982cf0eac Mon Sep 17 00:00:00 2001 +From: Pierre Joye +Date: Sat, 18 Jun 2016 20:15:10 +0200 +Subject: [PATCH] Fixed #72339 Integer Overflow in _gd2GetHeader() resulting in + heap overflow + +--- + ext/gd/libgd/gd_gd2.c | 7 +++++++ + ext/gd/tests/bug72339.gd | Bin 0 -> 67108882 bytes + ext/gd/tests/bug72339.phpt | 11 +++++++++++ + 3 files changed, 18 insertions(+) + create mode 100644 ext/gd/tests/bug72339.gd + create mode 100644 ext/gd/tests/bug72339.phpt + +diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c +index 6726fee..63e3aef 100644 +--- a/ext/gd/libgd/gd_gd2.c ++++ b/ext/gd/libgd/gd_gd2.c +@@ -138,11 +138,18 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in + if (gd2_compressed(*fmt)) { + nc = (*ncx) * (*ncy); + GD2_DBG(php_gd_error("Reading %d chunk index entries", nc)); ++ if (overflow2(sidx, nc)) { ++ goto fail1; ++ } + sidx = sizeof(t_chunk_info) * nc; + if (sidx <= 0) { + goto fail1; + } + cidx = gdCalloc(sidx, 1); ++ if (cidx == NULL) { ++ goto fail1; ++ } ++ + for (i = 0; i < nc; i++) { + if (gdGetInt(&cidx[i].offset, in) != 1) { + gdFree(cidx); +diff --git a/ext/gd/tests/bug72339.phpt b/ext/gd/tests/bug72339.phpt +new file mode 100644 +index 0000000..763ae71 +--- /dev/null ++++ b/ext/gd/tests/bug72339.phpt +@@ -0,0 +1,11 @@ ++--TEST-- ++Bug #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECTF-- ++Warning: imagecreatefromgd2(): gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully ++ in %sbug72339.php on line %d ++ ++Warning: imagecreatefromgd2(): '%sbug72339.gd' is not a valid GD2 file in %sbug72339.php on line %d + +From 5f107ab8a66f8b36ac0c0b32e0231bf94e083c94 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 20 Jun 2016 22:54:55 -0700 +Subject: [PATCH] fix tests + +--- + ext/gd/libgd/gd_gd2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c +index 63e3aef..e954aaf 100644 +--- a/ext/gd/libgd/gd_gd2.c ++++ b/ext/gd/libgd/gd_gd2.c +@@ -138,7 +138,7 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in + if (gd2_compressed(*fmt)) { + nc = (*ncx) * (*ncy); + GD2_DBG(php_gd_error("Reading %d chunk index entries", nc)); +- if (overflow2(sidx, nc)) { ++ if (overflow2(sizeof(t_chunk_info), nc)) { + goto fail1; + } + sidx = sizeof(t_chunk_info) * nc; + +From 0c7250f260303061425d0d8a348d1a80fa0cc12e Mon Sep 17 00:00:00 2001 +From: Anatol Belski +Date: Tue, 21 Jun 2016 09:42:38 +0200 +Subject: [PATCH] remove the huge test file, generate it on the fly instead + +--- + ext/gd/tests/bug72339.gd | Bin 67108882 -> 0 bytes + ext/gd/tests/bug72339.phpt | 24 +++++++++++++++++++++++- + 2 files changed, 23 insertions(+), 1 deletion(-) + delete mode 100644 ext/gd/tests/bug72339.gd + +diff --git a/ext/gd/tests/bug72339.phpt b/ext/gd/tests/bug72339.phpt +index 763ae71..2c30ee8 100644 +--- a/ext/gd/tests/bug72339.phpt ++++ b/ext/gd/tests/bug72339.phpt +@@ -3,7 +3,29 @@ Bug #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow + --SKIPIF-- + + --FILE-- +- ++ + --EXPECTF-- + Warning: imagecreatefromgd2(): gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully + in %sbug72339.php on line %d 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/bug72402.patch b/bug72402.patch new file mode 100644 index 0000000..5e7243f --- /dev/null +++ b/bug72402.patch @@ -0,0 +1,284 @@ +From 5b597a2e5b28e2d5a52fc1be13f425f08f47cb62 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 18 Jun 2016 21:48:39 -0700 +Subject: [PATCH] Fix bug #72402: _php_mb_regex_ereg_replace_exec - double free + +--- + ext/mbstring/php_mbregex.c | 65 ++++++++++++++++++++-------------------- + ext/mbstring/tests/bug72402.phpt | 17 +++++++++++ + 2 files changed, 49 insertions(+), 33 deletions(-) + create mode 100644 ext/mbstring/tests/bug72402.phpt + +diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c +index d73c848..6cdee23 100644 +--- a/ext/mbstring/php_mbregex.c ++++ b/ext/mbstring/php_mbregex.c +@@ -32,7 +32,7 @@ + #include "ext/standard/info.h" + #include "php_mbregex.h" + #include "mbstring.h" +- ++ + #include "php_onig_compat.h" /* must come prior to the oniguruma header */ + #include + #undef UChar +@@ -55,7 +55,7 @@ struct _zend_mb_regex_globals { + #define MBREX(g) (MBSTRG(mb_regex_globals)->g) + + /* {{{ static void php_mb_regex_free_cache() */ +-static void php_mb_regex_free_cache(php_mb_regex_t **pre) ++static void php_mb_regex_free_cache(php_mb_regex_t **pre) + { + onig_free(*pre); + } +@@ -78,7 +78,7 @@ static int _php_mb_regex_globals_ctor(zend_mb_regex_globals *pglobals TSRMLS_DC) + /* }}} */ + + /* {{{ _php_mb_regex_globals_dtor */ +-static void _php_mb_regex_globals_dtor(zend_mb_regex_globals *pglobals TSRMLS_DC) ++static void _php_mb_regex_globals_dtor(zend_mb_regex_globals *pglobals TSRMLS_DC) + { + zend_hash_destroy(&pglobals->ht_rc); + } +@@ -466,7 +466,7 @@ static php_mb_regex_t *php_mbregex_compile_pattern(const char *pattern, int patl + retval = *rc; + } + out: +- return retval; ++ return retval; + } + /* }}} */ + +@@ -483,7 +483,7 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT + --len_left; + *(p++) = 'i'; + } +- ++len_req; ++ ++len_req; + } + + if ((option & ONIG_OPTION_EXTEND) != 0) { +@@ -491,7 +491,7 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT + --len_left; + *(p++) = 'x'; + } +- ++len_req; ++ ++len_req; + } + + if ((option & (ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE)) == +@@ -500,14 +500,14 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT + --len_left; + *(p++) = 'p'; + } +- ++len_req; ++ ++len_req; + } else { + if ((option & ONIG_OPTION_MULTILINE) != 0) { + if (len_left > 0) { + --len_left; + *(p++) = 'm'; + } +- ++len_req; ++ ++len_req; + } + + if ((option & ONIG_OPTION_SINGLELINE) != 0) { +@@ -515,22 +515,22 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT + --len_left; + *(p++) = 's'; + } +- ++len_req; ++ ++len_req; + } +- } ++ } + if ((option & ONIG_OPTION_FIND_LONGEST) != 0) { + if (len_left > 0) { + --len_left; + *(p++) = 'l'; + } +- ++len_req; ++ ++len_req; + } + if ((option & ONIG_OPTION_FIND_NOT_EMPTY) != 0) { + if (len_left > 0) { + --len_left; + *(p++) = 'n'; + } +- ++len_req; ++ ++len_req; + } + + c = 0; +@@ -566,7 +566,7 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT + --len_left; + *(p++) = '\0'; + } +- ++len_req; ++ ++len_req; + if (len < len_req) { + return len_req; + } +@@ -577,11 +577,11 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT + + /* {{{ _php_mb_regex_init_options */ + static void +-_php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, OnigSyntaxType **syntax, int *eval) ++_php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, OnigSyntaxType **syntax, int *eval) + { + int n; + char c; +- int optm = 0; ++ int optm = 0; + + *syntax = ONIG_SYNTAX_RUBY; + +@@ -636,13 +636,13 @@ _php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, O + *syntax = ONIG_SYNTAX_POSIX_EXTENDED; + break; + case 'e': +- if (eval != NULL) *eval = 1; ++ if (eval != NULL) *eval = 1; + break; + default: + break; + } + } +- if (option != NULL) *option|=optm; ++ if (option != NULL) *option|=optm; + } + } + /* }}} */ +@@ -860,11 +860,11 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp + } else { + /* FIXME: this code is not multibyte aware! */ + convert_to_long_ex(arg_pattern_zval); +- pat_buf[0] = (char)Z_LVAL_PP(arg_pattern_zval); ++ pat_buf[0] = (char)Z_LVAL_PP(arg_pattern_zval); + pat_buf[1] = '\0'; + + arg_pattern = pat_buf; +- arg_pattern_len = 1; ++ arg_pattern_len = 1; + } + /* create regex pattern buffer */ + re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, options, MBREX(current_mbctype), syntax TSRMLS_CC); +@@ -934,7 +934,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp + } + } + } +- ++ + if (eval) { + zval v; + /* null terminate buffer */ +@@ -953,32 +953,31 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp + eval_buf.len = 0; + zval_dtor(&v); + } else if (is_callable) { +- zval *retval_ptr; ++ zval *retval_ptr = NULL; + zval **args[1]; + zval *subpats; + int i; +- ++ + MAKE_STD_ZVAL(subpats); + array_init(subpats); +- ++ + for (i = 0; i < regs->num_regs; i++) { + add_next_index_stringl(subpats, string + regs->beg[i], regs->end[i] - regs->beg[i], 1); +- } +- ++ } ++ + args[0] = &subpats; + /* null terminate buffer */ + smart_str_0(&eval_buf); +- ++ + arg_replace_fci.param_count = 1; + arg_replace_fci.params = args; + arg_replace_fci.retval_ptr_ptr = &retval_ptr; +- if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr) { ++ if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr && retval_ptr) { + convert_to_string_ex(&retval_ptr); + smart_str_appendl(&out_buf, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr)); + eval_buf.len = 0; + zval_ptr_dtor(&retval_ptr); + } else { +- efree(description); + if (!EG(exception)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function"); + } +@@ -991,7 +990,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp + pos = (OnigUChar *)string + n; + } else { + if (pos < string_lim) { +- smart_str_appendl(&out_buf, pos, 1); ++ smart_str_appendl(&out_buf, pos, 1); + } + pos++; + } +@@ -1013,7 +1012,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp + smart_str_free(&eval_buf); + + if (err <= -2) { +- smart_str_free(&out_buf); ++ smart_str_free(&out_buf); + RETVAL_FALSE; + } else { + smart_str_appendc(&out_buf, '\0'); +@@ -1063,7 +1062,7 @@ PHP_FUNCTION(mb_split) + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &arg_pattern, &arg_pattern_len, &string, &string_len, &count) == FAILURE) { + RETURN_FALSE; +- } ++ } + + if (count > 0) { + count--; +@@ -1317,7 +1316,7 @@ PHP_FUNCTION(mb_ereg_search_init) + if (zend_parse_parameters(argc TSRMLS_CC, "z|ss", &arg_str, &arg_pattern, &arg_pattern_len, &arg_options, &arg_options_len) == FAILURE) { + return; + } +- ++ + if (argc > 1 && arg_pattern_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty pattern"); + RETURN_FALSE; +@@ -1416,7 +1415,7 @@ PHP_FUNCTION(mb_ereg_search_setpos) + /* }}} */ + + /* {{{ php_mb_regex_set_options */ +-static void _php_mb_regex_set_options(OnigOptionType options, OnigSyntaxType *syntax, OnigOptionType *prev_options, OnigSyntaxType **prev_syntax TSRMLS_DC) ++static void _php_mb_regex_set_options(OnigOptionType options, OnigSyntaxType *syntax, OnigOptionType *prev_options, OnigSyntaxType **prev_syntax TSRMLS_DC) + { + if (prev_options != NULL) { + *prev_options = MBREX(regex_default_options); +diff --git a/ext/mbstring/tests/bug72402.phpt b/ext/mbstring/tests/bug72402.phpt +new file mode 100644 +index 0000000..abb290b +--- /dev/null ++++ b/ext/mbstring/tests/bug72402.phpt +@@ -0,0 +1,17 @@ ++--TEST-- ++Bug #72402: _php_mb_regex_ereg_replace_exec - double free ++--SKIPIF-- ++ ++--FILE-- ++ ++DONE ++--EXPECT-- ++DONE +\ No newline at end of file diff --git a/bug72433.patch b/bug72433.patch new file mode 100644 index 0000000..79b7265 --- /dev/null +++ b/bug72433.patch @@ -0,0 +1,113 @@ +From 3f627e580acfdaf0595ae3b115b8bec677f203ee Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 20 Jun 2016 21:26:33 -0700 +Subject: [PATCH] Fixed ##72433: Use After Free Vulnerability in PHP's GC + algorithm and unserialize + +--- + Zend/tests/gc_024.phpt | 2 +- + ext/spl/spl_array.c | 11 +++++++++++ + ext/standard/tests/strings/bug72433.phpt | 32 ++++++++++++++++++++++++++++++++ + 3 files changed, 44 insertions(+), 1 deletion(-) + create mode 100644 ext/standard/tests/strings/bug72433.phpt + +diff --git a/Zend/tests/gc_024.phpt b/Zend/tests/gc_024.phpt +index 9a2ceb8..ca78da6 100644 +--- a/Zend/tests/gc_024.phpt ++++ b/Zend/tests/gc_024.phpt +@@ -13,5 +13,5 @@ var_dump(gc_collect_cycles()); + echo "ok\n"; + ?> + --EXPECT-- +-int(1) ++int(2) + ok +diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c +index c89cf49..4e03c40 100644 +--- a/ext/spl/spl_array.c ++++ b/ext/spl/spl_array.c +@@ -831,6 +831,16 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* + } + /* }}} */ + ++static HashTable *spl_array_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */ ++{ ++ spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); ++ ++ *gc_data = &intern->array; ++ *gc_data_count = 1; ++ return zend_std_get_properties(object); ++} ++/* }}} */ ++ + static zval *spl_array_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ + { + spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); +@@ -1973,6 +1983,7 @@ PHP_MINIT_FUNCTION(spl_array) + + spl_handler_ArrayObject.get_properties = spl_array_get_properties; + spl_handler_ArrayObject.get_debug_info = spl_array_get_debug_info; ++ spl_handler_ArrayObject.get_gc = spl_array_get_gc; + spl_handler_ArrayObject.read_property = spl_array_read_property; + spl_handler_ArrayObject.write_property = spl_array_write_property; + spl_handler_ArrayObject.get_property_ptr_ptr = spl_array_get_property_ptr_ptr; +diff --git a/ext/standard/tests/strings/bug72433.phpt b/ext/standard/tests/strings/bug72433.phpt +new file mode 100644 +index 0000000..3a2c897 +--- /dev/null ++++ b/ext/standard/tests/strings/bug72433.phpt +@@ -0,0 +1,32 @@ ++--TEST-- ++Bug #72433: Use After Free Vulnerability in PHP's GC algorithm and unserialize ++--FILE-- ++ ++--EXPECTF-- ++array(3) { ++ [0]=> ++ *RECURSION* ++ [1]=> ++ *RECURSION* ++ [2]=> ++ object(ArrayObject)#%d (1) { ++ ["storage":"ArrayObject":private]=> ++ *RECURSION* ++ } ++} +From 7f428cae88f1294052087e6729f1ecb924b8a18d Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 20 Jun 2016 22:13:31 -0700 +Subject: [PATCH] fix build + +--- + ext/spl/spl_array.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c +index 4e03c40..5cb7d34 100644 +--- a/ext/spl/spl_array.c ++++ b/ext/spl/spl_array.c +@@ -837,7 +837,7 @@ static HashTable *spl_array_get_gc(zval *object, zval ***gc_data, int *gc_data_c + + *gc_data = &intern->array; + *gc_data_count = 1; +- return zend_std_get_properties(object); ++ return zend_std_get_properties(object TSRMLS_CC); + } + /* }}} */ + diff --git a/bug72434.patch b/bug72434.patch new file mode 100644 index 0000000..2e9294d --- /dev/null +++ b/bug72434.patch @@ -0,0 +1,78 @@ +From f6aef68089221c5ea047d4a74224ee3deead99a6 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 20 Jun 2016 21:35:22 -0700 +Subject: [PATCH] Fix bug #72434: ZipArchive class Use After Free Vulnerability + in PHP's GC algorithm and unserialize + +--- + ext/standard/tests/strings/bug72434.phpt | 33 ++++++++++++++++++++++++++++++++ + ext/zip/php_zip.c | 9 +++++++++ + 2 files changed, 42 insertions(+) + create mode 100644 ext/standard/tests/strings/bug72434.phpt + +diff --git a/ext/standard/tests/strings/bug72434.phpt b/ext/standard/tests/strings/bug72434.phpt +new file mode 100644 +index 0000000..1408b8f +--- /dev/null ++++ b/ext/standard/tests/strings/bug72434.phpt +@@ -0,0 +1,33 @@ ++--TEST-- ++Bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize ++--SKIPIF-- ++ ++--FILE-- ++ rc is 0 ++$a = $unserialized_payload[1]; ++// Increment the reference counter by 1 again -> rc is 1 ++$b = $a; ++// Trigger free of $free_me (referenced by $m[1]). ++unset($b); ++$fill_freed_space_1 = "filler_zval_1"; ++$fill_freed_space_2 = "filler_zval_2"; ++$fill_freed_space_3 = "filler_zval_3"; ++$fill_freed_space_4 = "filler_zval_4"; ++debug_zval_dump($unserialized_payload[1]); ++?> ++--EXPECTF-- ++array(1) refcount(1){ ++ [0]=> ++ object(stdClass)#%d (0) refcount(3){ ++ } ++} +diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c +index 99c293c..57d060f 100644 +--- a/ext/zip/php_zip.c ++++ b/ext/zip/php_zip.c +@@ -1015,6 +1015,14 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend + } + /* }}} */ + ++static HashTable *php_zip_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */ ++{ ++ *gc_data = NULL; ++ *gc_data_count = 0; ++ return zend_std_get_properties(object TSRMLS_CC); ++} ++/* }}} */ ++ + static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */ + { + ze_zip_object *obj; +@@ -2777,6 +2785,7 @@ static PHP_MINIT_FUNCTION(zip) + zip_object_handlers.clone_obj = NULL; + zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr; + ++ zip_object_handlers.get_gc = php_zip_get_gc; + zip_object_handlers.get_properties = php_zip_get_properties; + zip_object_handlers.read_property = php_zip_read_property; + zip_object_handlers.has_property = php_zip_has_property; diff --git a/bug72446.patch b/bug72446.patch new file mode 100644 index 0000000..1990705 --- /dev/null +++ b/bug72446.patch @@ -0,0 +1,30 @@ +Backported from 5.5.37 for 5.4 by Remi Collet + + +From c395c6e5d7e8df37a21265ff76e48fe75ceb5ae6 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 20 Jun 2016 23:58:26 -0700 +Subject: [PATCH] iFixed bug #72446 - Integer Overflow in + gdImagePaletteToTrueColor() resulting in heap overflow + +--- + NEWS | 2 ++ + ext/gd/libgd/gd.c | 22 +++++++++++++--------- + 2 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c +index 2c63aac..4dad95a 100644 +--- a/ext/gd/libgd/gd.c ++++ b/ext/gd/libgd/gd.c +@@ -133,6 +133,10 @@ gdImagePtr gdImageCreate (int sx, int sy) + return NULL; + } + ++ if (overflow2(sizeof(unsigned char *), sx)) { ++ return NULL; ++ } ++ + im = (gdImage *) gdCalloc(1, sizeof(gdImage)); + + /* Row-major ever since gd 1.3 */ + diff --git a/bug72455.patch b/bug72455.patch new file mode 100644 index 0000000..e3c3660 --- /dev/null +++ b/bug72455.patch @@ -0,0 +1,39 @@ +Backported from 5.5.37 for 5.4 by Remi Collet + + +From 6c5211a0cef0cc2854eaa387e0eb036e012904d0 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 20 Jun 2016 21:51:42 -0700 +Subject: [PATCH] Fix bug #72455: Heap Overflow due to integer overflows + +--- + ext/mcrypt/mcrypt.c | 92 +++++++++++++++++++++++++++++------------------------ + 1 file changed, 50 insertions(+), 42 deletions(-) + +diff --git a/ext/mcrypt/mcrypt.c b/ext/mcrypt/mcrypt.c +index 194660d..3cbb913 100644 +--- a/ext/mcrypt/mcrypt.c ++++ b/ext/mcrypt/mcrypt.c +@@ -681,6 +681,10 @@ PHP_FUNCTION(mcrypt_generic) + if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */ + block_size = mcrypt_enc_get_block_size(pm->td); + data_size = (((data_len - 1) / block_size) + 1) * block_size; ++ if (data_size <= 0) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Integer overflow in data size"); ++ RETURN_FALSE; ++ } + data_s = emalloc(data_size + 1); + memset(data_s, 0, data_size); + memcpy(data_s, data, data_len); +@@ -726,6 +730,10 @@ PHP_FUNCTION(mdecrypt_generic) + if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */ + block_size = mcrypt_enc_get_block_size(pm->td); + data_size = (((data_len - 1) / block_size) + 1) * block_size; ++ if (data_size <= 0) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Integer overflow in data size"); ++ RETURN_FALSE; ++ } + data_s = emalloc(data_size + 1); + memset(data_s, 0, data_size); + memcpy(data_s, data, data_len); + diff --git a/failed.txt b/failed.txt index 9d57fb8..14a47b2 100644 --- a/failed.txt +++ b/failed.txt @@ -1,14 +1,15 @@ -===== 5.5.45-9 (2016-05-29) +===== 5.5.45-10 (2016-06-23) $ grep -r 'Tests failed' /var/lib/mock/*/build.log -/var/lib/mock/el5i/build.log:Tests failed : 6 -/var/lib/mock/el5x/build.log:Tests failed : 2 +/var/lib/mock/el5i/build.log:Tests failed : 7 +/var/lib/mock/el5x/build.log:Tests failed : 3 /var/lib/mock/el6i/build.log:Tests failed : 5 /var/lib/mock/el6x/build.log:Tests failed : 1 /var/lib/mock/el7x/build.log:Tests failed : 0 el5i, el5x + Bug #33414 [1] (Comprehensive list of incorrect days returned after strotime() / date() tests) [ext/date/tests/bug33414-1.phpt] Bug #66501: EC private key support in openssl_sign [ext/openssl/tests/bug66501.phpt] Bug #64802: openssl_x509_parse fails to parse subject properly in some cases [ext/openssl/tests/bug64802.phpt] el5i, el6i diff --git a/php54.spec b/php54.spec index d5982c5..ba036b9 100644 --- a/php54.spec +++ b/php54.spec @@ -98,7 +98,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: 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 @@ -188,6 +188,18 @@ Patch228: bug72114.patch Patch229: bugoverflow.patch Patch230: bug72135.patch Patch231: bug72241.patch +Patch232: bug66387.patch +Patch233: bug72340.patch +Patch234: bug72275.patch +# For #72400, #72403, #72268 +Patch235: bug72400.patch +Patch236: bug72339.patch +Patch237: bug72298.patch +Patch238: bug72402.patch +Patch239: bug72433.patch +Patch240: bug72434.patch +Patch241: bug72455.patch +Patch242: bug72446.patch # Fixes for tests # no_NO issue @@ -927,6 +939,17 @@ rm -f ext/json/utf8_to_utf16.* %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 +%patch236 -p1 -b .bug72339 +%patch237 -p1 -b .bug72298 +%patch238 -p1 -b .bug72402 +%patch239 -p1 -b .bug72433 +%patch240 -p1 -b .bug72434 +%patch241 -p1 -b .bug72455 +%patch242 -p1 -b .bug72446 # Fixes for tests %patch301 -p1 -b .datetests2 @@ -1816,6 +1839,28 @@ fi %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 + CVE-2016-5772 +- Fix #72275: don't allow smart_str to overflow int +- Fix #72400: prevent signed int overflows for string lengths +- Fix #72403: prevent signed int overflows for string lengths +- Fix #72268: Integer Overflow in nl2br(). (Stas) +- Fix #72339: Integer Overflow in _gd2GetHeader() resulting in heap overflow + CVE-2016-5766 +- Fix #72298: pass2_no_dither out-of-bounds access +- Fix #72402: _php_mb_regex_ereg_replace_exec - double free + CVE-2016-5768 +- Fix #72433: SPL use After Free Vulnerability in PHP's GC + CVE-2016-5771 +- Fix #72434: ZipArchive class use After Free Vulnerability in PHP's GC + CVE-2016-5773 +- Fix #72455: Heap Overflow due to integer overflows + CVE-2016-5769 +- Fix #72446: Integer Overflow in gdImagePaletteToTrueColor() + CVE-2016-5767 + * Sun May 29 2016 Remi Collet 5.4.45-9 - Fix #71331: Uninitialized pointer in phar_make_dirstream CVE-2016-4343 -- cgit