summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bug73144.patch58
-rw-r--r--bug73331.patch223
-rw-r--r--bug73356.patch353
-rw-r--r--bug73418.patch26
-rw-r--r--failed.txt9
-rw-r--r--php.spec16
6 files changed, 680 insertions, 5 deletions
diff --git a/bug73144.patch b/bug73144.patch
new file mode 100644
index 0000000..bfe8c3e
--- /dev/null
+++ b/bug73144.patch
@@ -0,0 +1,58 @@
+Backported from 5.6.28 by Remi.
+
+
+From b433034febb099835a61943986522eb246115910 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 23 Oct 2016 21:56:35 -0700
+Subject: [PATCH] Fix bug #73144 and bug #73341 - remove extra dtor
+
+---
+ ext/spl/spl_array.c | 2 +-
+ ext/standard/tests/serialize/bug73341.phpt | 24 ++++++++++++++++++++++++
+ 2 files changed, 25 insertions(+), 1 deletion(-)
+ create mode 100644 ext/standard/tests/serialize/bug73341.phpt
+
+diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
+index 700d609..e7cbd1f 100644
+--- a/ext/spl/spl_array.c
++++ b/ext/spl/spl_array.c
+@@ -1798,7 +1798,7 @@ SPL_METHOD(Array, unserialize)
+ ALLOC_INIT_ZVAL(intern->array);
+ if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)
+ || (Z_TYPE_P(intern->array) != IS_ARRAY && Z_TYPE_P(intern->array) != IS_OBJECT)) {
+- zval_ptr_dtor(&intern->array);
++ // zval_ptr_dtor(&intern->array);
+ goto outexcept;
+ }
+ var_push_dtor(&var_hash, &intern->array);
+diff --git a/ext/standard/tests/serialize/bug73341.phpt b/ext/standard/tests/serialize/bug73341.phpt
+new file mode 100644
+index 0000000..5542321
+--- /dev/null
++++ b/ext/standard/tests/serialize/bug73341.phpt
+@@ -0,0 +1,24 @@
++--TEST--
++Bug #73144 (Use-afte-free in ArrayObject Deserialization)
++--FILE--
++<?php
++try {
++$token = 'a:2:{i:0;O:1:"0":2:0s:1:"0";i:0;s:1:"0";a:1:{i:0;C:11:"ArrayObject":7:0x:i:0;r0';
++$obj = unserialize($token);
++} catch(Exception $e) {
++ echo $e->getMessage()."\n";
++}
++
++try {
++$inner = 'x:i:1;O:8:"stdClass":1:{};m:a:0:{}';
++$exploit = 'C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}';
++unserialize($exploit);
++} catch(Exception $e) {
++ echo $e->getMessage()."\n";
++}
++?>
++--EXPECTF--
++Error at offset 6 of 7 bytes
++
++Notice: ArrayObject::unserialize(): Unexpected end of serialized data in %sbug73341.php on line %d
++Error at offset 24 of 34 bytes
+\ No newline at end of file
diff --git a/bug73331.patch b/bug73331.patch
new file mode 100644
index 0000000..e49be37
--- /dev/null
+++ b/bug73331.patch
@@ -0,0 +1,223 @@
+Backported from 5.6.28 by Remi.
+
+
+From 0cd5cdeb04946f4fa2f6613220deb6c82ea71ff7 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 23 Oct 2016 20:07:47 -0700
+Subject: [PATCH] Fix bug #73331 - do not try to serialize/unserialize objects
+ wddx can not handle
+
+Proper soltion would be to call serialize/unserialize and deal with the result,
+but this requires more work that should be done by wddx maintainer (not me).
+---
+ ext/pdo/pdo_stmt.c | 1 +
+ ext/wddx/tests/bug45901.phpt | 4 ++-
+ ext/wddx/tests/bug72790.phpt | 2 +-
+ ext/wddx/tests/bug73331.phpt | 15 ++++++++++
+ ext/wddx/wddx.c | 67 +++++++++++++++++++++++---------------------
+ 5 files changed, 55 insertions(+), 34 deletions(-)
+ create mode 100644 ext/wddx/tests/bug73331.phpt
+
+diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
+index f5c295c..9f9ada9 100644
+--- a/ext/pdo/pdo_stmt.c
++++ b/ext/pdo/pdo_stmt.c
+@@ -2355,6 +2355,7 @@ void pdo_stmt_init(TSRMLS_D)
+ pdo_row_ce->ce_flags |= ZEND_ACC_FINAL_CLASS; /* when removing this a lot of handlers need to be redone */
+ pdo_row_ce->create_object = pdo_row_new;
+ pdo_row_ce->serialize = pdo_row_serialize;
++ pdo_row_ce->unserialize = zend_class_unserialize_deny;
+ }
+
+ static void free_statement(pdo_stmt_t *stmt TSRMLS_DC)
+diff --git a/ext/wddx/tests/bug45901.phpt b/ext/wddx/tests/bug45901.phpt
+index 4084ccb..e76e47e 100644
+--- a/ext/wddx/tests/bug45901.phpt
++++ b/ext/wddx/tests/bug45901.phpt
+@@ -14,5 +14,7 @@ echo wddx_serialize_value($xml, 'Variables') . "\n";
+ echo "DONE";
+ ?>
+ --EXPECTF--
+-<wddxPacket version='1.0'><header><comment>Variables</comment></header><data><struct><var name='php_class_name'><string>SimpleXMLElement</string></var><var name='test'><struct><var name='php_class_name'><string>SimpleXMLElement</string></var></struct></var></struct></data></wddxPacket>
++
++Warning: wddx_serialize_value(): Class SimpleXMLElement can not be serialized in %sbug45901.php on line %d
++<wddxPacket version='1.0'><header><comment>Variables</comment></header><data></data></wddxPacket>
+ DONE
+\ No newline at end of file
+diff --git a/ext/wddx/tests/bug72790.phpt b/ext/wddx/tests/bug72790.phpt
+index a60524b..3b08e58 100644
+--- a/ext/wddx/tests/bug72790.phpt
++++ b/ext/wddx/tests/bug72790.phpt
+@@ -1,5 +1,5 @@
+ --TEST--
+-Bug 72790: wddx_deserialize null dereference with invalid xml
++Bug #72790: wddx_deserialize null dereference with invalid xml
+ --SKIPIF--
+ <?php
+ if (!extension_loaded('wddx')) {
+diff --git a/ext/wddx/tests/bug73331.phpt b/ext/wddx/tests/bug73331.phpt
+new file mode 100644
+index 0000000..7e4cda1
+--- /dev/null
++++ b/ext/wddx/tests/bug73331.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++Bug #73331 (NULL Pointer Dereference in WDDX Packet Deserialization with PDORow)
++--SKIPIF--
++<?php if (!extension_loaded("wddx") || !extension_loaded("pdo")) print "skip"; ?>
++--FILE--
++<?php
++
++$wddx = "<wddxPacket version='1.0'><header/><data><struct><var name='php_class_name'><string>PDORow</string></var></struct></data></wddxPacket>";
++var_dump(wddx_deserialize($wddx));
++?>
++--EXPECTF--
++
++Warning: wddx_deserialize(): Class pdorow can not be unserialized in %s73331.php on line %d
++NULL
++
+diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
+index 0e77826..59cc8dd 100644
+--- a/ext/wddx/wddx.c
++++ b/ext/wddx/wddx.c
+@@ -465,21 +465,26 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
+ ulong idx;
+ char tmp_buf[WDDX_BUF_LEN];
+ HashTable *objhash, *sleephash;
++ zend_class_entry *ce;
++ PHP_CLASS_ATTRIBUTES;
+ TSRMLS_FETCH();
+
++ PHP_SET_CLASS_ATTRIBUTES(obj);
++ ce = Z_OBJCE_P(obj);
++ if (!ce || ce->serialize || ce->unserialize) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s can not be serialized", class_name);
++ PHP_CLEANUP_CLASS_ATTRIBUTES();
++ return;
++ }
++
+ MAKE_STD_ZVAL(fname);
+ ZVAL_STRING(fname, "__sleep", 1);
+-
+ /*
+ * We try to call __sleep() method on object. It's supposed to return an
+ * array of property names to be serialized.
+ */
+ if (call_user_function_ex(CG(function_table), &obj, fname, &retval, 0, 0, 1, NULL TSRMLS_CC) == SUCCESS) {
+ if (retval && (sleephash = HASH_OF(retval))) {
+- PHP_CLASS_ATTRIBUTES;
+-
+- PHP_SET_CLASS_ATTRIBUTES(obj);
+-
+ php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
+ snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
+ php_wddx_add_chunk(packet, tmp_buf);
+@@ -488,8 +493,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
+ php_wddx_add_chunk_static(packet, WDDX_STRING_E);
+ php_wddx_add_chunk_static(packet, WDDX_VAR_E);
+
+- PHP_CLEANUP_CLASS_ATTRIBUTES();
+-
+ objhash = HASH_OF(obj);
+
+ for (zend_hash_internal_pointer_reset(sleephash);
+@@ -510,10 +513,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
+ } else {
+ uint key_len;
+
+- PHP_CLASS_ATTRIBUTES;
+-
+- PHP_SET_CLASS_ATTRIBUTES(obj);
+-
+ php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
+ snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
+ php_wddx_add_chunk(packet, tmp_buf);
+@@ -522,8 +521,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
+ php_wddx_add_chunk_static(packet, WDDX_STRING_E);
+ php_wddx_add_chunk_static(packet, WDDX_VAR_E);
+
+- PHP_CLEANUP_CLASS_ATTRIBUTES();
+-
+ objhash = HASH_OF(obj);
+ for (zend_hash_internal_pointer_reset(objhash);
+ zend_hash_get_current_data(objhash, (void**)&ent) == SUCCESS;
+@@ -545,6 +542,8 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
+ php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
+ }
+
++ PHP_CLEANUP_CLASS_ATTRIBUTES();
++
+ zval_dtor(fname);
+ FREE_ZVAL(fname);
+
+@@ -1005,26 +1004,30 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
+ pce = &PHP_IC_ENTRY;
+ }
+
+- /* Initialize target object */
+- MAKE_STD_ZVAL(obj);
+- object_init_ex(obj, *pce);
+-
+- /* Merge current hashtable with object's default properties */
+- zend_hash_merge(Z_OBJPROP_P(obj),
+- Z_ARRVAL_P(ent2->data),
+- (void (*)(void *)) zval_add_ref,
+- (void *) &tmp, sizeof(zval *), 0);
+-
+- if (incomplete_class) {
+- php_store_class_name(obj, Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data));
++ if (pce != &PHP_IC_ENTRY && ((*pce)->serialize || (*pce)->unserialize)) {
++ ent2->data = NULL;
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s can not be unserialized", Z_STRVAL_P(ent1->data));
++ } else {
++ /* Initialize target object */
++ MAKE_STD_ZVAL(obj);
++ object_init_ex(obj, *pce);
++
++ /* Merge current hashtable with object's default properties */
++ zend_hash_merge(Z_OBJPROP_P(obj),
++ Z_ARRVAL_P(ent2->data),
++ (void (*)(void *)) zval_add_ref,
++ (void *) &tmp, sizeof(zval *), 0);
++
++ if (incomplete_class) {
++ php_store_class_name(obj, Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data));
++ }
++
++ /* Clean up old array entry */
++ zval_ptr_dtor(&ent2->data);
++
++ /* Set stack entry to point to the newly created object */
++ ent2->data = obj;
+ }
+-
+- /* Clean up old array entry */
+- zval_ptr_dtor(&ent2->data);
+-
+- /* Set stack entry to point to the newly created object */
+- ent2->data = obj;
+-
+ /* Clean up class name var entry */
+ zval_ptr_dtor(&ent1->data);
+ } else if (Z_TYPE_P(ent2->data) == IS_OBJECT) {
+From 87bb51eb9fcf95dd4c71eb1fbb00d00a243f4276 Mon Sep 17 00:00:00 2001
+From: Anatol Belski <ab@php.net>
+Date: Tue, 8 Nov 2016 12:12:58 +0100
+Subject: [PATCH] fix memory leak
+
+---
+ ext/wddx/wddx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
+index 59cc8dd..069ea12 100644
+--- a/ext/wddx/wddx.c
++++ b/ext/wddx/wddx.c
+@@ -1005,6 +1005,7 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
+ }
+
+ if (pce != &PHP_IC_ENTRY && ((*pce)->serialize || (*pce)->unserialize)) {
++ zval_ptr_dtor(&ent2->data);
+ ent2->data = NULL;
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s can not be unserialized", Z_STRVAL_P(ent1->data));
+ } else {
diff --git a/bug73356.patch b/bug73356.patch
new file mode 100644
index 0000000..5bf0b64
--- /dev/null
+++ b/bug73356.patch
@@ -0,0 +1,353 @@
+Backported from 5.6.28 by Remi.
+
+
+From 18fef10644d865f9d25e49ed501f4f739efe44fc Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Thu, 3 Nov 2016 20:36:52 -0700
+Subject: [PATCH] More string length checks & fixes
+
+---
+ ext/bz2/bz2.c | 2 +-
+ ext/iconv/iconv.c | 2 +-
+ ext/imap/php_imap.c | 2 +-
+ ext/intl/breakiterator/breakiterator_iterators.cpp | 2 +-
+ ext/intl/intl_convert.c | 2 +-
+ ext/intl/locale/locale_methods.c | 9 ++++++++-
+ ext/intl/msgformat/msgformat_data.c | 4 ++--
+ ext/standard/exec.c | 10 +++++-----
+ ext/standard/php_smart_str.h | 3 ++-
+ ext/xmlrpc/libxmlrpc/base64.c | 22 +++++++++++++---------
+ ext/xmlrpc/libxmlrpc/simplestring.c | 3 ++-
+ ext/zip/php_zip.c | 6 +++---
+ ext/zlib/zlib.c | 2 +-
+ 13 files changed, 41 insertions(+), 28 deletions(-)
+
+diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
+index 79ec3ec..2e39f4a 100644
+--- a/ext/bz2/bz2.c
++++ b/ext/bz2/bz2.c
+@@ -512,7 +512,7 @@ static PHP_FUNCTION(bzcompress)
+ dest_len = (unsigned int) (source_len + (0.01 * source_len) + 600);
+
+ /* Allocate the destination buffer */
+- dest = emalloc(dest_len + 1);
++ dest = safe_emalloc(dest_len, 1, 1);
+
+ /* Handle the optional arguments */
+ if (argc > 1) {
+diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c
+index fc45f41..69dd8c1 100644
+--- a/ext/iconv/iconv.c
++++ b/ext/iconv/iconv.c
+@@ -2426,7 +2426,7 @@ PHP_NAMED_FUNCTION(php_if_iconv)
+ &out_buffer, &out_len, out_charset, in_charset);
+ _php_iconv_show_error(err, out_charset, in_charset TSRMLS_CC);
+ if (err == PHP_ICONV_ERR_SUCCESS && out_buffer != NULL) {
+- RETVAL_STRINGL(out_buffer, out_len, 0);
++ RETVAL_STRINGL_CHECK(out_buffer, out_len, 0);
+ } else {
+ if (out_buffer != NULL) {
+ efree(out_buffer);
+diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c
+index 6c392fb..00eae89 100644
+--- a/ext/imap/php_imap.c
++++ b/ext/imap/php_imap.c
+@@ -3910,7 +3910,7 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *
+ #define PHP_IMAP_CLEAN if (bufferTo) efree(bufferTo); if (bufferCc) efree(bufferCc); if (bufferBcc) efree(bufferBcc); if (bufferHeader) efree(bufferHeader);
+ #define PHP_IMAP_BAD_DEST PHP_IMAP_CLEAN; efree(tempMailTo); return (BAD_MSG_DESTINATION);
+
+- bufferHeader = (char *)emalloc(bufferLen + 1);
++ bufferHeader = (char *)safe_emalloc(bufferLen, 1, 1);
+ memset(bufferHeader, 0, bufferLen);
+ if (to && *to) {
+ strlcat(bufferHeader, "To: ", bufferLen + 1);
+diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp
+index 3748991..7065ec6 100644
+--- a/ext/intl/breakiterator/breakiterator_iterators.cpp
++++ b/ext/intl/breakiterator/breakiterator_iterators.cpp
+@@ -182,7 +182,7 @@ static void _breakiterator_parts_move_forward(zend_object_iterator *iter TSRMLS_
+ }
+ assert(next <= slen && next >= cur);
+ len = next - cur;
+- res = static_cast<char*>(emalloc(len + 1));
++ res = static_cast<char*>(safe_emalloc(len, 1, 1));
+
+ memcpy(res, &s[cur], len);
+ res[len] = '\0';
+diff --git a/ext/intl/intl_convert.c b/ext/intl/intl_convert.c
+index 92cdc4c..2dde6ad 100644
+--- a/ext/intl/intl_convert.c
++++ b/ext/intl/intl_convert.c
+@@ -49,7 +49,7 @@ void intl_convert_utf8_to_utf16(
+ UErrorCode* status )
+ {
+ UChar* dst_buf = NULL;
+- int32_t dst_len = 0;
++ uint32_t dst_len = 0;
+
+ /* If *target is NULL determine required destination buffer size (pre-flighting).
+ * Otherwise, attempt to convert source string; if *target buffer is not large enough
+diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c
+index 862b9f5..39d80d5 100644
+--- a/ext/intl/locale/locale_methods.c
++++ b/ext/intl/locale/locale_methods.c
+@@ -263,6 +263,9 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int*
+ int32_t buflen = 512;
+ UErrorCode status = U_ZERO_ERROR;
+
++ if (strlen(loc_name) > INTL_MAX_LOCALE_LEN) {
++ return NULL;
++ }
+
+ if( strcmp(tag_name, LOC_CANONICALIZE_TAG) != 0 ){
+ /* Handle grandfathered languages */
+@@ -395,7 +398,7 @@ 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 */
+@@ -702,6 +705,8 @@ PHP_FUNCTION( locale_get_keywords )
+ RETURN_FALSE;
+ }
+
++ INTL_CHECK_LOCALE_LEN(strlen(loc_name));
++
+ if(loc_name_len == 0) {
+ loc_name = intl_locale_get_default(TSRMLS_C);
+ }
+@@ -1109,6 +1114,8 @@ PHP_FUNCTION(locale_parse)
+ RETURN_FALSE;
+ }
+
++ INTL_CHECK_LOCALE_LEN(strlen(loc_name));
++
+ if(loc_name_len == 0) {
+ loc_name = intl_locale_get_default(TSRMLS_C);
+ }
+diff --git a/ext/intl/msgformat/msgformat_data.c b/ext/intl/msgformat/msgformat_data.c
+index 5d49054..9e967da 100644
+--- a/ext/intl/msgformat/msgformat_data.c
++++ b/ext/intl/msgformat/msgformat_data.c
+@@ -80,10 +80,10 @@ msgformat_data* msgformat_data_create( TSRMLS_D )
+ /* }}} */
+
+ #ifdef MSG_FORMAT_QUOTE_APOS
+-int msgformat_fix_quotes(UChar **spattern, uint32_t *spattern_len, UErrorCode *ec)
++int msgformat_fix_quotes(UChar **spattern, uint32_t *spattern_len, UErrorCode *ec)
+ {
+ if(*spattern && *spattern_len && u_strchr(*spattern, (UChar)'\'')) {
+- UChar *npattern = emalloc(sizeof(UChar)*(2*(*spattern_len)+1));
++ UChar *npattern = safe_emalloc(sizeof(UChar)*2, *spattern_len, sizeof(UChar));
+ uint32_t npattern_len;
+ npattern_len = umsg_autoQuoteApostrophe(*spattern, *spattern_len, npattern, 2*(*spattern_len)+1, ec);
+ efree(*spattern);
+diff --git a/ext/standard/exec.c b/ext/standard/exec.c
+index e0ca914..88a6b4a 100644
+--- a/ext/standard/exec.c
++++ b/ext/standard/exec.c
+@@ -133,7 +133,7 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_
+
+ if (type != 3) {
+ b = buf;
+-
++
+ while (php_stream_get_line(stream, b, EXEC_INPUT_BUF, &bufl)) {
+ /* no new line found, let's read some more */
+ if (b[bufl - 1] != '\n' && !php_stream_eof(stream)) {
+@@ -330,7 +330,7 @@ PHPAPI char *php_escape_shell_cmd(char *str)
+ cmd[y++] = str[x];
+ break;
+ #else
+- /* % is Windows specific for enviromental variables, ^%PATH% will
++ /* % is Windows specific for enviromental variables, ^%PATH% will
+ output PATH while ^%PATH^% will not. escapeshellcmd will escape all % and !.
+ */
+ case '%':
+@@ -492,7 +492,7 @@ PHP_FUNCTION(escapeshellcmd)
+ return;
+ }
+ cmd = php_escape_shell_cmd(command);
+- RETVAL_STRING(cmd, 0);
++ RETVAL_STRINGL_CHECK(cmd, strlen(cmd), 0);
+ } else {
+ RETVAL_EMPTY_STRING();
+ }
+@@ -517,7 +517,7 @@ PHP_FUNCTION(escapeshellarg)
+ return;
+ }
+ cmd = php_escape_shell_arg(argument);
+- RETVAL_STRING(cmd, 0);
++ RETVAL_STRINGL_CHECK(cmd, strlen(cmd), 0);
+ }
+ }
+ /* }}} */
+@@ -551,7 +551,7 @@ PHP_FUNCTION(shell_exec)
+ php_stream_close(stream);
+
+ if (total_readbytes > 0) {
+- RETVAL_STRINGL(ret, total_readbytes, 0);
++ RETVAL_STRINGL_CHECK(ret, total_readbytes, 0);
+ }
+ }
+ /* }}} */
+diff --git a/ext/standard/php_smart_str.h b/ext/standard/php_smart_str.h
+index edd9d3a..6baa49f 100644
+--- a/ext/standard/php_smart_str.h
++++ b/ext/standard/php_smart_str.h
+@@ -57,7 +57,8 @@
+ newlen = (n); \
+ (d)->a = newlen < SMART_STR_START_SIZE \
+ ? SMART_STR_START_SIZE \
+- : newlen + SMART_STR_PREALLOC; \
++ : (newlen >= (INT_MAX - SMART_STR_PREALLOC)? newlen \
++ : (newlen + SMART_STR_PREALLOC)); \
+ SMART_STR_DO_REALLOC(d, what); \
+ } else { \
+ newlen = (d)->len + (n); \
+diff --git a/ext/xmlrpc/libxmlrpc/base64.c b/ext/xmlrpc/libxmlrpc/base64.c
+index d020bd6..5ebdf31 100644
+--- a/ext/xmlrpc/libxmlrpc/base64.c
++++ b/ext/xmlrpc/libxmlrpc/base64.c
+@@ -15,6 +15,7 @@ static const char rcsid[] = "#(@) $Id$";
+ /* ENCODE -- Encode binary file into base64. */
+ #include <stdlib.h>
+ #include <ctype.h>
++#include <limits.h>
+
+ #include "base64.h"
+
+@@ -31,6 +32,9 @@ void buffer_new(struct buffer_st *b)
+
+ void buffer_add(struct buffer_st *b, char c)
+ {
++ if ((INT_MAX - b->length) <= 512) {
++ return;
++ }
+ *(b->ptr++) = c;
+ b->offset++;
+ if (b->offset == b->length) {
+@@ -54,13 +58,13 @@ void base64_encode_xmlrpc(struct buffer_st *b, const char *source, int length)
+ int i, hiteof = 0;
+ int offset = 0;
+ int olen;
+-
++
+ olen = 0;
+-
++
+ buffer_new(b);
+-
++
+ /* Fill dtable with character encodings. */
+-
++
+ for (i = 0; i < 26; i++) {
+ dtable[i] = 'A' + i;
+ dtable[26 + i] = 'a' + i;
+@@ -70,16 +74,16 @@ void base64_encode_xmlrpc(struct buffer_st *b, const char *source, int length)
+ }
+ dtable[62] = '+';
+ dtable[63] = '/';
+-
++
+ while (!hiteof) {
+ unsigned char igroup[3], ogroup[4];
+ int c, n;
+-
++
+ igroup[0] = igroup[1] = igroup[2] = 0;
+ for (n = 0; n < 3; n++) {
+ c = *(source++);
+ offset++;
+- if (offset > length) {
++ if (offset > length || offset <= 0) {
+ hiteof = 1;
+ break;
+ }
+@@ -90,11 +94,11 @@ void base64_encode_xmlrpc(struct buffer_st *b, const char *source, int length)
+ ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
+ ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
+ ogroup[3] = dtable[igroup[2] & 0x3F];
+-
++
+ /* Replace characters in output stream with "=" pad
+ characters if fewer than three characters were
+ read from the end of the input stream. */
+-
++
+ if (n < 3) {
+ ogroup[3] = '=';
+ if (n < 2) {
+diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c
+index c88754f..98b5c81 100644
+--- a/ext/xmlrpc/libxmlrpc/simplestring.c
++++ b/ext/xmlrpc/libxmlrpc/simplestring.c
+@@ -80,6 +80,7 @@ static const char rcsid[] = "#(@) $Id$";
+
+ #include <stdlib.h>
+ #include <string.h>
++#include <limits.h>
+ #include "simplestring.h"
+
+ #define my_free(thing) if(thing) {free(thing); thing = 0;}
+@@ -200,7 +201,7 @@ void simplestring_addn(simplestring* target, const char* source, size_t add_len)
+ simplestring_init_str(target);
+ }
+
+- if((SIZE_MAX - add_len) < target->len || (SIZE_MAX - add_len - 1) < target->len) {
++ if((INT_MAX - add_len) < target->len || (INT_MAX - add_len - 1) < target->len) {
+ /* check for overflows, if there's a potential overflow do nothing */
+ return;
+ }
+
+From f14da6f0b01e329c3809de93c1b928ad4b4fa6fa Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Thu, 3 Nov 2016 22:10:22 -0700
+Subject: [PATCH] Add length check for bzcompress too - fix for bug #73356
+
+---
+ ext/bz2/bz2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
+index 2e39f4a..13b9f38 100644
+--- a/ext/bz2/bz2.c
++++ b/ext/bz2/bz2.c
+@@ -532,7 +532,7 @@ static PHP_FUNCTION(bzcompress)
+ so we erealloc() the buffer to the proper size */
+ dest = erealloc(dest, dest_len + 1);
+ dest[dest_len] = 0;
+- RETURN_STRINGL(dest, dest_len, 0);
++ RETURN_STRINGL_CHECK(dest, dest_len, 0);
+ }
+ }
+ /* }}} */
+From e43b3bff6a6f5358712ff18961ffa650224dcdcb Mon Sep 17 00:00:00 2001
+From: Anatol Belski <ab@php.net>
+Date: Sun, 6 Nov 2016 17:51:25 +0100
+Subject: [PATCH] add missing RETURN_STRINGL_CHECK
+
+As RETVAL_STRINGL_CHECK is already there, this one is needed for
+completion. One place in ext/bz2 is missing that, so it will likely
+be useful for other possible fixes.
+---
+ Zend/zend_API.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Zend/zend_API.h b/Zend/zend_API.h
+index dadeaf5..41aa65f 100644
+--- a/Zend/zend_API.h
++++ b/Zend/zend_API.h
+@@ -654,7 +654,7 @@
+ } \
+ RETVAL_STRINGL((s), (int)__len, (dup)); \
+ } while (0)
+-
++#define RETURN_STRINGL_CHECK(s, len, dup) { RETVAL_STRINGL_CHECK(s, len, dup); return; }
+
+
+ #define SET_VAR_STRING(n, v) { \
diff --git a/bug73418.patch b/bug73418.patch
new file mode 100644
index 0000000..d85e4a6
--- /dev/null
+++ b/bug73418.patch
@@ -0,0 +1,26 @@
+Backported from 5.6.28 by Remi.
+
+
+From b823b14e374251ad6ab437a9631e4b010ca09b68 Mon Sep 17 00:00:00 2001
+From: Anatol Belski <ab@php.net>
+Date: Thu, 3 Nov 2016 17:03:23 +0100
+Subject: [PATCH] Fixed bug #73418 Integer Overflow in "_php_imap_mail" leads
+ to crash
+
+---
+ 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 564473b..6c392fb 100644
+--- a/ext/imap/php_imap.c
++++ b/ext/imap/php_imap.c
+@@ -3894,7 +3898,7 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *
+ char *tsm_errmsg = NULL;
+ ADDRESS *addr;
+ char *bufferTo = NULL, *bufferCc = NULL, *bufferBcc = NULL, *bufferHeader = NULL;
+- int offset, bufferLen = 0;
++ size_t offset, bufferLen = 0;
+ size_t bt_len;
+
+ if (headers) {
diff --git a/failed.txt b/failed.txt
index 9124897..ceb438e 100644
--- a/failed.txt
+++ b/failed.txt
@@ -1,9 +1,9 @@
-==== PHP 5.5.38-4 (2016-10-15)
+==== PHP 5.5.38-5 (2016-11-09)
$ grep -r 'Tests failed' /var/lib/mock/scl55*/build.log
-/var/lib/mock/scl55el6x/build.log: Tests failed : 0
-/var/lib/mock/scl55el7x/build.log: Tests failed : 0
+/var/lib/mock/scl55el6x/build.log: Tests failed : 3
+/var/lib/mock/scl55el7x/build.log: Tests failed : 3
/var/lib/mock/scl55fc22x/build.log:Tests failed : 0
/var/lib/mock/scl55fc23x/build.log:Tests failed : 2
/var/lib/mock/scl55fc24x/build.log:Tests failed : 4
@@ -11,8 +11,9 @@ $ grep -r 'Tests failed' /var/lib/mock/scl55*/build.log
fc23x, fc24x, fc25x:
Bug #64802: openssl_x509_parse fails to parse subject properly in some cases [ext/openssl/tests/bug64802.phpt]
+el6x, el7x, fc23x
Bug #33414 [1] (Comprehensive list of incorrect days returned after strotime() / date() tests) [ext/date/tests/bug33414-1.phpt]
-fc24x, fc25x
+el6x, el7x, fc24x, fc25x
Bug #20382 [2] (strtotime ("Monday", $date) produces wrong result on DST changeover) [ext/date/tests/bug20382-2.phpt]
Bug #33415 [1] (Possibly invalid non-one-hour DST or timezone shifts) [ext/date/tests/bug33415-1.phpt]
diff --git a/php.spec b/php.spec
index 59da3e1..e778cd4 100644
--- a/php.spec
+++ b/php.spec
@@ -140,7 +140,7 @@
Summary: PHP scripting language for creating dynamic web sites
Name: %{?scl_prefix}php
Version: 5.5.38
-Release: 4%{?dist}
+Release: 5%{?dist}
# All files licensed under PHP version 3.01, except
# Zend is licensed under Zend
# TSRM is licensed under BSD
@@ -237,6 +237,10 @@ Patch141: bug73276.patch
Patch142: bug73293.patch
Patch143: bug73240.patch
Patch144: bug73017.patch
+Patch145: bug73331.patch
+Patch146: bug73144.patch
+Patch147: bug73418.patch
+Patch148: bug73356.patch
# Security fixes (200+)
@@ -974,6 +978,10 @@ support for using the enchant library to PHP.
%patch142 -p1 -b .bug73293
%patch143 -p1 -b .bug73240
%patch144 -p1 -b .bug73017
+%patch145 -p1 -b .bug73331
+%patch146 -p1 -b .bug73144
+%patch147 -p1 -b .bug73418
+%patch148 -p1 -b .bug73356
: ------------------------
# Fixes for tests
@@ -1879,6 +1887,12 @@ EOF
%changelog
+* Wed Nov 9 2016 Remi Collet <remi@remirepo.net> 5.5.38-5
+- fix #73418: Integer Overflow in "_php_imap_mail" leads Heap Overflow
+- fix #73144: Use-after-free in ArrayObject Deserialization
+- fix #73356: crash in bzcompress function
+- fix #73331: NULL Pointer Deref. in WDDX Packet Deserialization with PDORow
+
* 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