diff options
author | Remi Collet <fedora@famillecollet.com> | 2016-06-23 15:53:37 +0200 |
---|---|---|
committer | Remi Collet <fedora@famillecollet.com> | 2016-06-23 15:53:37 +0200 |
commit | 53a86c2a4f553385955475c30a25a2b0a50284f4 (patch) | |
tree | e3c3b9f5cfb68105af5b78eae42575de5df8ca97 | |
parent | 436225969c85449d3352c91b972a5e31828f68f0 (diff) |
PHP 5.4.45 with security fix from 5.5.37
-rw-r--r-- | bug72298.patch | 93 | ||||
-rw-r--r-- | bug72339.patch | 127 | ||||
-rw-r--r-- | bug72402.patch | 284 | ||||
-rw-r--r-- | bug72433.patch | 113 | ||||
-rw-r--r-- | bug72434.patch | 78 | ||||
-rw-r--r-- | bug72446.patch | 30 | ||||
-rw-r--r-- | bug72455.patch | 39 | ||||
-rw-r--r-- | failed.txt | 13 | ||||
-rw-r--r-- | php.spec | 33 |
9 files changed, 803 insertions, 7 deletions
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 <stas@php.net> +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-- ++<?php ++ if (!extension_loaded('gd')) die("skip gd extension not available\n"); ++?> ++--FILE-- ++<?php ++$img = imagecreatetruecolor (1 , 1); ++imagecolortransparent($img, 0); ++imagetruecolortopalette($img, false, 4); ++?> ++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 <pajoye@php.net> +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-- ++<?php if (!function_exists("imagecreatefromgd2")) print "skip"; ?> ++--FILE-- ++<?php imagecreatefromgd2(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug72339.gd"); ?> ++--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 <stas@php.net> +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 <ab@php.net> +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-- + <?php if (!function_exists("imagecreatefromgd2")) print "skip"; ?> + --FILE-- +-<?php imagecreatefromgd2(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug72339.gd"); ?> ++<?php ++$fname = dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug72339.gd"; ++ ++$fh = fopen($fname, "w"); ++fwrite($fh, "gd2\x00"); ++fwrite($fh, pack("n", 2)); ++fwrite($fh, pack("n", 1)); ++fwrite($fh, pack("n", 1)); ++fwrite($fh, pack("n", 0x40)); ++fwrite($fh, pack("n", 2)); ++fwrite($fh, pack("n", 0x5AA0)); // Chunks Wide ++fwrite($fh, pack("n", 0x5B00)); // Chunks Vertically ++fwrite($fh, str_repeat("\x41\x41\x41\x41", 0x1000000)); // overflow data ++fclose($fh); ++ ++$im = imagecreatefromgd2($fname); ++ ++if ($im) { ++ imagedestroy($im); ++} ++unlink($fname); ++ ++?> + --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/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 <stas@php.net> +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 <oniguruma.h> + #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-- ++<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> ++--FILE-- ++<?php ++function throwit() { ++ throw new Exception('it'); ++} ++$var10 = "throwit"; ++try { ++ $var14 = mb_ereg_replace_callback("", $var10, ""); ++} catch(Exception $e) {} ++?> ++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 <stas@php.net> +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-- ++<?php ++// Fill any potential freed spaces until now. ++$filler = array(); ++for($i = 0; $i < 100; $i++) ++ $filler[] = ""; ++// Create our payload and unserialize it. ++$serialized_payload = 'a:3:{i:0;r:1;i:1;r:1;i:2;C:11:"ArrayObject":19:{x:i:0;r:1;;m:a:0:{}}}'; ++$free_me = unserialize($serialized_payload); ++// We need to increment the reference counter of our ArrayObject s.t. all reference counters of our unserialized array become 0. ++$inc_ref_by_one = $free_me[2]; ++// The call to gc_collect_cycles will free '$free_me'. ++gc_collect_cycles(); ++// We now have multiple freed spaces. Fill all of them. ++$fill_freed_space_1 = "filler_zval_1"; ++$fill_freed_space_2 = "filler_zval_2"; ++var_dump($free_me); ++?> ++--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 <stas@php.net> +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 <stas@php.net> +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-- ++<?php ++if(!class_exists('zip')) die('ZipArchive'); ++?> ++--FILE-- ++<?php ++// The following array will be serialized and this representation will be freed later on. ++$free_me = array(new StdClass()); ++// Create our payload and unserialize it. ++$serialized_payload = 'a:3:{i:1;N;i:2;O:10:"ZipArchive":1:{s:8:"filename";'.serialize($free_me).'}i:1;R:4;}'; ++$unserialized_payload = unserialize($serialized_payload); ++gc_collect_cycles(); ++// The reference counter for $free_me is at -1 for PHP 7 right now. ++// Increment the reference counter by 1 -> 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 <stas@php.net> +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 <stas@php.net> +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); + @@ -1,20 +1,21 @@ -===== 5.5.45-9 (2016-05-29) +===== 5.5.45-10 (2016-06-23) $ grep -r 'Tests failed' /var/lib/mock/scl54*/build.log /var/lib/mock/scl54el6x/build.log:Tests failed : 1 /var/lib/mock/scl54el7x/build.log:Tests failed : 0 /var/lib/mock/scl54fc21x/build.log:Tests failed : 1 -/var/lib/mock/scl54fc22x/build.log:Tests failed : 2 -/var/lib/mock/scl54fc23x/build.log:Tests failed : 2 -/var/lib/mock/scl54fc24x/build.log:Tests failed : 2 +/var/lib/mock/scl54fc22x/build.log:Tests failed : 1 +/var/lib/mock/scl54fc23x/build.log:Tests failed : 3 +/var/lib/mock/scl54fc24x/build.log:Tests failed : 3 f23, f24 Bug #64802: openssl_x509_parse fails to parse subject properly in some cases [ext/openssl/tests/bug64802.phpt] + Bug #33414 [1] (Comprehensive list of incorrect days returned after strotime() / date() tests) [ext/date/tests/bug33414-1.phpt] f21, f22, f23, f24 Test strptime() function : basic functionality [ext/standard/tests/time/strptime_basic.phpt] -f22 - file_get_contents() test using offset parameter out of range [ext/standard/tests/file/file_get_contents_error001.phpt] el6 Bug #32001 (xml_parse*() goes into infinite loop when autodetection in effect), using UTF-* [ext/xml/tests/bug32001.phpt] +* bug33414-1.phpt fails with tzdata-2016e + @@ -214,7 +214,15 @@ 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 (300+) # Backported from 5.5 @@ -888,6 +896,13 @@ support for using the enchant library to PHP. %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 %patch300 -p1 -b .datetests1 @@ -1714,8 +1729,24 @@ EOF * Tue Jun 21 2016 Remi Collet <remi@fedoraproject.org> 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 and #72403: prevent signed int overflows for string lengths +- 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 <remi@fedoraproject.org> 5.4.45-9 - Fix #71331: Uninitialized pointer in phar_make_dirstream |