diff options
author | Remi Collet <fedora@famillecollet.com> | 2016-11-09 18:12:33 +0100 |
---|---|---|
committer | Remi Collet <fedora@famillecollet.com> | 2016-11-09 18:12:33 +0100 |
commit | aae3fef56b0850352e715a7e860a69b33c34fe5d (patch) | |
tree | e89593443458d051c45b5449bb5fb39ae7df0451 | |
parent | 4b420dae109ee4ca511cbbba0c209ea5c30513b1 (diff) |
PHP 5.5.38 with minor security fix from 5.6.28
-rw-r--r-- | bug73144.patch | 58 | ||||
-rw-r--r-- | bug73331.patch | 223 | ||||
-rw-r--r-- | bug73356.patch | 353 | ||||
-rw-r--r-- | bug73418.patch | 26 | ||||
-rw-r--r-- | failed.txt | 15 | ||||
-rw-r--r-- | php55.spec | 16 |
6 files changed, 683 insertions, 8 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) { @@ -1,17 +1,14 @@ -==== PHP 5.5.38-4 (2016-10-15) +==== PHP 5.5.38-5 (2016-11-09) $ grep -r 'Tests failed' /var/lib/mock/*/build.log /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 +/var/lib/mock/el6i/build.log:Tests failed : 6 +/var/lib/mock/el6x/build.log:Tests failed : 3 +/var/lib/mock/el7x/build.log:Tests failed : 3 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] @@ -20,4 +17,8 @@ el6i el5i, el6i Bug #53437 DateInterval unserialize bad data, 32 bit [ext/date/tests/bug53437_var3.phpt] Bug #64146 (serialize incorrectly saving objects when they are cloned) [ext/standard/tests/serialize/bug64146.phpt] +el5i, el5x, el6i, el6x, el7x + 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] @@ -141,7 +141,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: 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 @@ -247,6 +247,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+) @@ -1057,6 +1061,10 @@ rm -rf ext/json %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 %patch300 -p1 -b .datetests @@ -2079,6 +2087,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 |