diff options
| -rw-r--r-- | bug72581.patch | 56 | ||||
| -rw-r--r-- | bug73017.patch | 90 | ||||
| -rw-r--r-- | bug73073.patch | 72 | ||||
| -rw-r--r-- | bug73082.patch | 46 | ||||
| -rw-r--r-- | bug73147.patch | 108 | ||||
| -rw-r--r-- | bug73150.patch | 37 | ||||
| -rw-r--r-- | bug73174.patch | 76 | ||||
| -rw-r--r-- | bug73189.patch | 78 | ||||
| -rw-r--r-- | bug73190.patch | 134 | ||||
| -rw-r--r-- | bug73208.patch | 28 | ||||
| -rw-r--r-- | bug73218.patch | 269 | ||||
| -rw-r--r-- | bug73240.patch | 141 | ||||
| -rw-r--r-- | bug73275.patch | 49 | ||||
| -rw-r--r-- | bug73276.patch | 42 | ||||
| -rw-r--r-- | bug73284.patch | 185 | ||||
| -rw-r--r-- | bug73293.patch | 179 | ||||
| -rw-r--r-- | failed.txt | 8 | ||||
| -rw-r--r-- | php55.spec | 54 | 
18 files changed, 1647 insertions, 5 deletions
diff --git a/bug72581.patch b/bug72581.patch new file mode 100644 index 0000000..06b9f50 --- /dev/null +++ b/bug72581.patch @@ -0,0 +1,56 @@ +Backported from 5.6.27 by Remi. + + +From 7903276f4c18fcfda06c02785f0b4201421f9c7c Mon Sep 17 00:00:00 2001 +From: Xinchen Hui <laruence@gmail.com> +Date: Tue, 12 Jul 2016 12:14:45 +0800 +Subject: [PATCH] backport to 5.6 (we should not unset the default value) + +--- + NEWS                                       | 2 ++ + Zend/zend_exceptions.c                     | 2 +- + ext/standard/tests/serialize/bug69152.phpt | 1 - + ext/standard/tests/serialize/bug69793.phpt | 2 -- + 4 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c +index 66476a1..fda4d21 100644 +--- a/Zend/zend_exceptions.c ++++ b/Zend/zend_exceptions.c +@@ -222,7 +222,7 @@ ZEND_METHOD(exception, __construct) +    Exception unserialize checks */ + #define CHECK_EXC_TYPE(name, type) \ + 	value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \ +-	if(value && Z_TYPE_P(value) != type) { \ ++	if (value && Z_TYPE_P(value) != IS_NULL && Z_TYPE_P(value) != type) { \ + 		zval *tmp; \ + 		MAKE_STD_ZVAL(tmp); \ + 		ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \ +diff --git a/ext/standard/tests/serialize/bug69152.phpt b/ext/standard/tests/serialize/bug69152.phpt +index bc2b302..4e74168 100644 +--- a/ext/standard/tests/serialize/bug69152.phpt ++++ b/ext/standard/tests/serialize/bug69152.phpt +@@ -9,7 +9,6 @@ $x->test(); +  + ?> + --EXPECTF-- +-Notice: Undefined property: Exception::$previous in %s on line %d + exception 'Exception' in %s:%d + Stack trace: + #0 {main} + +--- a/ext/standard/tests/serialize/bug69793.phpt	2016-07-20 10:41:48.000000000 +0200 ++++ b/ext/standard/tests/serialize/bug69793.phpt	2016-10-14 13:03:12.000000000 +0200 +@@ -7,11 +7,7 @@ + var_dump($e.""); + ?> + --EXPECTF-- +-Notice: Undefined property: Exception::$message in %s/bug69793.php on line %d +- +-Notice: Undefined property: Exception::$file in %s/bug69793.php on line %d +- +-Notice: Undefined property: Exception::$previous in %s/bug69793.php on line %d ++Notice: Undefined property: Exception::$file in %s%ebug69793.php on line %d + string(53) "exception 'Exception' in :1337 + Stack trace: + #0 {main}" diff --git a/bug73017.patch b/bug73017.patch new file mode 100644 index 0000000..c3809f8 --- /dev/null +++ b/bug73017.patch @@ -0,0 +1,90 @@ +Backported from 5.6.27 by Remi. + + +From 631173aa5c716f6d4a7bf1f6b7295482a46823bc Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Mon, 3 Oct 2016 18:06:59 -0700 +Subject: [PATCH] Really fix bug #73017 + +--- + ext/standard/string.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/ext/standard/string.c b/ext/standard/string.c +index 9acbe03..cb6a8b4 100644 +--- a/ext/standard/string.c ++++ b/ext/standard/string.c +@@ -891,11 +891,12 @@ PHP_FUNCTION(wordwrap) + { + 	const char *text, *breakchar = "\n"; + 	char *newtext; +-	int textlen, breakcharlen = 1, newtextlen, chk; ++	int textlen, breakcharlen = 1, chk; + 	size_t alloced; +-	long current = 0, laststart = 0, lastspace = 0; ++	size_t current = 0, laststart = 0, lastspace = 0; + 	long linelength = 75; + 	zend_bool docut = 0; ++	size_t newtextlen; +  + 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lsb", &text, &textlen, &linelength, &breakchar, &breakcharlen, &docut) == FAILURE) { + 		return; +@@ -915,6 +916,11 @@ PHP_FUNCTION(wordwrap) + 		RETURN_FALSE; + 	} +  ++	if (linelength < 0 || linelength > INT_MAX) { ++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length should be between 0 and %d", INT_MAX); ++		RETURN_FALSE; ++	} ++ + 	/* Special case for a single-character break as it needs no + 	   additional storage space */ + 	if (breakcharlen == 1 && !docut) { +@@ -942,10 +948,10 @@ PHP_FUNCTION(wordwrap) + 		if (linelength > 0) { + 			chk = (int)(textlen/linelength + 1); + 			newtext = safe_emalloc(chk, breakcharlen, textlen + 1); +-			alloced = textlen + chk * breakcharlen + 1; ++			alloced = (size_t)textlen + chk * (size_t)breakcharlen + 1; + 		} else { + 			chk = textlen; +-			alloced = textlen * (breakcharlen + 1) + 1; ++			alloced = (size_t)textlen * ((size_t)breakcharlen + 1) + 1; + 			newtext = safe_emalloc(textlen, (breakcharlen + 1), 1); + 		} +  +--  +2.1.4 + +From 8ea01d5f19a68a3f062c1e5d735372f8a48cbba8 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Mon, 3 Oct 2016 19:17:42 -0700 +Subject: [PATCH] Apparently negative wordwrap is a thing and should work as + length = 0. + +I'll leave it as is for now. +--- + ext/standard/string.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ext/standard/string.c b/ext/standard/string.c +index cb6a8b4..abe4eb1 100644 +--- a/ext/standard/string.c ++++ b/ext/standard/string.c +@@ -916,7 +916,11 @@ PHP_FUNCTION(wordwrap) + 		RETURN_FALSE; + 	} +  +-	if (linelength < 0 || linelength > INT_MAX) { ++	if (linelength < 0) { ++		/* For BC */ ++		linelength = 0; ++	} ++	if (linelength > INT_MAX) { + 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length should be between 0 and %d", INT_MAX); + 		RETURN_FALSE; + 	} +--  +2.1.4 + diff --git a/bug73073.patch b/bug73073.patch new file mode 100644 index 0000000..7831362 --- /dev/null +++ b/bug73073.patch @@ -0,0 +1,72 @@ +Backported from 5.6.27 by Remi. + + +From 33a8af0510c5899cbf9148f53da08cf4f2df0013 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 20 Sep 2016 22:59:12 -0700 +Subject: [PATCH] Fix bug #73073 - CachingIterator null dereference when + convert to string + +--- + ext/spl/spl_iterators.c     | 254 +++++++++++++++++++++++--------------------- + ext/spl/tests/bug73073.phpt |   9 ++ + 2 files changed, 141 insertions(+), 122 deletions(-) + create mode 100644 ext/spl/tests/bug73073.phpt + +diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c +index a023b11..c6d03e0 100644 +--- a/ext/spl/spl_iterators.c ++++ b/ext/spl/spl_iterators.c +@@ -2784,15 +2784,25 @@ SPL_METHOD(CachingIterator, __toString) +  + 	SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); +  ++	if (!spl_caching_it_valid(intern TSRMLS_CC)) { ++		RETURN_EMPTY_STRING(); ++	} ++ + 	if (!(intern->u.caching.flags & (CIT_CALL_TOSTRING|CIT_TOSTRING_USE_KEY|CIT_TOSTRING_USE_CURRENT|CIT_TOSTRING_USE_INNER)))	{ + 		zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not fetch string value (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + 		return; + 	} + 	if (intern->u.caching.flags & CIT_TOSTRING_USE_KEY) { ++		if (!intern->current.key) { ++			RETURN_EMPTY_STRING(); ++		} + 		MAKE_COPY_ZVAL(&intern->current.key, return_value); + 		convert_to_string(return_value); + 		return; + 	} else if (intern->u.caching.flags & CIT_TOSTRING_USE_CURRENT) { ++		if (!intern->current.data) { ++			RETURN_EMPTY_STRING(); ++		} + 		MAKE_COPY_ZVAL(&intern->current.data, return_value); + 		convert_to_string(return_value); + 		return; +@@ -2800,7 +2810,7 @@ SPL_METHOD(CachingIterator, __toString) + 	if (intern->u.caching.zstr) { + 		RETURN_STRINGL(Z_STRVAL_P(intern->u.caching.zstr), Z_STRLEN_P(intern->u.caching.zstr), 1); + 	} else { +-		RETURN_NULL(); ++		RETURN_EMPTY_STRING(); + 	} + } /* }}} */ +  +diff --git a/ext/spl/tests/bug73073.phpt b/ext/spl/tests/bug73073.phpt +new file mode 100644 +index 0000000..218a28e +--- /dev/null ++++ b/ext/spl/tests/bug73073.phpt +@@ -0,0 +1,9 @@ ++--TEST-- ++Bug #73073: CachingIterator null dereference when convert to string ++--FILE-- ++<?php ++$it = new CachingIterator(new ArrayIterator(array()), CachingIterator::TOSTRING_USE_KEY); ++var_dump((string)$it); ++?> ++--EXPECT-- ++string(0) "" +--  +2.1.4 + diff --git a/bug73082.patch b/bug73082.patch new file mode 100644 index 0000000..288eb14 --- /dev/null +++ b/bug73082.patch @@ -0,0 +1,46 @@ +Backported from 5.6.27 by Remi. + + +From e1709b7e588cbda71c577f6e5b701713d0c70a23 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Sun, 25 Sep 2016 16:07:14 -0700 +Subject: [PATCH] Fix bug #73082 + +--- + ext/mbstring/mbstring.c | 96 ++++++++++++++++++++++++------------------------- + 1 file changed, 48 insertions(+), 48 deletions(-) + +diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c +index 56f7cfa..cf5f8ed 100644 +--- a/ext/mbstring/mbstring.c ++++ b/ext/mbstring/mbstring.c +@@ -3349,7 +3349,7 @@ PHP_FUNCTION(mb_encode_mimeheader) + 	mbfl_string_init(&result); + 	ret = mbfl_mime_header_encode(&string, &result, charset, transenc, linefeed, indent); + 	if (ret != NULL) { +-		RETVAL_STRINGL((char *)ret->val, ret->len, 0);	/* the string is already strdup()'ed */ ++		RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0);	/* the string is already strdup()'ed */ + 	} else { + 		RETVAL_FALSE; + 	} +@@ -3476,7 +3476,7 @@ PHP_FUNCTION(mb_convert_kana) +  + 	ret = mbfl_ja_jp_hantozen(&string, &result, opt); + 	if (ret != NULL) { +-		RETVAL_STRINGL((char *)ret->val, ret->len, 0);		/* the string is already strdup()'ed */ ++		RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0);		/* the string is already strdup()'ed */ + 	} else { + 		RETVAL_FALSE; + 	} +@@ -3772,7 +3772,7 @@ php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type) +  + 	ret = mbfl_html_numeric_entity(&string, &result, convmap, mapsize, type); + 	if (ret != NULL) { +-		RETVAL_STRINGL((char *)ret->val, ret->len, 0); ++		RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0); + 	} else { + 		RETVAL_FALSE; + 	} +--  +2.1.4 + diff --git a/bug73147.patch b/bug73147.patch new file mode 100644 index 0000000..f7cb829 --- /dev/null +++ b/bug73147.patch @@ -0,0 +1,108 @@ +Backported from 5.6.27 by Remi. + + +From 0e6fe3a4c96be2d3e88389a5776f878021b4c59f Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Sun, 25 Sep 2016 19:53:59 -0700 +Subject: [PATCH] Fix bug #73147: Use After Free in PHP7 unserialize() + +--- + Zend/zend_API.c              | 24 ++++++++++++++++++++++++ + Zend/zend_API.h              |  1 + + ext/curl/curl_file.c         |  5 ++++- + ext/curl/tests/bug73147.phpt | 20 ++++++++++++++++++++ + 4 files changed, 49 insertions(+), 1 deletion(-) + create mode 100644 ext/curl/tests/bug73147.phpt + +diff --git a/Zend/zend_API.c b/Zend/zend_API.c +index 8202b9a..0757cc9 100644 +--- a/Zend/zend_API.c ++++ b/Zend/zend_API.c +@@ -3721,6 +3721,30 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const + } + /* }}} */ +  ++ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC) /* {{{ */ ++{ ++	zval *property; ++	zend_class_entry *old_scope = EG(scope); ++ ++	EG(scope) = scope; ++ ++	if (!Z_OBJ_HT_P(object)->unset_property) { ++		const char *class_name; ++		zend_uint class_name_len; ++ ++		zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC); ++ ++		zend_error(E_CORE_ERROR, "Property %s of class %s cannot be unset", name, class_name); ++	} ++	MAKE_STD_ZVAL(property); ++	ZVAL_STRINGL(property, name, name_length, 1); ++	Z_OBJ_HT_P(object)->unset_property(object, property, 0 TSRMLS_CC); ++	zval_ptr_dtor(&property); ++ ++	EG(scope) = old_scope; ++} ++/* }}} */ ++ + ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC) /* {{{ */ + { + 	zval *tmp; +diff --git a/Zend/zend_API.h b/Zend/zend_API.h +index 53c1a4c..c57c003 100644 +--- a/Zend/zend_API.h ++++ b/Zend/zend_API.h +@@ -327,6 +327,7 @@ ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, c + ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, int name_length, double value TSRMLS_DC); + ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value TSRMLS_DC); + ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value, int value_length TSRMLS_DC); ++ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC); +  + ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, int name_length, zval *value TSRMLS_DC); + ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, int name_length TSRMLS_DC); +diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c +index 56c1bbe..029a58a 100644 +--- a/ext/curl/curl_file.c ++++ b/ext/curl/curl_file.c +@@ -137,7 +137,10 @@ ZEND_METHOD(CURLFile, setPostFilename) +    Unserialization handler */ + ZEND_METHOD(CURLFile, __wakeup) + { +-	zend_update_property_string(curl_CURLFile_class, getThis(), "name", sizeof("name")-1, "" TSRMLS_CC); ++	zval *_this = getThis(); ++ ++	zend_unset_property(curl_CURLFile_class, _this, "name", sizeof("name")-1 TSRMLS_CC); ++	zend_update_property_string(curl_CURLFile_class, _this, "name", sizeof("name")-1, "" TSRMLS_CC); + 	zend_throw_exception(NULL, "Unserialization of CURLFile instances is not allowed", 0 TSRMLS_CC); + } + /* }}} */ +diff --git a/ext/curl/tests/bug73147.phpt b/ext/curl/tests/bug73147.phpt +new file mode 100644 +index 0000000..118177d +--- /dev/null ++++ b/ext/curl/tests/bug73147.phpt +@@ -0,0 +1,20 @@ ++--TEST-- ++Bug #73147: Use After Free in PHP7 unserialize() ++--SKIPIF-- ++<?php ++if (!extension_loaded("curl")) { ++        exit("skip curl extension not loaded"); ++} ++?> ++--FILE-- ++<?php ++ ++$poc = 'a:1:{i:0;O:8:"CURLFile":1:{s:4:"name";R:1;}}'; ++try { ++var_dump(unserialize($poc)); ++} catch(Exception $e) { ++	echo $e->getMessage(); ++} ++?> ++--EXPECT-- ++Unserialization of CURLFile instances is not allowed +--  +2.1.4 + diff --git a/bug73150.patch b/bug73150.patch new file mode 100644 index 0000000..0482167 --- /dev/null +++ b/bug73150.patch @@ -0,0 +1,37 @@ +Backported from 5.6.27 by Remi. + + +From 1c0e9126fbfb7fde3173347b7464237f56c38bfa Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Sun, 25 Sep 2016 21:25:01 -0700 +Subject: [PATCH] Fix bug #73150: missing NULL check in dom_document_save_html + +--- + ext/dom/document.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ext/dom/document.c b/ext/dom/document.c +index d33aaf1..1970c38 100644 +--- a/ext/dom/document.c ++++ b/ext/dom/document.c +@@ -1853,7 +1853,7 @@ PHP_FUNCTION(dom_document_savexml) + 		if (options & LIBXML_SAVE_NOEMPTYTAG) { + 			xmlSaveNoEmptyTags = saveempty; + 		} +-		if (!size) { ++		if (!size || !mem) { + 			RETURN_FALSE; + 		} + 		RETVAL_STRINGL(mem, size, 1); +@@ -2388,7 +2388,7 @@ PHP_FUNCTION(dom_document_save_html) + #else + 		htmlDocDumpMemory(docp, &mem, &size); + #endif +-		if (!size) { ++		if (!size || !mem) { + 			RETVAL_FALSE; + 		} else { + 			RETVAL_STRINGL((const char*) mem, size, 1); +--  +2.1.4 + 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 + diff --git a/bug73189.patch b/bug73189.patch new file mode 100644 index 0000000..7cfc2d8 --- /dev/null +++ b/bug73189.patch @@ -0,0 +1,78 @@ +Backported from 5.6.27 by Remi. + + +From da7e89cde880c66887caacd0a3eae7ecdacf9b2a Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Wed, 28 Sep 2016 23:30:48 -0700 +Subject: [PATCH] Fix bug #73189 - Memcpy negative size parameter + php_resolve_path + +--- + main/fopen_wrappers.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c +index 74a493b..af9c558 100644 +--- a/main/fopen_wrappers.c ++++ b/main/fopen_wrappers.c +@@ -211,7 +211,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path + 			if (path_len > 1 && path_tmp[path_len - 2] == ':') { + 				if (path_len != 3) { + 					return -1; +-				}  ++				} + 				/* this is c:\ */ + 				path_tmp[path_len] = '\0'; + 			} else { +@@ -401,7 +401,7 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) + 				spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */ + 			} else { + 				filename = SG(request_info).path_translated; +-			}  ++			} + #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) + 			efree(pwbuf); + #endif +@@ -494,8 +494,8 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c + 		return NULL; + 	} +  +-	if ((*filename == '.' &&  +-	     (IS_SLASH(filename[1]) ||  ++	if ((*filename == '.' && ++	     (IS_SLASH(filename[1]) || + 	      ((filename[1] == '.') && IS_SLASH(filename[2])))) || + 	    IS_ABSOLUTE_PATH(filename, filename_length) || + 	    !path || +@@ -522,7 +522,7 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c + 		} + 		end = strchr(p, DEFAULT_DIR_SEPARATOR); + 		if (end) { +-			if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) { ++			if (filename_length > (MAXPATHLEN - 2) || (end-ptr) > MAXPATHLEN || (end-ptr) + 1 + (size_t)filename_length + 1 >= MAXPATHLEN) { + 				ptr = end + 1; + 				continue; + 			} +@@ -531,9 +531,9 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c + 			memcpy(trypath+(end-ptr)+1, filename, filename_length+1); + 			ptr = end+1; + 		} else { +-			int len = strlen(ptr); ++			size_t len = strlen(ptr); +  +-			if (len + 1 + filename_length + 1 >= MAXPATHLEN) { ++			if (filename_length > (MAXPATHLEN - 2) || len > MAXPATHLEN || (size_t)len + 1 + (size_t)filename_length + 1 >= MAXPATHLEN) { + 				break; + 			} + 			memcpy(trypath, ptr, len); +@@ -571,6 +571,7 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c + 		while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); + 		if (exec_fname && exec_fname[0] != '[' && + 		    exec_fname_length > 0 && ++			filename_length < (MAXPATHLEN - 2) && + 		    exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) { + 			memcpy(trypath, exec_fname, exec_fname_length + 1); + 			memcpy(trypath+exec_fname_length + 1, filename, filename_length+1); +--  +2.1.4 + diff --git a/bug73190.patch b/bug73190.patch new file mode 100644 index 0000000..ccbb388 --- /dev/null +++ b/bug73190.patch @@ -0,0 +1,134 @@ +Backported from 5.6.27 by Remi. + + +From 40e7baab3c90001beee4c8f0ed0ef79ad18ee0d6 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Mon, 3 Oct 2016 00:09:02 -0700 +Subject: [PATCH] Fix bug #73190: memcpy negative parameter _bc_new_num_ex + +--- + Zend/zend_exceptions.c              | 32 ++++++++++++++++++++++++-------- + ext/bcmath/libbcmath/src/init.c     |  5 ++++- + ext/bcmath/libbcmath/src/outofmem.c |  3 +-- + main/php_version.h                  |  6 +++--- + 4 files changed, 32 insertions(+), 14 deletions(-) + +diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c +index fda4d21..e656575 100644 +--- a/Zend/zend_exceptions.c ++++ b/Zend/zend_exceptions.c +@@ -221,13 +221,9 @@ ZEND_METHOD(exception, __construct) + /* {{{ proto Exception::__wakeup() +    Exception unserialize checks */ + #define CHECK_EXC_TYPE(name, type) \ +-	value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \ ++	value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 1 TSRMLS_CC); \ + 	if (value && Z_TYPE_P(value) != IS_NULL && Z_TYPE_P(value) != type) { \ +-		zval *tmp; \ +-		MAKE_STD_ZVAL(tmp); \ +-		ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \ +-		Z_OBJ_HANDLER_P(object, unset_property)(object, tmp, 0 TSRMLS_CC); \ +-		zval_ptr_dtor(&tmp); \ ++		zend_unset_property(default_exception_ce, object, name, sizeof(name)-1 TSRMLS_CC); \ + 	} +  + ZEND_METHOD(exception, __wakeup) +@@ -241,7 +237,12 @@ ZEND_METHOD(exception, __wakeup) + 	CHECK_EXC_TYPE("file", IS_STRING); + 	CHECK_EXC_TYPE("line", IS_LONG); + 	CHECK_EXC_TYPE("trace", IS_ARRAY); +-	CHECK_EXC_TYPE("previous", IS_OBJECT); ++	value = zend_read_property(default_exception_ce, object, "previous", sizeof("previous")-1, 1 TSRMLS_CC); ++	if (value && Z_TYPE_P(value) != IS_NULL && (Z_TYPE_P(value) != IS_OBJECT || ++			!instanceof_function(Z_OBJCE_P(value), default_exception_ce TSRMLS_CC) || ++			value == object)) { ++		zend_unset_property(default_exception_ce, object, "previous", sizeof("previous")-1 TSRMLS_CC); ++	} + } + /* }}} */ +  +@@ -719,7 +720,11 @@ ZEND_METHOD(exception, __toString) + 		zval_dtor(&file); + 		zval_dtor(&line); +  +-		exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 0 TSRMLS_CC); ++		Z_OBJPROP_P(exception)->nApplyCount++; ++		exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); ++		if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_OBJPROP_P(exception)->nApplyCount > 0) { ++			exception = NULL; ++		} +  + 		if (trace) { + 			zval_ptr_dtor(&trace); +@@ -728,6 +733,17 @@ ZEND_METHOD(exception, __toString) + 	} + 	zval_dtor(&fname); +  ++	/* Reset apply counts */ ++	exception = getThis(); ++	while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) { ++		if(Z_OBJPROP_P(exception)->nApplyCount) { ++			Z_OBJPROP_P(exception)->nApplyCount--; ++		} else { ++			break; ++		} ++		exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); ++	} ++ + 	/* We store the result in the private property string so we can access + 	 * the result in uncaught exception handlers without memleaks. */ + 	zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC); +diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c +index 986ad1d..c51133b 100644 +--- a/ext/bcmath/libbcmath/src/init.c ++++ b/ext/bcmath/libbcmath/src/init.c +@@ -49,7 +49,10 @@ _bc_new_num_ex (length, scale, persistent) +      int length, scale, persistent; + { +   bc_num temp; +- ++  /* PHP Change:  add length check */ ++  if ((size_t)length+(size_t)scale > INT_MAX) { ++   zend_error(E_ERROR, "Result too long, max is %d", INT_MAX); ++  } +   /* PHP Change:  malloc() -> pemalloc(), removed free_list code */ +   temp = (bc_num) safe_pemalloc (1, sizeof(bc_struct)+length, scale, persistent); + #if 0 +diff --git a/ext/bcmath/libbcmath/src/outofmem.c b/ext/bcmath/libbcmath/src/outofmem.c +index 799a32d..05fa484 100644 +--- a/ext/bcmath/libbcmath/src/outofmem.c ++++ b/ext/bcmath/libbcmath/src/outofmem.c +@@ -41,6 +41,5 @@ +  + void bc_out_of_memory (void) + { +-  (void) fprintf (stderr, "bcmath: out of memory!\n"); +-  exit (1); ++  zend_error_noreturn(E_ERROR, "bcmath: out of memory!"); + } +--  +2.1.4 + +From e1f5b6d8dfe1543205d5b45d3dcf1d34f5e2e420 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@php.net> +Date: Fri, 14 Oct 2016 10:53:40 +0200 +Subject: [PATCH] use zend_error instead of zend_error_noreturn + +--- + ext/bcmath/libbcmath/src/outofmem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/bcmath/libbcmath/src/outofmem.c b/ext/bcmath/libbcmath/src/outofmem.c +index 05fa484..ba92450 100644 +--- a/ext/bcmath/libbcmath/src/outofmem.c ++++ b/ext/bcmath/libbcmath/src/outofmem.c +@@ -41,5 +41,5 @@ +  + void bc_out_of_memory (void) + { +-  zend_error_noreturn(E_ERROR, "bcmath: out of memory!"); ++  zend_error(E_ERROR, "bcmath: out of memory!"); + } +--  +2.1.4 + diff --git a/bug73208.patch b/bug73208.patch new file mode 100644 index 0000000..7855fb6 --- /dev/null +++ b/bug73208.patch @@ -0,0 +1,28 @@ +Backported from 5.6.27 by Remi. + + +From ef801b9bf96fb46b0418772a11a9b38f52cd93b4 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Mon, 3 Oct 2016 00:12:14 -0700 +Subject: [PATCH] Fix bug #73208 - another missing length check + +--- + ext/imap/php_imap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c +index 8fe9de9..564473b 100644 +--- a/ext/imap/php_imap.c ++++ b/ext/imap/php_imap.c +@@ -2518,7 +2518,7 @@ PHP_FUNCTION(imap_8bit) + 		RETURN_FALSE; + 	} +  +-	RETVAL_STRINGL(decode, newlength, 1); ++	RETVAL_STRINGL_CHECK(decode, newlength, 1); + 	fs_give((void**) &decode); + } + /* }}} */ +--  +2.1.4 + diff --git a/bug73218.patch b/bug73218.patch new file mode 100644 index 0000000..eacf5db --- /dev/null +++ b/bug73218.patch @@ -0,0 +1,269 @@ +Backported from 5.6.27 by Remi. + + +From d946d102936525bc7dcd01f3827d0a6e0bb971b0 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 4 Oct 2016 22:40:09 -0700 +Subject: [PATCH] Bug #73218: add mitigation for ICU int overflow + +--- + ext/intl/resourcebundle/resourcebundle_class.c | 42 +++++++++++++++++--------- + 1 file changed, 27 insertions(+), 15 deletions(-) + +diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c +index dc12124..90aebd4 100644 +--- a/ext/intl/resourcebundle/resourcebundle_class.c ++++ b/ext/intl/resourcebundle/resourcebundle_class.c +@@ -77,7 +77,7 @@ static zend_object_value ResourceBundle_object_create( zend_class_entry *ce TSRM + /* }}} */ +  + /* {{{ ResourceBundle_ctor */ +-static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)  ++static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) + { + 	const char	*bundlename; + 	int			bundlename_len = 0; +@@ -90,7 +90,7 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) +  + 	intl_error_reset( NULL TSRMLS_CC ); +  +-	if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s!s!|b",  ++	if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s!s!|b", + 		&locale, &locale_len, &bundlename, &bundlename_len, &fallback ) == FAILURE ) + 	{ + 		intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, +@@ -100,11 +100,18 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) + 	} +  + 	INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); +-	 ++ + 	if (locale == NULL) { + 		locale = intl_locale_get_default(TSRMLS_C); + 	} +  ++	if (bundlename_len >= MAXPATHLEN) { ++		intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,	"Bundle name too long", 0 TSRMLS_CC ); ++		zval_dtor(return_value); ++		ZVAL_NULL(return_value); ++		RETURN_NULL(); ++	} ++ + 	if (fallback) { + 		rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); + 	} else { +@@ -151,7 +158,7 @@ PHP_METHOD( ResourceBundle, __construct ) + /* {{{ proto ResourceBundle ResourceBundle::create( string $locale [, string $bundlename [, bool $fallback = true ]] ) + proto ResourceBundle resourcebundle_create( string $locale [, string $bundlename [, bool $fallback = true ]] ) + */ +-PHP_FUNCTION( resourcebundle_create )  ++PHP_FUNCTION( resourcebundle_create ) + { + 	object_init_ex( return_value, ResourceBundle_ce_ptr ); + 	resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); +@@ -159,7 +166,7 @@ PHP_FUNCTION( resourcebundle_create ) + /* }}} */ +  + /* {{{ resourcebundle_array_fetch */ +-static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC)  ++static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC) + { + 	int32_t     meindex = 0; + 	char *      mekey = NULL; +@@ -167,7 +174,7 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_ + 	char         *pbuf; + 	ResourceBundle_object *rb; +  +-	intl_error_reset( NULL TSRMLS_CC );	 ++	intl_error_reset( NULL TSRMLS_CC ); + 	RESOURCEBUNDLE_METHOD_FETCH_OBJECT; +  + 	if(Z_TYPE_P(offset) == IS_LONG) { +@@ -178,12 +185,12 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_ + 		mekey = Z_STRVAL_P(offset); + 		rb->child = ures_getByKey(rb->me, mekey, rb->child, &INTL_DATA_ERROR_CODE(rb) ); + 	} else { +-		intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR,	 ++		intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR, + 			"resourcebundle_get: index should be integer or string", 0 TSRMLS_CC); + 		RETURN_NULL(); + 	} +  +-	intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );	 ++	intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC ); + 	if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) { + 		if (is_numeric) { + 			spprintf( &pbuf, 0, "Cannot load resource element %d", meindex ); +@@ -213,7 +220,7 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_ + /* }}} */ +  + /* {{{ resourcebundle_array_get */ +-zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC)  ++zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC) + { + 	zval *retval; +  +@@ -246,7 +253,7 @@ PHP_FUNCTION( resourcebundle_get ) + 	zval *      object; +  + 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz|b",	&object, ResourceBundle_ce_ptr, &offset, &fallback ) == FAILURE) { +-		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,	 ++		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + 			"resourcebundle_get: unable to parse input params", 0 TSRMLS_CC); + 		RETURN_FALSE; + 	} +@@ -256,7 +263,7 @@ PHP_FUNCTION( resourcebundle_get ) + /* }}} */ +  + /* {{{ resourcebundle_array_count */ +-int resourcebundle_array_count(zval *object, long *count TSRMLS_DC)  ++int resourcebundle_array_count(zval *object, long *count TSRMLS_DC) + { + 	ResourceBundle_object *rb; + 	RESOURCEBUNDLE_METHOD_FETCH_OBJECT_NO_CHECK; +@@ -288,7 +295,7 @@ PHP_FUNCTION( resourcebundle_count ) + 	RESOURCEBUNDLE_METHOD_INIT_VARS; +  + 	if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, ResourceBundle_ce_ptr ) == FAILURE ) { +-		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,	 ++		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + 			"resourcebundle_count: unable to parse input params", 0 TSRMLS_CC); + 		RETURN_FALSE; + 	} +@@ -322,21 +329,26 @@ PHP_FUNCTION( resourcebundle_locales ) +  + 	if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &bundlename, &bundlename_len ) == FAILURE ) + 	{ +-		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,	 ++		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + 			"resourcebundle_locales: unable to parse input params", 0 TSRMLS_CC); + 		RETURN_FALSE; + 	} +  ++	if (bundlename_len >= MAXPATHLEN) { ++		intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,	"resourcebundle_locales: bundle name too long", 0 TSRMLS_CC ); ++		RETURN_FALSE; ++	} ++ + 	if(bundlename_len == 0) { + 		// fetch default locales list + 		bundlename = NULL; + 	} +  + 	icuenum = ures_openAvailableLocales( bundlename, &icuerror ); +-	INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list");		 ++	INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list"); +  + 	uenum_reset( icuenum, &icuerror ); +-	INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list");		 ++	INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list"); +  + 	array_init( return_value ); + 	while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) { +--  +2.1.4 + +From d3eb58332af433982f1e2ae9095fb087974a95f2 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 4 Oct 2016 21:28:40 -0700 +Subject: [PATCH] Add more locale length checks, due to ICU bugs. + +--- + ext/intl/locale/locale_methods.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c +index 443856f..862b9f5 100644 +--- a/ext/intl/locale/locale_methods.c ++++ b/ext/intl/locale/locale_methods.c +@@ -395,6 +395,8 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) + 	if(loc_name_len == 0) { + 		loc_name = intl_locale_get_default(TSRMLS_C); + 	} ++	 ++	INTL_CHECK_LOCALE_LEN(strlen(loc_name)); +  + 	/* Call ICU get */ + 	tag_value = get_icu_value_internal( loc_name , tag_name , &result ,0); +@@ -1159,6 +1161,7 @@ PHP_FUNCTION(locale_get_all_variants) + 		loc_name = intl_locale_get_default(TSRMLS_C); + 	} +  ++	INTL_CHECK_LOCALE_LEN(strlen(loc_name)); +  + 	array_init( return_value ); +  +@@ -1267,6 +1270,9 @@ PHP_FUNCTION(locale_filter_matches) + 		RETURN_TRUE; + 	} +  ++	INTL_CHECK_LOCALE_LEN(strlen(loc_range)); ++	INTL_CHECK_LOCALE_LEN(strlen(lang_tag)); ++ + 	if( boolCanonical ){ + 		/* canonicalize loc_range */ + 		can_loc_range=get_icu_value_internal( loc_range , LOC_CANONICALIZE_TAG , &result , 0); +@@ -1549,6 +1555,8 @@ PHP_FUNCTION(locale_lookup) + 		loc_range = intl_locale_get_default(TSRMLS_C); + 	} +  ++	INTL_CHECK_LOCALE_LEN(strlen(loc_range)); ++ + 	hash_arr = HASH_OF(arr); +  + 	if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) { +--  +2.1.4 + +From 082d1f237531ab71c3050dfb9f598344f654d9e1 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 11 Oct 2016 16:16:20 -0700 +Subject: [PATCH] Fix tests + +--- + ext/intl/tests/bug72241.phpt                            | 4 +--- + ext/spl/spl_iterators.c                                 | 4 ---- + ext/spl/tests/spl_cachingiterator___toString_basic.phpt | 2 +- + ext/standard/tests/serialize/bug69793.phpt              | 2 -- + 4 files changed, 2 insertions(+), 10 deletions(-) + +diff --git a/ext/intl/tests/bug72241.phpt b/ext/intl/tests/bug72241.phpt +index 397e1e7..7ac5a5b 100644 +--- a/ext/intl/tests/bug72241.phpt ++++ b/ext/intl/tests/bug72241.phpt +@@ -9,6 +9,4 @@ $out = locale_get_primary_language($var1); + echo strlen($out) . PHP_EOL; + echo unpack('H*', $out)[1] . PHP_EOL; + --EXPECT-- +-1000 +-61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 +- ++0 +diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c +index c6d03e0..154aba0 100644 +--- a/ext/spl/spl_iterators.c ++++ b/ext/spl/spl_iterators.c +@@ -2784,10 +2784,6 @@ SPL_METHOD(CachingIterator, __toString) +  + 	SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); +  +-	if (!spl_caching_it_valid(intern TSRMLS_CC)) { +-		RETURN_EMPTY_STRING(); +-	} +- + 	if (!(intern->u.caching.flags & (CIT_CALL_TOSTRING|CIT_TOSTRING_USE_KEY|CIT_TOSTRING_USE_CURRENT|CIT_TOSTRING_USE_INNER)))	{ + 		zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not fetch string value (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + 		return; +diff --git a/ext/spl/tests/spl_cachingiterator___toString_basic.phpt b/ext/spl/tests/spl_cachingiterator___toString_basic.phpt +index 0395b37..57ca515 100644 +--- a/ext/spl/tests/spl_cachingiterator___toString_basic.phpt ++++ b/ext/spl/tests/spl_cachingiterator___toString_basic.phpt +@@ -13,4 +13,4 @@ $ci->__toString() // if conversion to string is done by echo, for example, an ex + ); + ?> + --EXPECTF-- +-NULL ++string(0) "" +--  +2.1.4 + diff --git a/bug73240.patch b/bug73240.patch new file mode 100644 index 0000000..9f0d435 --- /dev/null +++ b/bug73240.patch @@ -0,0 +1,141 @@ +Backported from 5.6.27 by Remi. + + +From 8259130b6bc752968856b352c9e7f8e03a8c0a8e Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Mon, 10 Oct 2016 23:42:50 -0700 +Subject: [PATCH] Fix for #73240 - Write out of bounds at number_format + +--- + ext/standard/math.c | 108 +++++++++++++++++++++++++++++----------------------- + 1 file changed, 60 insertions(+), 48 deletions(-) + +diff --git a/ext/standard/math.c b/ext/standard/math.c +index 5ffeff7..8290b20 100644 +--- a/ext/standard/math.c ++++ b/ext/standard/math.c +@@ -1099,13 +1099,13 @@ PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char tho +  + static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, + 		size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len, +-		int *result_len) ++		size_t *result_len) + { + 	char *tmpbuf = NULL, *resbuf; + 	char *s, *t;  /* source, target */ + 	char *dp; +-	int integral; +-	int tmplen, reslen=0; ++	size_t integral; ++	size_t tmplen, reslen=0; + 	int count=0; + 	int is_negative=0; +  +@@ -1144,15 +1144,23 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, +  + 	/* allow for thousand separators */ + 	if (thousand_sep) { ++		if (integral + thousand_sep_len * ((integral-1) / 3) < integral) { ++			/* overflow */ ++			php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); ++		} + 		integral += thousand_sep_len * ((integral-1) / 3); + 	} +-	 ++ + 	reslen = integral; +-	 ++ + 	if (dec) { + 		reslen += dec; +  + 		if (dec_point) { ++			if (reslen + dec_point < dec_point) { ++				/* overflow */ ++				php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); ++			} + 			reslen += dec_point_len; + 		} + 	} +@@ -1235,17 +1243,21 @@ PHP_FUNCTION(number_format) + 	char *thousand_sep = NULL, *dec_point = NULL; + 	char thousand_sep_chr = ',', dec_point_chr = '.'; + 	int thousand_sep_len = 0, dec_point_len = 0; +-	 ++	char *formatted; ++	size_t formatted_len; ++ + 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|ls!s!", &num, &dec, &dec_point, &dec_point_len, &thousand_sep, &thousand_sep_len) == FAILURE) { + 		return; + 	} +  + 	switch(ZEND_NUM_ARGS()) { + 	case 1: +-		RETURN_STRING(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr), 0); ++		formatted = _php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr); ++		formatted_len = strlen(formatted); + 		break; + 	case 2: +-		RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0); ++		formatted = _php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr); ++		formatted_len = strlen(formatted); + 		break; + 	case 4: + 		if (dec_point == NULL) { +@@ -1258,15 +1270,15 @@ PHP_FUNCTION(number_format) + 			thousand_sep_len = 1; + 		} +  +-		Z_TYPE_P(return_value) = IS_STRING; +-		Z_STRVAL_P(return_value) = _php_math_number_format_ex_len(num, dec, ++		formatted = _php_math_number_format_ex_len(num, dec, + 				dec_point, dec_point_len, thousand_sep, thousand_sep_len, +-				&Z_STRLEN_P(return_value)); ++				&formatted_len); + 		break; + 	default: + 		WRONG_PARAM_COUNT; +-		break; ++		return; + 	} ++	RETVAL_STRINGL_CHECK(formatted, formatted_len, 0); + } + /* }}} */ +  +--  +2.1.4 + +From c1112ff323c9dd1a4596aa4272e918acf0f797eb Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 11 Oct 2016 14:39:16 -0700 +Subject: [PATCH] fix tsrm + +--- + ext/standard/math.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ext/standard/math.c b/ext/standard/math.c +index 8290b20..bb64425 100644 +--- a/ext/standard/math.c ++++ b/ext/standard/math.c +@@ -1146,7 +1146,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, + 	if (thousand_sep) { + 		if (integral + thousand_sep_len * ((integral-1) / 3) < integral) { + 			/* overflow */ +-			php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); ++			zend_error(E_ERROR, "String overflow"); + 		} + 		integral += thousand_sep_len * ((integral-1) / 3); + 	} +@@ -1159,7 +1159,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, + 		if (dec_point) { + 			if (reslen + dec_point < dec_point) { + 				/* overflow */ +-				php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); ++				zend_error(E_ERROR, "String overflow"); + 			} + 			reslen += dec_point_len; + 		} +--  +2.1.4 + diff --git a/bug73275.patch b/bug73275.patch new file mode 100644 index 0000000..2b36171 --- /dev/null +++ b/bug73275.patch @@ -0,0 +1,49 @@ +Backported from 5.6.27 by Remi. + + +From 8822f7c9f0be2f591f8fa58834c5e1bc529b24dc Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 11 Oct 2016 13:19:20 -0700 +Subject: [PATCH] fix bug #73275 - crash in openssl_encrypt function + +--- + ext/openssl/openssl.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c +index 844132b..33593e7 100644 +--- a/ext/openssl/openssl.c ++++ b/ext/openssl/openssl.c +@@ -4939,7 +4939,7 @@ PHP_FUNCTION(openssl_encrypt) + 	free_iv = php_openssl_validate_iv(&iv, &iv_len, max_iv_len TSRMLS_CC); +  + 	outlen = data_len + EVP_CIPHER_block_size(cipher_type); +-	outbuf = emalloc(outlen + 1); ++	outbuf = safe_emalloc(outlen, 1, 1); +  + 	EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL); + 	if (password_len > keylen) { +@@ -4957,14 +49575,18 @@ PHP_FUNCTION(openssl_encrypt) + 		outlen += i; + 		if (options & OPENSSL_RAW_DATA) { + 			outbuf[outlen] = '\0'; +-			RETVAL_STRINGL((char *)outbuf, outlen, 0); ++			RETVAL_STRINGL_CHECK((char *)outbuf, outlen, 0); + 		} else { + 			int base64_str_len; + 			char *base64_str; +  + 			base64_str = (char*)php_base64_encode(outbuf, outlen, &base64_str_len); + 			efree(outbuf); +-			RETVAL_STRINGL(base64_str, base64_str_len, 0); ++			if (!base64_str) { ++				RETVAL_FALSE; ++			} else { ++				RETVAL_STRINGL(base64_str, base64_str_len, 0); ++			} + 		} + 	} else { + 		efree(outbuf); +--  +2.1.4 + diff --git a/bug73276.patch b/bug73276.patch new file mode 100644 index 0000000..3f5fd3c --- /dev/null +++ b/bug73276.patch @@ -0,0 +1,42 @@ +Backported from 5.6.27 by Remi. + + +From 85a22a0af0722ef3a8d49a056a0b2b18be1fb981 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 11 Oct 2016 13:37:47 -0700 +Subject: [PATCH] Fix bug #73276 - crash in openssl_random_pseudo_bytes + function + +--- + ext/openssl/openssl.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c +index 33593e7..01f2a09 100644 +--- a/ext/openssl/openssl.c ++++ b/ext/openssl/openssl.c +@@ -5145,16 +5145,16 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) + 		return; + 	} +  +-	if (buffer_length <= 0) { +-		RETURN_FALSE; +-	} +- + 	if (zstrong_result_returned) { + 		zval_dtor(zstrong_result_returned); + 		ZVAL_BOOL(zstrong_result_returned, 0); + 	} +  +-	buffer = emalloc(buffer_length + 1); ++	if (buffer_length <= 0 || buffer_length > INT_MAX) { ++		RETURN_FALSE; ++	} ++ ++	buffer = safe_emalloc(buffer_length, 1, 1); +  + #ifdef PHP_WIN32 + 	/* random/urandom equivalent on Windows */ +--  +2.1.4 + 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 <stas@php.net> +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 + diff --git a/bug73293.patch b/bug73293.patch new file mode 100644 index 0000000..5be3171 --- /dev/null +++ b/bug73293.patch @@ -0,0 +1,179 @@ +Backported from 5.6.27 by Remi. + + +From 19866fb76cf4c95d904ebb0e08592cf38303fae9 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Thu, 1 Sep 2016 23:15:34 -0700 +Subject: [PATCH] Fix various int size overflows. + +Add function for detection of string zvals with length that does not fit +INT_MAX. +--- + Zend/zend_API.c       |  61 ++++++++++++++--- + Zend/zend_API.h       |  14 ++++ + Zend/zend_alloc.c     |   9 +++ + Zend/zend_alloc.h     |   4 +- + ext/imap/php_imap.c   |  28 +++++--- + ext/ldap/ldap.c       |   2 +- + ext/pcre/php_pcre.c   |  14 ++-- + ext/pgsql/pgsql.c     | 186 +++++++++++++++++++++++++------------------------- + ext/standard/string.c |  23 +++---- + ext/xml/xml.c         |   4 +- + ext/zlib/zlib.c       |   8 +-- + 11 files changed, 210 insertions(+), 143 deletions(-) + +diff --git a/Zend/zend_API.h b/Zend/zend_API.h +index e17be4c..3e191b6 100644 +--- a/Zend/zend_API.h ++++ b/Zend/zend_API.h +@@ -642,6 +642,21 @@ END_EXTERN_C() + #define RETURN_FALSE  					{ RETVAL_FALSE; return; } + #define RETURN_TRUE   					{ RETVAL_TRUE; return; } +  ++/* Check that returned string length fits int */ ++#define RETVAL_STRINGL_CHECK(s, len, dup) do {	\ ++	size_t __len = (len);					\ ++	if (UNEXPECTED(__len > INT_MAX)) { 		\ ++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "String too long, max is %d", INT_MAX); \ ++		if(!(dup)) { 						\ ++			efree((s));						\ ++		}									\ ++		RETURN_FALSE;						\ ++	}										\ ++	RETVAL_STRINGL((s), __len, (dup)); \ ++} while (0) ++ ++ ++ + #define SET_VAR_STRING(n, v) {																				\ + 								{																			\ + 									zval *var;																\ + + +From 96a8cf8e1b5dc1b0c708bb5574e0d6727cc56d9e Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <stas@php.net> +Date: Tue, 11 Oct 2016 13:30:52 -0700 +Subject: [PATCH] Fix bug #73293 - NULL pointer dereference in + SimpleXMLElement::asXML() + +--- + Zend/zend_API.h           |  2 +- + ext/simplexml/simplexml.c | 33 +++++++++++++++++++++++---------- + 2 files changed, 24 insertions(+), 11 deletions(-) + +diff --git a/Zend/zend_API.h b/Zend/zend_API.h +index c57c003..dadeaf5 100644 +--- a/Zend/zend_API.h ++++ b/Zend/zend_API.h +@@ -652,7 +652,7 @@ END_EXTERN_C() + 		}									\ + 		RETURN_FALSE;						\ + 	}										\ +-	RETVAL_STRINGL((s), __len, (dup)); \ ++	RETVAL_STRINGL((s), (int)__len, (dup)); \ + } while (0) +  +  +diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c +index 07fc654..d7077fc 100644 +--- a/ext/simplexml/simplexml.c ++++ b/ext/simplexml/simplexml.c +@@ -989,7 +989,7 @@ static inline char * sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, in + { + 	xmlChar *tmp = xmlNodeListGetString(doc, list, inLine); + 	char    *res; +-	 ++ + 	if (tmp) { + 		res = estrdup((char*)tmp); + 		xmlFree(tmp); +@@ -1147,7 +1147,7 @@ static HashTable * sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{ + 			} else { + 				if (node->type == XML_TEXT_NODE) { + 					const xmlChar *cur = node->content; +-					 ++ + 					if (*cur != 0) { + 						MAKE_STD_ZVAL(value); + 						ZVAL_STRING(value, sxe_xmlNodeListGetString(node->doc, node, 1), 0); +@@ -1198,7 +1198,7 @@ next_iter: + static HashTable * sxe_get_gc(zval *object, zval ***table, int *n TSRMLS_DC) /* {{{ */ { + 	php_sxe_object  *sxe; + 	sxe = php_sxe_fetch_object(object TSRMLS_CC); +-	 ++ + 	*table = NULL; + 	*n = 0; + 	return sxe->properties; +@@ -1302,7 +1302,7 @@ SXE_METHOD(xpath) + 	result = retval->nodesetval; +  + 	array_init(return_value); +-		 ++ + 	if (result != NULL) { + 		for (i = 0; i < result->nodeNr; ++i) { + 			nodeptr = result->nodeTab[i]; +@@ -1412,9 +1412,15 @@ SXE_METHOD(asXML) + 	if (node) { + 		if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) { + 			xmlDocDumpMemoryEnc((xmlDocPtr) sxe->document->ptr, &strval, &strval_len, ((xmlDocPtr) sxe->document->ptr)->encoding); +-			RETVAL_STRINGL((char *)strval, strval_len, 1); ++			if (!strval) { ++				RETVAL_FALSE; ++			} else { ++				RETVAL_STRINGL((char *)strval, strval_len, 1); ++			} + 			xmlFree(strval); + 		} else { ++			char *return_content; ++			size_t return_len; + 			/* Should we be passing encoding information instead of NULL? */ + 			outbuf = xmlAllocOutputBuffer(NULL); +  +@@ -1425,10 +1431,17 @@ SXE_METHOD(asXML) + 			xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, ((xmlDocPtr) sxe->document->ptr)->encoding); + 			xmlOutputBufferFlush(outbuf); + #ifdef LIBXML2_NEW_BUFFER +-			RETVAL_STRINGL((char *)xmlOutputBufferGetContent(outbuf), xmlOutputBufferGetSize(outbuf), 1); ++			return_content = (char *)xmlOutputBufferGetContent(outbuf); ++			return_len = xmlOutputBufferGetSize(outbuf); + #else +-			RETVAL_STRINGL((char *)outbuf->buffer->content, outbuf->buffer->use, 1); ++			return_content = (char *)outbuf->buffer->content; ++			return_len = outbuf->buffer->use; + #endif ++			if (!return_content) { ++				RETVAL_FALSE; ++			} else { ++				RETVAL_STRINGL_CHECK(return_content, return_len, 1); ++			} + 			xmlOutputBufferClose(outbuf); + 		} + 	} else { +@@ -1542,11 +1555,11 @@ SXE_METHOD(getDocNamespaces) + 	}else{ + 		GET_NODE(sxe, node); + 	} +-	 ++ + 	if (node == NULL) { + 		RETURN_FALSE; + 	} +-	 ++ + 	array_init(return_value); + 	sxe_add_registered_namespaces(sxe, node, recursive, return_value TSRMLS_CC); + } +@@ -1933,7 +1946,7 @@ SXE_METHOD(count) + 	} +  + 	php_sxe_count_elements_helper(sxe, &count TSRMLS_CC); +-	 ++ + 	RETURN_LONG(count); + } + /* }}} */ +--  +2.1.4 + @@ -1,15 +1,17 @@ -==== PHP 5.5.38-3 (2016-09-19) +==== PHP 5.5.38-4 (2016-10-15)  $ 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    :    4 +/var/lib/mock/el5i/build.log:Tests failed    :    8 +/var/lib/mock/el5x/build.log:Tests failed    :    6  /var/lib/mock/el6i/build.log:Tests failed    :    3  /var/lib/mock/el6x/build.log:Tests failed    :    0  /var/lib/mock/el7x/build.log:Tests failed    :    0  el5i, el5x +	Bug #20382 [2] (strtotime ("Monday", $date) produces wrong result on DST changeover) [ext/date/tests/bug20382-2.phpt]  	Bug #33414 [1] (Comprehensive list of incorrect days returned after strotime() / date() tests) [ext/date/tests/bug33414-1.phpt] +	Bug #33415 [1] (Possibly invalid non-one-hour DST or timezone shifts) [ext/date/tests/bug33415-1.phpt]  	Bug #64802: openssl_x509_parse fails to parse subject properly in some cases [ext/openssl/tests/bug64802.phpt]  	Bug #66501: EC private key support in openssl_sign [ext/openssl/tests/bug66501.phpt]  	openssl_x509_parse() basic test for OpenSSL 0.9 [ext/openssl/tests/openssl_x509_parse_basic_v9.phpt] @@ -141,7 +141,7 @@  Summary: PHP scripting language for creating dynamic web sites  Name: php  Version: 5.5.38 -Release: 3%{?dist} +Release: 4%{?dist}  # All files licensed under PHP version 3.01, except  # Zend is licensed under Zend  # TSRM is licensed under BSD @@ -231,6 +231,22 @@ Patch125: bug73029.patch  Patch126: bug73052.patch  Patch127: bug73035.patch  Patch128: bug73065.patch +Patch129: bug72581.patch +Patch130: bug73189.patch +Patch131: bug73147.patch +Patch132: bug73190.patch +Patch133: bug73150.patch +Patch134: bug73284.patch +Patch135: bug73073.patch +Patch136: bug73218.patch +Patch137: bug73208.patch +Patch138: bug73082.patch +Patch139: bug73174.patch +Patch140: bug73275.patch +Patch141: bug73276.patch +Patch142: bug73293.patch +Patch143: bug73240.patch +Patch144: bug73017.patch  # Security fixes (200+) @@ -978,7 +994,7 @@ rm -rf ext/json  %patch21 -p1 -b .odbctimer  %patch40 -p1 -b .dlopen -%if 0%{?fedora} >= 19 || 0%{?rhel} >= 5 +%if 0%{?fedora} >= 23 || 0%{?rhel} >= 5  %patch42 -p1 -b .systzdata  %endif  %patch43 -p1 -b .headers @@ -1025,6 +1041,22 @@ rm -rf ext/json  %patch126 -p1 -b .bug73052  %patch127 -p1 -b .bug73035  %patch128 -p1 -b .bug73065 +%patch129 -p1 -b .bug73581 +%patch130 -p1 -b .bug73189 +%patch131 -p1 -b .bug73147 +%patch132 -p1 -b .bug73190 +%patch133 -p1 -b .bug73150 +%patch134 -p1 -b .bug73284 +%patch135 -p1 -b .bug73073 +%patch136 -p1 -b .bug73218 +%patch137 -p1 -b .bug73208 +%patch138 -p1 -b .bug73082 +%patch139 -p1 -b .bug73174 +%patch140 -p1 -b .bug73275 +%patch141 -p1 -b .bug73276 +%patch142 -p1 -b .bug73293 +%patch143 -p1 -b .bug73240 +%patch144 -p1 -b .bug73017  # Fixes for tests  %patch300 -p1 -b .datetests @@ -2047,6 +2079,24 @@ EOF  %changelog +* Sat Oct 15 2016 Remi Collet <remi@remirepo.net> 5.5.38-4 +- fix #73189: Memcpy negative size parameter php_resolve_path +- fix #72581: previous property undefined in Exception after deserialization +- fix #73147: Use After Free in unserialize +- fix #73190: memcpy negative parameter _bc_new_num_ex +- fix #73150: missing NULL check in dom_document_save_html +- fix #73284: heap overflow in php_ereg_replace function +- fix #73073: CachingIterator null dereference when convert to string +- fix #73218: add mitigation for ICU int overflow +- fix #73208: integer overflow in imap_8bit caused heap corruption +- fix #73082: string length overflow in mb_encode_* function +- fix #73174: heap overflow in php_pcre_replace_impl +- fix #73275: crash in openssl_encrypt function +- fix #73275: crash in openssl_encrypt function +- fix #73293: NULL pointer dereference in SimpleXMLElement::asXML +- fix #73240: Write out of bounds at number_format +- fix #73017: memory corruption in wordwrap function +  * Mon Sep 19 2016 Remi Collet <remi@remirepo.net> 5.5.38-3  - fix #72910: Out of bounds heap read in mbc_to_code()  - fix #72926: Uninitialized Thumbail Data Leads To Memory Leakage  | 
