From 925b0dd1fef2d4ea806fa270921c59fbbd75b1c6 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 15 2016 20:37:35 +0000 Subject: import rh-php56-php-5.6.5-8.el7 --- diff --git a/SOURCES/php-5.6.5-CVE-2015-5589.patch b/SOURCES/php-5.6.5-CVE-2015-5589.patch new file mode 100644 index 0000000..3a74c19 --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-5589.patch @@ -0,0 +1,95 @@ +Patch cleanup for 5.6.5 +Binary diff removed + +From bf58162ddf970f63502837f366930e44d6a992cf Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 4 Jul 2015 21:01:50 -0700 +Subject: [PATCH] Fix bug #69958 - Segfault in Phar::convertToData on invalid + file + +--- + ext/phar/phar_object.c | 70 ++++++++++++++++++++++--------------------- + ext/phar/tests/bug69958.phpt | 14 +++++++++ + ext/phar/tests/bug69958.tar | Bin 0 -> 513 bytes + 3 files changed, 50 insertions(+), 34 deletions(-) + create mode 100644 ext/phar/tests/bug69958.phpt + create mode 100644 ext/phar/tests/bug69958.tar + +diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c +index add1fa0..1184863 100644 +--- a/ext/phar/phar_object.c ++++ b/ext/phar/phar_object.c +@@ -2341,7 +2341,9 @@ static zval *phar_convert_to_other(phar_archive_data *source, int convert, char + zend_hash_destroy(&(phar->manifest)); + zend_hash_destroy(&(phar->mounted_dirs)); + zend_hash_destroy(&(phar->virtual_dirs)); +- php_stream_close(phar->fp); ++ if (phar->fp) { ++ php_stream_close(phar->fp); ++ } + efree(phar->fname); + efree(phar); + return NULL; + +From 885edfef0a0eb1016a906d197399f92375a795e4 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 6 Jul 2015 22:58:28 -0700 +Subject: [PATCH] Better fix for bug #69958 + +--- + ext/phar/phar_object.c | 22 +++++++++++++--------- + ext/phar/tests/bug69958.phpt | 2 ++ + 2 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c +index 1184863..8cfe0c8 100644 +--- a/ext/phar/phar_object.c ++++ b/ext/phar/phar_object.c +@@ -2019,9 +2019,10 @@ static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp TSRMLS + } + /* }}} */ + +-static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC) /* {{{ */ ++static zval *phar_rename_archive(phar_archive_data **sphar, char *ext, zend_bool compress TSRMLS_DC) /* {{{ */ + { + const char *oldname = NULL; ++ phar_archive_data *phar = *sphar; + char *oldpath = NULL; + char *basename = NULL, *basepath = NULL; + char *newname = NULL, *newpath = NULL; +@@ -2129,6 +2130,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c + phar->fp = NULL; + phar_destroy_phar_data(phar TSRMLS_CC); + phar = *pphar; ++ *sphar = NULL; + phar->refcount++; + newpath = oldpath; + goto its_ok; +@@ -2335,17 +2337,19 @@ static zval *phar_convert_to_other(phar_archive_data *source, int convert, char + phar_add_virtual_dirs(phar, newentry.filename, newentry.filename_len TSRMLS_CC); + } + +- if ((ret = phar_rename_archive(phar, ext, 0 TSRMLS_CC))) { ++ if ((ret = phar_rename_archive(&phar, ext, 0 TSRMLS_CC))) { + return ret; + } else { +- zend_hash_destroy(&(phar->manifest)); +- zend_hash_destroy(&(phar->mounted_dirs)); +- zend_hash_destroy(&(phar->virtual_dirs)); +- if (phar->fp) { +- php_stream_close(phar->fp); ++ if(phar != NULL) { ++ zend_hash_destroy(&(phar->manifest)); ++ zend_hash_destroy(&(phar->mounted_dirs)); ++ zend_hash_destroy(&(phar->virtual_dirs)); ++ if (phar->fp) { ++ php_stream_close(phar->fp); ++ } ++ efree(phar->fname); ++ efree(phar); + } +- efree(phar->fname); +- efree(phar); + return NULL; + } + } diff --git a/SOURCES/php-5.6.5-CVE-2015-5590.patch b/SOURCES/php-5.6.5-CVE-2015-5590.patch new file mode 100644 index 0000000..7837718 --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-5590.patch @@ -0,0 +1,69 @@ +Patch cleanup for 5.6.5 + +From 6dedeb40db13971af45276f80b5375030aa7e76f Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 4 Jul 2015 23:47:48 -0700 +Subject: [PATCH] Fix bug #69923 - Buffer overflow and stack smashing error in + phar_fix_filepath + +--- + ext/phar/phar.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ext/phar/phar.c b/ext/phar/phar.c +index 223bfe8..ba73462 100644 +--- a/ext/phar/phar.c ++++ b/ext/phar/phar.c +@@ -2118,7 +2118,7 @@ char *tsrm_strtok_r(char *s, const char *delim, char **last) /* {{{ */ + */ + char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ */ + { +- char newpath[MAXPATHLEN]; ++ char *newpath; + int newpath_len; + char *ptr; + char *tok; +@@ -2126,8 +2126,10 @@ char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ + + if (PHAR_G(cwd_len) && use_cwd && path_length > 2 && path[0] == '.' && path[1] == '/') { + newpath_len = PHAR_G(cwd_len); ++ newpath = emalloc(strlen(path) + newpath_len + 1); + memcpy(newpath, PHAR_G(cwd), newpath_len); + } else { ++ newpath = emalloc(strlen(path) + 2); + newpath[0] = '/'; + newpath_len = 1; + } +@@ -2150,6 +2152,7 @@ char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ + if (*tok == '.') { + efree(path); + *new_len = 1; ++ efree(newpath); + return estrndup("/", 1); + } + break; +@@ -2157,9 +2160,11 @@ char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ + if (tok[0] == '.' && tok[1] == '.') { + efree(path); + *new_len = 1; ++ efree(newpath); + return estrndup("/", 1); + } + } ++ efree(newpath); + return path; + } + +@@ -2208,7 +2213,8 @@ last_time: + + efree(path); + *new_len = newpath_len; +- return estrndup(newpath, newpath_len); ++ newpath[newpath_len] = '\0'; ++ return erealloc(newpath, newpath_len + 1); + } + /* }}} */ + +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-6831.patch b/SOURCES/php-5.6.5-CVE-2015-6831.patch new file mode 100644 index 0000000..a2df6bd --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6831.patch @@ -0,0 +1,201 @@ +From 7381b6accc5559b2de039af3a22f6ec1003b03b3 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 1 Aug 2015 21:45:19 -0700 +Subject: [PATCH] Fixed bug #70166 - Use After Free Vulnerability in + unserialize() with SPLArrayObject + +--- + ext/spl/spl_array.c | 3 +++ + ext/spl/tests/bug70166.phpt | 29 +++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + create mode 100644 ext/spl/tests/bug70166.phpt + +diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c +index a37eced..86608c0 100644 +--- a/ext/spl/spl_array.c ++++ b/ext/spl/spl_array.c +@@ -1773,6 +1773,7 @@ SPL_METHOD(Array, unserialize) + goto outexcept; + } + ++ var_push_dtor(&var_hash, &pflags); + --p; /* for ';' */ + flags = Z_LVAL_P(pflags); + /* flags needs to be verified and we also need to verify whether the next +@@ -1796,6 +1797,7 @@ SPL_METHOD(Array, unserialize) + if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) { + goto outexcept; + } ++ var_push_dtor(&var_hash, &intern->array); + } + if (*p != ';') { + goto outexcept; +@@ -1814,6 +1816,7 @@ SPL_METHOD(Array, unserialize) + goto outexcept; + } + ++ var_push_dtor(&var_hash, &pmembers); + /* copy members */ + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); +diff --git a/ext/spl/tests/bug70166.phpt b/ext/spl/tests/bug70166.phpt +new file mode 100644 +index 0000000..51a3596 +--- /dev/null ++++ b/ext/spl/tests/bug70166.phpt +@@ -0,0 +1,29 @@ ++--TEST-- ++SPL: Bug #70166 Use After Free Vulnerability in unserialize() with SPLArrayObject ++--FILE-- ++ ++===DONE=== ++--EXPECTF-- ++array(2) { ++ [0]=> ++ object(ArrayObject)#%d (1) { ++ ["storage":"ArrayObject":private]=> ++ array(0) { ++ } ++ } ++ [1]=> ++ array(0) { ++ } ++} ++===DONE=== +-- +2.1.4 + +From c2e197e4efc663ca55f393bf0e799848842286f3 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 1 Aug 2015 21:12:38 -0700 +Subject: [PATCH] Fix bug #70168 - Use After Free Vulnerability in + unserialize() with SplObjectStorage + +--- + ext/spl/spl_observer.c | 68 +++++++++++++++++++++++---------------------- + ext/spl/tests/bug70168.phpt | 19 +++++++++++++ + 2 files changed, 54 insertions(+), 33 deletions(-) + create mode 100644 ext/spl/tests/bug70168.phpt + +diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c +index da9110b..5d94a3b 100644 +--- a/ext/spl/spl_observer.c ++++ b/ext/spl/spl_observer.c +@@ -848,6 +848,7 @@ SPL_METHOD(SplObjectStorage, unserialize + goto outexcept; + } + ++ var_push_dtor(&var_hash, &pcount); + --p; /* for ';' */ + count = Z_LVAL_P(pcount); + +@@ -919,6 +920,7 @@ SPL_METHOD(SplObjectStorage, unserialize + goto outexcept; + } + ++ var_push_dtor(&var_hash, &pmembers); + /* copy members */ + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); +diff --git a/ext/spl/tests/bug70168.phpt b/ext/spl/tests/bug70168.phpt +new file mode 100644 +index 0000000..192f0f3 +--- /dev/null ++++ b/ext/spl/tests/bug70168.phpt +@@ -0,0 +1,19 @@ ++--TEST-- ++SPL: Bug #70168 Use After Free Vulnerability in unserialize() with SplObjectStorage ++--FILE-- ++ ++===DONE=== ++--EXPECT-- ++int(1) ++===DONE=== +-- +2.1.4 + +From 863bf294feb9ad425eadb94f288bc7f18673089d Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 1 Aug 2015 21:51:08 -0700 +Subject: [PATCH] Fixed bug #70169 (Use After Free Vulnerability in + unserialize() with SplDoublyLinkedList) + +--- + ext/spl/spl_dllist.c | 25 +++++++++++++------------ + ext/spl/tests/bug70169.phpt | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 43 insertions(+), 12 deletions(-) + create mode 100644 ext/spl/tests/bug70169.phpt + +diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c +index b5ddfc0..011d7a6 100644 +--- a/ext/spl/spl_dllist.c ++++ b/ext/spl/spl_dllist.c +@@ -1207,6 +1207,7 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) + zval_ptr_dtor(&flags); + goto error; + } ++ var_push_dtor(&var_hash, &flags); + intern->flags = Z_LVAL_P(flags); + zval_ptr_dtor(&flags); + +diff --git a/ext/spl/tests/bug70169.phpt b/ext/spl/tests/bug70169.phpt +new file mode 100644 +index 0000000..9d814be +--- /dev/null ++++ b/ext/spl/tests/bug70169.phpt +@@ -0,0 +1,30 @@ ++--TEST-- ++SPL: Bug #70169 Use After Free Vulnerability in unserialize() with SplDoublyLinkedList ++--FILE-- ++ ++===DONE=== ++--EXPECTF-- ++array(2) { ++ [0]=> ++ object(SplDoublyLinkedList)#%d (2) { ++ ["flags":"SplDoublyLinkedList":private]=> ++ int(1) ++ ["dllist":"SplDoublyLinkedList":private]=> ++ array(0) { ++ } ++ } ++ [1]=> ++ int(1) ++} ++===DONE=== +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-6832.patch b/SOURCES/php-5.6.5-CVE-2015-6832.patch new file mode 100644 index 0000000..0df76d3 --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6832.patch @@ -0,0 +1,68 @@ +Patch cleanup for 5.6.5 + +From b7fa67742cd8d2b0ca0c0273b157f6ffee9ad6e2 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 26 Jul 2015 17:25:25 -0700 +Subject: [PATCH] Fix bug #70068 (Dangling pointer in the unserialization of + ArrayObject items) + +--- + ext/spl/spl_array.c | 90 +++++++++++++++++++++++---------------------- + ext/spl/tests/bug70068.phpt | 9 +++++ + 2 files changed, 56 insertions(+), 43 deletions(-) + create mode 100644 ext/spl/tests/bug70068.phpt + +diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c +index ec9ce21..a37eced 100644 +--- a/ext/spl/spl_array.c ++++ b/ext/spl/spl_array.c +@@ -1770,13 +1770,11 @@ SPL_METHOD(Array, unserialize) + + ALLOC_INIT_ZVAL(pflags); + if (!php_var_unserialize(&pflags, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pflags) != IS_LONG) { +- zval_ptr_dtor(&pflags); + goto outexcept; + } + + --p; /* for ';' */ + flags = Z_LVAL_P(pflags); +- zval_ptr_dtor(&pflags); + /* flags needs to be verified and we also need to verify whether the next + * thing we get is ';'. After that we require an 'm' or somethign else + * where 'm' stands for members and anything else should be an array. If +@@ -1826,10 +1824,16 @@ SPL_METHOD(Array, unserialize) + /* done reading $serialized */ + + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); ++ if (pflags) { ++ zval_ptr_dtor(&pflags); ++ } + return; + + outexcept: + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); ++ if (pflags) { ++ zval_ptr_dtor(&pflags); ++ } + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + return; + +diff --git a/ext/spl/tests/bug70068.phpt b/ext/spl/tests/bug70068.phpt +new file mode 100644 +index 0000000..92a38df +--- /dev/null ++++ b/ext/spl/tests/bug70068.phpt +@@ -0,0 +1,9 @@ ++--TEST-- ++Bug #70068 (Dangling pointer in the unserialization of ArrayObject items) ++--FILE-- ++ ++OK ++--EXPECT-- ++OK +\ No newline at end of file +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-6833.patch b/SOURCES/php-5.6.5-CVE-2015-6833.patch new file mode 100644 index 0000000..156dadd --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6833.patch @@ -0,0 +1,215 @@ +Patch cleanup for 5.6.5 +Binary diff removed + +From dda81f0505217a95db065e6bf9cc2d81eb902417 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Tue, 4 Aug 2015 14:00:29 -0700 +Subject: [PATCH] Fix bug #70019 - limit extracted files to given directory + +--- + ext/phar/phar_object.c | 50 +++++++++++++++++++++++++++++++++++++++---- + ext/phar/tests/bug70019.phpt | 22 +++++++++++++++++++ + ext/phar/tests/bug70019.zip | Bin 0 -> 184 bytes + 3 files changed, 68 insertions(+), 4 deletions(-) + create mode 100644 ext/phar/tests/bug70019.phpt + create mode 100644 ext/phar/tests/bug70019.zip + +diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c +index 8cfe0c8..b652181 100644 +--- a/ext/phar/phar_object.c ++++ b/ext/phar/phar_object.c +@@ -4118,6 +4118,9 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + char *fullpath; + const char *slash; + mode_t mode; ++ cwd_state new_state; ++ char *filename; ++ size_t filename_len; + + if (entry->is_mounted) { + /* silently ignore mounted entries */ +@@ -4127,8 +4130,39 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + if (entry->filename_len >= sizeof(".phar")-1 && !memcmp(entry->filename, ".phar", sizeof(".phar")-1)) { + return SUCCESS; + } ++ /* strip .. from path and restrict it to be under dest directory */ ++ new_state.cwd = (char*)malloc(2); ++ new_state.cwd[0] = DEFAULT_SLASH; ++ new_state.cwd[1] = '\0'; ++ new_state.cwd_length = 1; ++ if (virtual_file_ex(&new_state, entry->filename, NULL, CWD_EXPAND TSRMLS_CC) != 0 || ++ new_state.cwd_length <= 1) { ++ if (EINVAL == errno && entry->filename_len > 50) { ++ char *tmp = estrndup(entry->filename, 50); ++ spprintf(error, 4096, "Cannot extract \"%s...\" to \"%s...\", extracted filename is too long for filesystem", tmp, dest); ++ efree(tmp); ++ } else { ++ spprintf(error, 4096, "Cannot extract \"%s\", internal error", entry->filename); ++ } ++ free(new_state.cwd); ++ return FAILURE; ++ } ++ filename = new_state.cwd + 1; ++ filename_len = new_state.cwd_length - 1; ++#ifdef PHP_WIN32 ++ /* unixify the path back, otherwise non zip formats might be broken */ ++ { ++ int cnt = filename_len; ++ ++ do { ++ if ('\\' == filename[cnt]) { ++ filename[cnt] = '/'; ++ } ++ } while (cnt-- >= 0); ++ } ++#endif + +- len = spprintf(&fullpath, 0, "%s/%s", dest, entry->filename); ++ len = spprintf(&fullpath, 0, "%s/%s", dest, filename); + + if (len >= MAXPATHLEN) { + char *tmp; +@@ -4142,18 +4176,21 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s...\", extracted filename is too long for filesystem", entry->filename, fullpath); + } + efree(fullpath); ++ free(new_state.cwd); + return FAILURE; + } + + if (!len) { + spprintf(error, 4096, "Cannot extract \"%s\", internal error", entry->filename); + efree(fullpath); ++ free(new_state.cwd); + return FAILURE; + } + + if (PHAR_OPENBASEDIR_CHECKPATH(fullpath)) { + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", openbasedir/safe mode restrictions in effect", entry->filename, fullpath); + efree(fullpath); ++ free(new_state.cwd); + return FAILURE; + } + +@@ -4161,14 +4198,15 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + if (!overwrite && SUCCESS == php_stream_stat_path(fullpath, &ssb)) { + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", path already exists", entry->filename, fullpath); + efree(fullpath); ++ free(new_state.cwd); + return FAILURE; + } + + /* perform dirname */ +- slash = zend_memrchr(entry->filename, '/', entry->filename_len); ++ slash = zend_memrchr(filename, '/', filename_len); + + if (slash) { +- fullpath[dest_len + (slash - entry->filename) + 1] = '\0'; ++ fullpath[dest_len + (slash - filename) + 1] = '\0'; + } else { + fullpath[dest_len] = '\0'; + } +@@ -4178,23 +4216,27 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + if (!php_stream_mkdir(fullpath, entry->flags & PHAR_ENT_PERM_MASK, PHP_STREAM_MKDIR_RECURSIVE, NULL)) { + spprintf(error, 4096, "Cannot extract \"%s\", could not create directory \"%s\"", entry->filename, fullpath); + efree(fullpath); ++ free(new_state.cwd); + return FAILURE; + } + } else { + if (!php_stream_mkdir(fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL)) { + spprintf(error, 4096, "Cannot extract \"%s\", could not create directory \"%s\"", entry->filename, fullpath); + efree(fullpath); ++ free(new_state.cwd); + return FAILURE; + } + } + } + + if (slash) { +- fullpath[dest_len + (slash - entry->filename) + 1] = '/'; ++ fullpath[dest_len + (slash - filename) + 1] = '/'; + } else { + fullpath[dest_len] = '/'; + } + ++ filename = NULL; ++ free(new_state.cwd); + /* it is a standalone directory, job done */ + if (entry->is_dir) { + efree(fullpath); + +From eb7ba73079b73ca4ef91307ae1ef30b43468717b Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Tue, 4 Aug 2015 16:31:57 -0700 +Subject: [PATCH] virtual_file_ex uses emalloc in 5.6+ + +--- + ext/phar/phar_object.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c +index 22d59c2..d7c9541 100644 +--- a/ext/phar/phar_object.c ++++ b/ext/phar/phar_object.c +@@ -4131,7 +4131,7 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + return SUCCESS; + } + /* strip .. from path and restrict it to be under dest directory */ +- new_state.cwd = (char*)malloc(2); ++ new_state.cwd = (char*)emalloc(2); + new_state.cwd[0] = DEFAULT_SLASH; + new_state.cwd[1] = '\0'; + new_state.cwd_length = 1; +@@ -4144,7 +4144,7 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + } else { + spprintf(error, 4096, "Cannot extract \"%s\", internal error", entry->filename); + } +- free(new_state.cwd); ++ efree(new_state.cwd); + return FAILURE; + } + filename = new_state.cwd + 1; +@@ -4176,21 +4176,21 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s...\", extracted filename is too long for filesystem", entry->filename, fullpath); + } + efree(fullpath); +- free(new_state.cwd); ++ efree(new_state.cwd); + return FAILURE; + } + + if (!len) { + spprintf(error, 4096, "Cannot extract \"%s\", internal error", entry->filename); + efree(fullpath); +- free(new_state.cwd); ++ efree(new_state.cwd); + return FAILURE; + } + + if (PHAR_OPENBASEDIR_CHECKPATH(fullpath)) { + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", openbasedir/safe mode restrictions in effect", entry->filename, fullpath); + efree(fullpath); +- free(new_state.cwd); ++ efree(new_state.cwd); + return FAILURE; + } + +@@ -4198,7 +4198,7 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + if (!overwrite && SUCCESS == php_stream_stat_path(fullpath, &ssb)) { + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", path already exists", entry->filename, fullpath); + efree(fullpath); +- free(new_state.cwd); ++ efree(new_state.cwd); + return FAILURE; + } + +@@ -4236,7 +4236,7 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * + } + + filename = NULL; +- free(new_state.cwd); ++ efree(new_state.cwd); + /* it is a standalone directory, job done */ + if (entry->is_dir) { + efree(fullpath); diff --git a/SOURCES/php-5.6.5-CVE-2015-6834-1.patch b/SOURCES/php-5.6.5-CVE-2015-6834-1.patch new file mode 100644 index 0000000..8977714 --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6834-1.patch @@ -0,0 +1,355 @@ +From e8429400d40e3c3aa4b22ba701991d698a2f3b2f Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 31 Aug 2015 21:28:11 -0700 +Subject: [PATCH] Fix bug #70172 - Use After Free Vulnerability in + unserialize() + +--- + ext/standard/tests/serialize/bug70172.phpt | 52 ++++++++++++++++++++ + ext/standard/var.c | 23 +++++++-- + ext/standard/var_unserializer.c | 76 ++++++++++++++++-------------- + ext/standard/var_unserializer.re | 12 +++-- + 4 files changed, 121 insertions(+), 42 deletions(-) + create mode 100644 ext/standard/tests/serialize/bug70172.phpt + +diff --git a/ext/standard/tests/serialize/bug70172.phpt b/ext/standard/tests/serialize/bug70172.phpt +new file mode 100644 +index 0000000..0e9d7ed +--- /dev/null ++++ b/ext/standard/tests/serialize/bug70172.phpt +@@ -0,0 +1,52 @@ ++--TEST-- ++Bug #70172 - Use After Free Vulnerability in unserialize() ++--FILE-- ++data); ++ } ++ function unserialize($data) { ++ $this->data = unserialize($data); ++ } ++} ++ ++$fakezval = ptr2str(1122334455); ++$fakezval .= ptr2str(0); ++$fakezval .= "\x00\x00\x00\x00"; ++$fakezval .= "\x01"; ++$fakezval .= "\x00"; ++$fakezval .= "\x00\x00"; ++ ++$inner = 'r:2;'; ++$exploit = 'a:2:{i:0;i:1;i:1;C:3:"obj":'.strlen($inner).':{'.$inner.'}}'; ++ ++$data = unserialize($exploit); ++ ++for ($i = 0; $i < 5; $i++) { ++ $v[$i] = $fakezval.$i; ++} ++ ++var_dump($data); ++ ++function ptr2str($ptr) ++{ ++ $out = ''; ++ for ($i = 0; $i < 8; $i++) { ++ $out .= chr($ptr & 0xff); ++ $ptr >>= 8; ++ } ++ return $out; ++} ++?> ++--EXPECTF-- ++array(2) { ++ [0]=> ++ int(1) ++ [1]=> ++ object(obj)#%d (1) { ++ ["data"]=> ++ int(1) ++ } ++} +\ No newline at end of file +diff --git a/ext/standard/var.c b/ext/standard/var.c +index 7603ff2..33b976f 100644 +--- a/ext/standard/var.c ++++ b/ext/standard/var.c +@@ -951,6 +951,8 @@ PHP_FUNCTION(unserialize) + int buf_len; + const unsigned char *p; + php_unserialize_data_t var_hash; ++ int oldlevel; ++ zval *old_rval = return_value; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { + RETURN_FALSE; +@@ -970,6 +972,19 @@ PHP_FUNCTION(unserialize) + } + RETURN_FALSE; + } ++ if (return_value != old_rval) { ++ /* ++ * Terrible hack due to the fact that executor passes us zval *, ++ * but unserialize with r/R wants to replace it with another zval * ++ */ ++ zval_dtor(old_rval); ++ *old_rval = *return_value; ++ zval_copy_ctor(old_rval); ++ var_push_dtor_no_addref(&var_hash, &return_value); ++ var_push_dtor_no_addref(&var_hash, &old_rval); ++ } else { ++ var_push_dtor(&var_hash, &return_value); ++ } + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + } + /* }}} */ +diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c +index ffaf680..5f2336e 100644 +--- a/ext/standard/var_unserializer.c ++++ b/ext/standard/var_unserializer.c +@@ -67,7 +67,7 @@ + + var_hash = (*var_hashx)->last_dtor; + #if VAR_ENTRIES_DBG +- fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); ++ fprintf(stderr, "var_push_dtor(%p, %ld): %d\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); + #endif + + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { +@@ -98,7 +98,7 @@ + + var_hash = (*var_hashx)->last_dtor; + #if VAR_ENTRIES_DBG +- fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); ++ fprintf(stderr, "var_push_dtor_no_addref(%p, %ld): %d (%d)\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); + #endif + + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { +@@ -177,6 +177,9 @@ + + while (var_hash) { + for (i = 0; i < var_hash->used_slots; i++) { ++#if VAR_ENTRIES_DBG ++ fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_hash->data[i], Z_REFCOUNT_P(var_hash->data[i])); ++#endif + zval_ptr_dtor(&var_hash->data[i]); + } + next = var_hash->next; +@@ -629,6 +632,7 @@ + zval **args[1]; + zval *arg_func_name; + ++ if (!var_hash) return 0; + if (*start == 'C') { + custom_object = 1; + } +@@ -784,6 +788,7 @@ + if (yych != '"') goto yy18; + ++YYCURSOR; + { ++ if (!var_hash) return 0; + + INIT_PZVAL(*rval); + +@@ -814,6 +819,7 @@ + long elements = parse_iv(start + 2); + /* use iv() not uiv() in order to check data range */ + *p = YYCURSOR; ++ if (!var_hash) return 0; + + if (elements < 0) { + return 0; +@@ -1243,7 +1249,7 @@ + } + + if (*rval != NULL) { +- zval_ptr_dtor(rval); ++ var_push_dtor_no_addref(var_hash, rval); + } + *rval = *rval_ref; + Z_ADDREF_PP(rval); +diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re +index f02602c..ed82152 100644 +--- a/ext/standard/var_unserializer.re ++++ b/ext/standard/var_unserializer.re +@@ -66,7 +66,7 @@ + + var_hash = (*var_hashx)->last_dtor; + #if VAR_ENTRIES_DBG +- fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); ++ fprintf(stderr, "var_push_dtor(%p, %ld): %d\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); + #endif + + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { +@@ -97,7 +97,7 @@ + + var_hash = (*var_hashx)->last_dtor; + #if VAR_ENTRIES_DBG +- fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); ++ fprintf(stderr, "var_push_dtor_no_addref(%p, %ld): %d (%d)\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); + #endif + + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { +@@ -176,6 +176,9 @@ + + while (var_hash) { + for (i = 0; i < var_hash->used_slots; i++) { ++#if VAR_ENTRIES_DBG ++ fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_hash->data[i], Z_REFCOUNT_P(var_hash->data[i])); ++#endif + zval_ptr_dtor(&var_hash->data[i]); + } + next = var_hash->next; +@@ -496,7 +499,7 @@ + } + + if (*rval != NULL) { +- zval_ptr_dtor(rval); ++ var_push_dtor_no_addref(var_hash, rval); + } + *rval = *rval_ref; + Z_ADDREF_PP(rval); +@@ -655,6 +658,7 @@ + long elements = parse_iv(start + 2); + /* use iv() not uiv() in order to check data range */ + *p = YYCURSOR; ++ if (!var_hash) return 0; + + if (elements < 0) { + return 0; +@@ -672,6 +676,7 @@ + } + + "o:" iv ":" ["] { ++ if (!var_hash) return 0; + + INIT_PZVAL(*rval); + +@@ -694,6 +699,7 @@ + zval **args[1]; + zval *arg_func_name; + ++ if (!var_hash) return 0; + if (*start == 'C') { + custom_object = 1; + } +-- +2.1.4 + +From 7c31203935589ab4fcb104041ef9d87f747bfee4 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Tue, 1 Sep 2015 11:38:15 -0700 +Subject: [PATCH] Improve fix for #70172 + +--- + ext/standard/tests/serialize/bug70172.phpt | 2 + + ext/standard/tests/serialize/bug70172_2.phpt | 68 ++++++++++++++++++++++++++++ + ext/standard/var.c | 3 +- + 3 files changed, 72 insertions(+), 1 deletion(-) + create mode 100644 ext/standard/tests/serialize/bug70172_2.phpt + +diff --git a/ext/standard/tests/serialize/bug70172.phpt b/ext/standard/tests/serialize/bug70172.phpt +index 0e9d7ed..0a4aa4b 100644 +--- a/ext/standard/tests/serialize/bug70172.phpt ++++ b/ext/standard/tests/serialize/bug70172.phpt +@@ -1,5 +1,7 @@ + --TEST-- + Bug #70172 - Use After Free Vulnerability in unserialize() ++--XFAIL-- ++Memory leak on debug build, needs fix. + --FILE-- + data); ++ } ++ function unserialize($data) { ++ $this->data = unserialize($data); ++ } ++} ++ ++class obj2 { ++ var $ryat; ++ function __wakeup() { ++ $this->ryat = 1; ++ } ++} ++ ++$fakezval = ptr2str(1122334455); ++$fakezval .= ptr2str(0); ++$fakezval .= "\x00\x00\x00\x00"; ++$fakezval .= "\x01"; ++$fakezval .= "\x00"; ++$fakezval .= "\x00\x00"; ++ ++$inner = 'r:2;'; ++$exploit = 'a:2:{i:0;O:4:"obj2":1:{s:4:"ryat";C:3:"obj":'.strlen($inner).':{'.$inner.'}}i:1;a:1:{i:0;a:1:{i:0;R:4;}}}'; ++ ++$data = unserialize($exploit); ++ ++for ($i = 0; $i < 5; $i++) { ++ $v[$i] = $fakezval.$i; ++} ++ ++var_dump($data); ++ ++function ptr2str($ptr) ++{ ++ $out = ''; ++ for ($i = 0; $i < 8; $i++) { ++ $out .= chr($ptr & 0xff); ++ $ptr >>= 8; ++ } ++ return $out; ++} ++?> ++--EXPECTF-- ++array(2) { ++ [0]=> ++ object(obj2)#%d (1) { ++ ["ryat"]=> ++ int(1) ++ } ++ [1]=> ++ array(1) { ++ [0]=> ++ array(1) { ++ [0]=> ++ object(obj2)#%d (1) { ++ ["ryat"]=> ++ int(1) ++ } ++ } ++ } ++} +\ No newline at end of file +diff --git a/ext/standard/var.c b/ext/standard/var.c +index 33b976f..113b8cb 100644 +--- a/ext/standard/var.c ++++ b/ext/standard/var.c +@@ -981,7 +981,8 @@ PHP_FUNCTION(unserialize) + *old_rval = *return_value; + zval_copy_ctor(old_rval); + var_push_dtor_no_addref(&var_hash, &return_value); +- var_push_dtor_no_addref(&var_hash, &old_rval); ++ /* FIXME: old_rval is not freed in some scenarios, see bug #70172 ++ var_push_dtor_no_addref(&var_hash, &old_rval); */ + } else { + var_push_dtor(&var_hash, &return_value); + } +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-6834-2.patch b/SOURCES/php-5.6.5-CVE-2015-6834-2.patch new file mode 100644 index 0000000..e8fd7fb --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6834-2.patch @@ -0,0 +1,191 @@ +From f06a069c462d37c2e009f6d1d93b8c8e7b713393 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Tue, 1 Sep 2015 00:14:15 -0700 +Subject: [PATCH] Fix bug #70365 - use-after-free vulnerability in + unserialize() with SplObjectStorage + +--- + ext/spl/spl_observer.c | 2 ++ + ext/spl/tests/bug70365.phpt | 50 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 52 insertions(+) + create mode 100644 ext/spl/tests/bug70365.phpt + +diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c +index 5d94a3b..6a2e321 100644 +--- a/ext/spl/spl_observer.c ++++ b/ext/spl/spl_observer.c +@@ -869,6 +869,7 @@ SPL_METHOD(SplObjectStorage, unserialize) + zval_ptr_dtor(&pentry); + goto outexcept; + } ++ var_push_dtor(&var_hash, &pentry); + if(Z_TYPE_P(pentry) != IS_OBJECT) { + zval_ptr_dtor(&pentry); + goto outexcept; +@@ -880,6 +881,7 @@ SPL_METHOD(SplObjectStorage, unserialize) + zval_ptr_dtor(&pinf); + goto outexcept; + } ++ var_push_dtor(&var_hash, &pinf); + } + + hash = spl_object_storage_get_hash(intern, getThis(), pentry, &hash_len TSRMLS_CC); +diff --git a/ext/spl/tests/bug70365.phpt b/ext/spl/tests/bug70365.phpt +new file mode 100644 +index 0000000..bd57360 +--- /dev/null ++++ b/ext/spl/tests/bug70365.phpt +@@ -0,0 +1,50 @@ ++--TEST-- ++SPL: Bug #70365 yet another use-after-free vulnerability in unserialize() with SplObjectStorage ++--FILE-- ++ryat = 1; ++ } ++} ++ ++$fakezval = ptr2str(1122334455); ++$fakezval .= ptr2str(0); ++$fakezval .= "\x00\x00\x00\x00"; ++$fakezval .= "\x01"; ++$fakezval .= "\x00"; ++$fakezval .= "\x00\x00"; ++ ++$inner = 'x:i:1;O:8:"stdClass":0:{},i:1;;m:a:0:{}'; ++$exploit = 'a:5:{i:0;i:1;i:1;C:16:"SplObjectStorage":'.strlen($inner).':{'.$inner.'}i:2;O:3:"obj":1:{s:4:"ryat";R:3;}i:3;R:6;i:4;s:'.strlen($fakezval).':"'.$fakezval.'";}'; ++ ++$data = unserialize($exploit); ++ ++var_dump($data); ++ ++function ptr2str($ptr) ++{ ++ $out = ''; ++ for ($i = 0; $i < 8; $i++) { ++ $out .= chr($ptr & 0xff); ++ $ptr >>= 8; ++ } ++ return $out; ++} ++--EXPECTF-- ++array(5) { ++ [0]=> ++ int(1) ++ [1]=> ++ &int(1) ++ [2]=> ++ object(obj)#%d (1) { ++ ["ryat"]=> ++ &int(1) ++ } ++ [3]=> ++ int(1) ++ [4]=> ++ string(24) "%s" ++} +-- +2.1.4 + +From 259057b2a484747a6c73ce54c4fa0f5acbd56179 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Tue, 1 Sep 2015 00:20:45 -0700 +Subject: [PATCH] Fix bug #70366 - use-after-free vulnerability in + unserialize() with SplDoublyLinkedList + +--- + ext/spl/spl_dllist.c | 1 + + ext/spl/tests/bug70365.phpt | 2 +- + ext/spl/tests/bug70366.phpt | 54 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 56 insertions(+), 1 deletion(-) + create mode 100644 ext/spl/tests/bug70366.phpt + +diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c +index 011d7a6..ebe61c3 100644 +--- a/ext/spl/spl_dllist.c ++++ b/ext/spl/spl_dllist.c +@@ -1219,6 +1219,7 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) + zval_ptr_dtor(&elem); + goto error; + } ++ var_push_dtor(&var_hash, &elem); + + spl_ptr_llist_push(intern->llist, elem TSRMLS_CC); + } +diff --git a/ext/spl/tests/bug70365.phpt b/ext/spl/tests/bug70365.phpt +index bd57360..c18110e 100644 +--- a/ext/spl/tests/bug70365.phpt ++++ b/ext/spl/tests/bug70365.phpt +@@ -1,5 +1,5 @@ + --TEST-- +-SPL: Bug #70365 yet another use-after-free vulnerability in unserialize() with SplObjectStorage ++SPL: Bug #70365 use-after-free vulnerability in unserialize() with SplObjectStorage + --FILE-- + ryat = 1; ++ } ++} ++ ++$fakezval = ptr2str(1122334455); ++$fakezval .= ptr2str(0); ++$fakezval .= "\x00\x00\x00\x00"; ++$fakezval .= "\x01"; ++$fakezval .= "\x00"; ++$fakezval .= "\x00\x00"; ++ ++$inner = 'i:1234;:i:1;'; ++$exploit = 'a:5:{i:0;i:1;i:1;C:19:"SplDoublyLinkedList":'.strlen($inner).':{'.$inner.'}i:2;O:3:"obj":1:{s:4:"ryat";R:3;}i:3;a:1:{i:0;R:5;}i:4;s:'.strlen($fakezval).':"'.$fakezval.'";}'; ++ ++$data = unserialize($exploit); ++ ++var_dump($data); ++ ++function ptr2str($ptr) ++{ ++ $out = ''; ++ for ($i = 0; $i < 8; $i++) { ++ $out .= chr($ptr & 0xff); ++ $ptr >>= 8; ++ } ++ return $out; ++} ++?> ++--EXPECTF-- ++array(5) { ++ [0]=> ++ int(1) ++ [1]=> ++ &int(1) ++ [2]=> ++ object(obj)#%d (1) { ++ ["ryat"]=> ++ &int(1) ++ } ++ [3]=> ++ array(1) { ++ [0]=> ++ int(1) ++ } ++ [4]=> ++ string(24) "%s" ++} +\ No newline at end of file +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-6835.patch b/SOURCES/php-5.6.5-CVE-2015-6835.patch new file mode 100644 index 0000000..a2536ac --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6835.patch @@ -0,0 +1,1021 @@ +Patch cleanup for 5.6.5 + +From df4bf28f9f104ca3ef78ed94b497859f15b004e5 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 23 Aug 2015 13:27:59 -0700 +Subject: [PATCH] Fix bug #70219 (Use after free vulnerability in session + deserializer) + +--- + ext/session/session.c | 36 +- + ext/session/tests/session_decode_error2.phpt | 518 +++++------------------ + ext/session/tests/session_decode_variation3.phpt | 2 +- + ext/standard/tests/serialize/bug70219.phpt | 38 ++ + ext/standard/var_unserializer.c | 68 +-- + ext/standard/var_unserializer.re | 64 +-- + 6 files changed, 228 insertions(+), 498 deletions(-) + create mode 100644 ext/standard/tests/serialize/bug70219.phpt + +diff --git a/ext/session/session.c b/ext/session/session.c +index 306aba3..0e53c62 100644 +--- a/ext/session/session.c ++++ b/ext/session/session.c +@@ -210,16 +210,18 @@ static char *php_session_encode(int *newlen TSRMLS_DC) /* {{{ */ + } + /* }}} */ + +-static void php_session_decode(const char *val, int vallen TSRMLS_DC) /* {{{ */ ++static int php_session_decode(const char *val, int vallen TSRMLS_DC) /* {{{ */ + { + if (!PS(serializer)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown session.serialize_handler. Failed to decode session object"); +- return; ++ return FAILURE; + } + if (PS(serializer)->decode(val, vallen TSRMLS_CC) == FAILURE) { + php_session_destroy(TSRMLS_C); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to decode session object. Session has been destroyed"); ++ return FAILURE; + } ++ return SUCCESS; + } + /* }}} */ + +@@ -855,8 +857,11 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */ + ALLOC_INIT_ZVAL(current); + if (php_var_unserialize(¤t, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { + php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC); ++ } else { ++ PHP_VAR_UNSERIALIZE_DESTROY(var_hash); ++ return FAILURE; + } +- zval_ptr_dtor(¤t); ++ var_push_dtor_no_addref(&var_hash, ¤t); + } + PS_ADD_VARL(name, namelen); + efree(name); +@@ -947,8 +952,13 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */ + ALLOC_INIT_ZVAL(current); + if (php_var_unserialize(¤t, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { + php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC); ++ } else { ++ var_push_dtor_no_addref(&var_hash, ¤t); ++ efree(name); ++ PHP_VAR_UNSERIALIZE_DESTROY(var_hash); ++ return FAILURE; + } +- zval_ptr_dtor(¤t); ++ var_push_dtor_no_addref(&var_hash, ¤t); + } + PS_ADD_VARL(name, namelen); + skip: +@@ -1922,9 +1932,7 @@ static PHP_FUNCTION(session_decode) + return; + } + +- php_session_decode(str, str_len TSRMLS_CC); +- +- RETURN_TRUE; ++ RETVAL_BOOL(php_session_decode(str, str_len TSRMLS_CC) == SUCCESS); + } + /* }}} */ + +diff --git a/ext/session/tests/session_decode_error2.phpt b/ext/session/tests/session_decode_error2.phpt +index 4160f87..515047b 100644 +--- a/ext/session/tests/session_decode_error2.phpt ++++ b/ext/session/tests/session_decode_error2.phpt +@@ -53,563 +53,247 @@ array(0) { + } + + -- Iteration 4 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++ ++Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d ++bool(false) ++array(0) { + } + + -- Iteration 5 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 6 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 7 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 8 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 9 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 10 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 11 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 12 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 13 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 14 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 15 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 16 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 17 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 18 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 19 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 20 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 21 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 22 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 23 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 24 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 25 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 26 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 27 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 28 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 29 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 30 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 31 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 32 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 33 -- +-bool(true) +-array(1) { +- ["foo"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 34 -- +-bool(true) +-array(1) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 35 -- +-bool(true) +-array(1) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 36 -- +-bool(true) +-array(1) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 37 -- +-bool(true) +-array(1) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 38 -- +-bool(true) +-array(1) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 39 -- +-bool(true) +-array(2) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 40 -- +-bool(true) +-array(2) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 41 -- +-bool(true) +-array(2) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 42 -- +-bool(true) +-array(2) { +- ["foo"]=> +- array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 43 -- +-bool(true) +-array(2) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 44 -- +-bool(true) +-array(2) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 45 -- +-bool(true) +-array(2) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 46 -- +-bool(true) +-array(2) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 47 -- +-bool(true) +-array(2) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } ++bool(false) ++array(0) { + } + + -- Iteration 48 -- +-bool(true) +-array(3) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["blah"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 49 -- +-bool(true) +-array(3) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["blah"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 50 -- +-bool(true) +-array(3) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["blah"]=> +- NULL ++bool(false) ++array(0) { + } + + -- Iteration 51 -- +-bool(true) +-array(3) { +- ["foo"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["guff"]=> +- &array(3) { +- [0]=> +- int(1) +- [1]=> +- int(2) +- [2]=> +- int(3) +- } +- ["blah"]=> +- NULL ++bool(false) ++array(0) { + } +-bool(true) +-Done + ++Warning: session_destroy(): Trying to destroy uninitialized session in %s/session_decode_error2.php on line %d ++bool(false) ++Done +diff --git a/ext/session/tests/session_decode_variation3.phpt b/ext/session/tests/session_decode_variation3.phpt +index 4a6f768..0960531 100644 +--- a/ext/session/tests/session_decode_variation3.phpt ++++ b/ext/session/tests/session_decode_variation3.phpt +@@ -49,7 +49,7 @@ array(3) { + } + + Warning: session_decode(): Unknown session.serialize_handler. Failed to decode session object in %s on line %d +-bool(true) ++bool(false) + array(3) { + ["foo"]=> + int(1234567890) +diff --git a/ext/standard/tests/serialize/bug70219.phpt b/ext/standard/tests/serialize/bug70219.phpt +new file mode 100644 +index 0000000..84a059f +--- /dev/null ++++ b/ext/standard/tests/serialize/bug70219.phpt +@@ -0,0 +1,38 @@ ++--TEST-- ++Bug #70219 Use after free vulnerability in session deserializer ++--FILE-- ++data); ++ } ++ function unserialize($data) { ++ session_start(); ++ session_decode($data); ++ } ++} ++ ++$inner = 'ryat|a:1:{i:0;a:1:{i:1;'; ++$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}'; ++ ++$data = unserialize($exploit); ++ ++for ($i = 0; $i < 5; $i++) { ++ $v[$i] = 'hi'.$i; ++} ++ ++var_dump($data); ++?> ++--EXPECTF-- ++Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s on line %d ++array(2) { ++ [0]=> ++ object(obj)#%d (1) { ++ ["data"]=> ++ NULL ++ } ++ [1]=> ++ array(0) { ++ } ++} +diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c +index ee0cac4..ffaf680 100644 +--- a/ext/standard/var_unserializer.c ++++ b/ext/standard/var_unserializer.c +@@ -90,7 +90,13 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) + + PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval) + { +- var_entries *var_hash = (*var_hashx)->last_dtor; ++ var_entries *var_hash; ++ ++ if (!var_hashx || !*var_hashx) { ++ return; ++ } ++ ++ var_hash = (*var_hashx)->last_dtor; + #if VAR_ENTRIES_DBG + fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); + #endif +@@ -301,24 +307,20 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long + ALLOC_INIT_ZVAL(key); + + if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) { +- zval_dtor(key); +- FREE_ZVAL(key); ++ var_push_dtor_no_addref(var_hash, &key); + return 0; + } + + if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) { +- zval_dtor(key); +- FREE_ZVAL(key); ++ var_push_dtor_no_addref(var_hash, &key); + return 0; + } + + ALLOC_INIT_ZVAL(data); + + if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) { +- zval_dtor(key); +- FREE_ZVAL(key); +- zval_dtor(data); +- FREE_ZVAL(data); ++ var_push_dtor_no_addref(var_hash, &key); ++ var_push_dtor_no_addref(var_hash, &data); + return 0; + } + +@@ -347,9 +349,7 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long + sizeof data, NULL); + } + var_push_dtor(var_hash, &data); +- +- zval_dtor(key); +- FREE_ZVAL(key); ++ var_push_dtor_no_addref(var_hash, &key); + + if (elements && *(*p-1) != ';' && *(*p-1) != '}') { + (*p)--; +diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re +index abac77c..f02602c 100644 +--- a/ext/standard/var_unserializer.re ++++ b/ext/standard/var_unserializer.re +@@ -89,7 +89,13 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) + + PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval) + { +- var_entries *var_hash = (*var_hashx)->last_dtor; ++ var_entries *var_hash; ++ ++ if (!var_hashx || !*var_hashx) { ++ return; ++ } ++ ++ var_hash = (*var_hashx)->last_dtor; + #if VAR_ENTRIES_DBG + fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); + #endif +@@ -307,24 +313,20 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long + ALLOC_INIT_ZVAL(key); + + if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) { +- zval_dtor(key); +- FREE_ZVAL(key); ++ var_push_dtor_no_addref(var_hash, &key); + return 0; + } + + if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) { +- zval_dtor(key); +- FREE_ZVAL(key); ++ var_push_dtor_no_addref(var_hash, &key); + return 0; + } + + ALLOC_INIT_ZVAL(data); + + if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) { +- zval_dtor(key); +- FREE_ZVAL(key); +- zval_dtor(data); +- FREE_ZVAL(data); ++ var_push_dtor_no_addref(var_hash, &key); ++ var_push_dtor_no_addref(var_hash, &data); + return 0; + } + +@@ -353,9 +355,7 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long + sizeof data, NULL); + } + var_push_dtor(var_hash, &data); +- +- zval_dtor(key); +- FREE_ZVAL(key); ++ var_push_dtor_no_addref(var_hash, &key); + + if (elements && *(*p-1) != ';' && *(*p-1) != '}') { + (*p)--; +-- +2.1.4 + +From fc8eff897bd7fe3fed7f6867d2d6a86117a5278d Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Fri, 28 Aug 2015 21:50:21 -0700 +Subject: [PATCH] More fixes for bug #70219 + +--- + ext/session/session.c | 7 +++-- + ext/standard/tests/serialize/bug70219_1.phpt | 46 ++++++++++++++++++++++++++++ + 2 files changed, 51 insertions(+), 2 deletions(-) + create mode 100644 ext/standard/tests/serialize/bug70219_1.phpt + +diff --git a/ext/session/session.c b/ext/session/session.c +index 247f9b2..f5439ea 100644 +--- a/ext/session/session.c ++++ b/ext/session/session.c +@@ -863,7 +863,10 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */ + + PHP_VAR_UNSERIALIZE_INIT(var_hash); + ALLOC_INIT_ZVAL(session_vars); +- php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC); ++ if (php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC)) { ++ var_push_dtor(&var_hash, &session_vars); ++ } ++ + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + if (PS(http_session_vars)) { + zval_ptr_dtor(&PS(http_session_vars)); +@@ -872,7 +875,7 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */ + array_init(session_vars); + } + PS(http_session_vars) = session_vars; +- ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 2, 1); ++ ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), Z_REFCOUNT_P(PS(http_session_vars)) + 1, 1); + return SUCCESS; + } + /* }}} */ +diff --git a/ext/standard/tests/serialize/bug70219_1.phpt b/ext/standard/tests/serialize/bug70219_1.phpt +new file mode 100644 +index 0000000..f9c4c67 +--- /dev/null ++++ b/ext/standard/tests/serialize/bug70219_1.phpt +@@ -0,0 +1,46 @@ ++--TEST-- ++Bug #70219 Use after free vulnerability in session deserializer ++--FILE-- ++data); ++ } ++ function unserialize($data) { ++ session_decode($data); ++ } ++} ++ ++$inner = 'r:2;'; ++$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;C:3:"obj":'.strlen($inner).':{'.$inner.'}}'; ++ ++$data = unserialize($exploit); ++ ++for ($i = 0; $i < 5; $i++) { ++ $v[$i] = 'hi'.$i; ++} ++ ++var_dump($data); ++var_dump($_SESSION); ++?> ++--EXPECTF-- ++array(2) { ++ [0]=> ++ &object(obj)#%d (1) { ++ ["data"]=> ++ NULL ++ } ++ [1]=> ++ object(obj)#%d (1) { ++ ["data"]=> ++ NULL ++ } ++} ++object(obj)#1 (1) { ++ ["data"]=> ++ NULL ++} +\ No newline at end of file +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-6836.patch b/SOURCES/php-5.6.5-CVE-2015-6836.patch new file mode 100644 index 0000000..eaf1e7e --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6836.patch @@ -0,0 +1,88 @@ +Patch cleanup for 5.6.5 + +From e201f01ac17243a1e5fb6a3911ed8e21b1619ac1 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 31 Aug 2015 21:06:03 -0700 +Subject: [PATCH] Fix bug #70388 - SOAP serialize_function_call() type + confusion + +--- + ext/soap/soap.c | 96 ++++++++++++++++++++++++-------------------- + ext/soap/tests/bug70388.phpt | 17 ++++++++ + 2 files changed, 69 insertions(+), 44 deletions(-) + create mode 100644 ext/soap/tests/bug70388.phpt + +diff --git a/ext/soap/soap.c b/ext/soap/soap.c +index 1b8f545..a0e64a3 100644 +--- a/ext/soap/soap.c ++++ b/ext/soap/soap.c +@@ -2921,8 +2921,10 @@ PHP_METHOD(SoapClient, __call) + } + zend_hash_internal_pointer_reset(default_headers); + while (zend_hash_get_current_data(default_headers, (void**)&tmp) == SUCCESS) { +- Z_ADDREF_PP(tmp); +- zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL); ++ if(Z_TYPE_PP(tmp) == IS_OBJECT) { ++ Z_ADDREF_PP(tmp); ++ zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL); ++ } + zend_hash_move_forward(default_headers); + } + } else { +@@ -4346,11 +4348,18 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function + if (head) { + zval** header; + +- zend_hash_internal_pointer_reset(soap_headers); +- while (zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS) { +- HashTable *ht = Z_OBJPROP_PP(header); ++ for(zend_hash_internal_pointer_reset(soap_headers); ++ zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS; ++ zend_hash_move_forward(soap_headers) ++ ) { ++ HashTable *ht; + zval **name, **ns, **tmp; + ++ if (Z_TYPE_PP(header) != IS_OBJECT) { ++ continue; ++ } ++ ++ ht = Z_OBJPROP_PP(header); + if (zend_hash_find(ht, "name", sizeof("name"), (void**)&name) == SUCCESS && + Z_TYPE_PP(name) == IS_STRING && + zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&ns) == SUCCESS && +@@ -4389,7 +4398,6 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function + xmlSetNs(h, nsptr); + set_soap_header_attributes(h, ht, version); + } +- zend_hash_move_forward(soap_headers); + } + } + +diff --git a/ext/soap/tests/bug70388.phpt b/ext/soap/tests/bug70388.phpt +new file mode 100644 +index 0000000..49a8efc +--- /dev/null ++++ b/ext/soap/tests/bug70388.phpt +@@ -0,0 +1,17 @@ ++--TEST-- ++Bug #70388 (SOAP serialize_function_call() type confusion / RCE) ++--SKIPIF-- ++ ++--FILE-- ++notexisting()); ++} catch(Exception $e) { ++ var_dump($e->getMessage()); ++ var_dump(get_class($e)); ++} ++?> ++--EXPECTF-- ++string(%d) "%s" ++string(9) "SoapFault" +\ No newline at end of file +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-6837.patch b/SOURCES/php-5.6.5-CVE-2015-6837.patch new file mode 100644 index 0000000..3be1430 --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-6837.patch @@ -0,0 +1,42 @@ +Patch cleanup for 5.6.5 + +From 1744be2d17befc69bf00033993f4081852a747d6 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 16 Aug 2015 17:16:15 -0700 +Subject: [PATCH] Fix for bug #69782 + +--- + ext/xsl/xsltprocessor.c | 142 +++++++++++++++++++++++++----------------------- + 1 file changed, 73 insertions(+), 69 deletions(-) + +diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c +index 67c90f5..d21a8eb 100644 +--- a/ext/xsl/xsltprocessor.c ++++ b/ext/xsl/xsltprocessor.c +@@ -223,7 +223,9 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t + if (error == 1) { + for (i = nargs - 1; i >= 0; i--) { + obj = valuePop(ctxt); +- xmlXPathFreeObject(obj); ++ if (obj) { ++ xmlXPathFreeObject(obj); ++ } + } + return; + } +@@ -304,7 +306,9 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t + obj = valuePop(ctxt); +- if (obj->stringval == NULL) { +- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string"); +- xmlXPathFreeObject(obj); ++ if (obj == NULL || obj->stringval == NULL) { ++ if (obj) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string"); ++ xmlXPathFreeObject(obj); ++ } + valuePush(ctxt, xmlXPathNewString("")); + if (fci.param_count > 0) { + for (i = 0; i < nargs - 1; i++) { +-- +2.1.4 + diff --git a/SOURCES/php-5.6.5-CVE-2015-7803.patch b/SOURCES/php-5.6.5-CVE-2015-7803.patch new file mode 100644 index 0000000..e92065e --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-7803.patch @@ -0,0 +1,55 @@ +Patch cleanup for 5.6.5 +Binary diff removed + +From d698f0ae51f67c9cce870b09c59df3d6ba959244 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 28 Sep 2015 15:51:59 -0700 +Subject: [PATCH] Fix bug #69720: Null pointer dereference in + phar_get_fp_offset() + +--- + ext/phar/tests/bug69720.phar | Bin 0 -> 8192 bytes + ext/phar/tests/bug69720.phpt | 40 ++++++++++++++++++++++++++++++++++++++++ + ext/phar/util.c | 6 +++++- + 3 files changed, 45 insertions(+), 1 deletion(-) + create mode 100644 ext/phar/tests/bug69720.phar + create mode 100644 ext/phar/tests/bug69720.phpt + +diff --git a/ext/phar/util.c b/ext/phar/util.c +index 2c41adf..69da7b9 100644 +--- a/ext/phar/util.c ++++ b/ext/phar/util.c +@@ -494,7 +494,11 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char + (*ret)->is_tar = entry->is_tar; + (*ret)->fp = phar_get_efp(entry, 1 TSRMLS_CC); + if (entry->link) { +- (*ret)->zero = phar_get_fp_offset(phar_get_link_source(entry TSRMLS_CC) TSRMLS_CC); ++ phar_entry_info *link = phar_get_link_source(entry TSRMLS_CC); ++ if(!link) { ++ return FAILURE; ++ } ++ (*ret)->zero = phar_get_fp_offset(link TSRMLS_CC); + } else { + (*ret)->zero = phar_get_fp_offset(entry TSRMLS_CC); + } +From f98ab19dc0c978e3caaa2614579e4a61f2c317f5 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 28 Sep 2015 20:43:18 -0700 +Subject: [PATCH] fix memory leak + +--- + ext/phar/util.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ext/phar/util.c b/ext/phar/util.c +index 69da7b9..e7decda 100644 +--- a/ext/phar/util.c ++++ b/ext/phar/util.c +@@ -496,6 +496,7 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char + if (entry->link) { + phar_entry_info *link = phar_get_link_source(entry TSRMLS_CC); + if(!link) { ++ efree(*ret); + return FAILURE; + } + (*ret)->zero = phar_get_fp_offset(link TSRMLS_CC); diff --git a/SOURCES/php-5.6.5-CVE-2015-7804.patch b/SOURCES/php-5.6.5-CVE-2015-7804.patch new file mode 100644 index 0000000..4060535 --- /dev/null +++ b/SOURCES/php-5.6.5-CVE-2015-7804.patch @@ -0,0 +1,82 @@ +Patch cleanup for 5.6.5 +Binary diff removed + +From e78ac461dbefb7c4a3e9fde78d50fbc56b7b0183 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 28 Sep 2015 17:12:35 -0700 +Subject: [PATCH] FIx bug #70433 - Uninitialized pointer in phar_make_dirstream + when zip entry filename is "/" + +--- + ext/phar/dirstream.c | 2 +- + ext/phar/tests/bug70433.phpt | 23 +++++++++++++++++++++++ + ext/phar/tests/bug70433.zip | Bin 0 -> 264 bytes + 3 files changed, 24 insertions(+), 1 deletion(-) + create mode 100644 ext/phar/tests/bug70433.phpt + create mode 100755 ext/phar/tests/bug70433.zip + +diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c +index 75cf049..4728e29 100644 +--- a/ext/phar/dirstream.c ++++ b/ext/phar/dirstream.c +@@ -198,7 +198,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) + zend_hash_internal_pointer_reset(manifest); + + while (FAILURE != zend_hash_has_more_elements(manifest)) { +- if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &str_key, &keylen, &unused, 0, NULL)) { ++ if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(manifest, &str_key, &keylen, &unused, 0, NULL)) { + break; + } + +From 1ddf72180a52d247db88ea42a3e35f824a8fbda1 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 28 Sep 2015 21:37:26 -0700 +Subject: [PATCH] Better fix for bug #70433 + +--- + ext/phar/dirstream.c | 2 +- + ext/phar/util.c | 2 +- + ext/phar/zip.c | 4 +++- + 3 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c +index 4728e29..75cf049 100644 +--- a/ext/phar/dirstream.c ++++ b/ext/phar/dirstream.c +@@ -198,7 +198,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) + zend_hash_internal_pointer_reset(manifest); + + while (FAILURE != zend_hash_has_more_elements(manifest)) { +- if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(manifest, &str_key, &keylen, &unused, 0, NULL)) { ++ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &str_key, &keylen, &unused, 0, NULL)) { + break; + } + +diff --git a/ext/phar/util.c b/ext/phar/util.c +index e7decda..303daed 100644 +--- a/ext/phar/util.c ++++ b/ext/phar/util.c +@@ -1970,7 +1970,7 @@ void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int filename + + while ((s = zend_memrchr(filename, '/', filename_len))) { + filename_len = s - filename; +- if (FAILURE == zend_hash_add_empty_element(&phar->virtual_dirs, filename, filename_len)) { ++ if (!filename_len || FAILURE == zend_hash_add_empty_element(&phar->virtual_dirs, filename, filename_len)) { + break; + } + } +diff --git a/ext/phar/zip.c b/ext/phar/zip.c +index 142165c..e4883d3 100644 +--- a/ext/phar/zip.c ++++ b/ext/phar/zip.c +@@ -396,7 +396,9 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, + + if (entry.filename[entry.filename_len - 1] == '/') { + entry.is_dir = 1; +- entry.filename_len--; ++ if(entry.filename_len > 1) { ++ entry.filename_len--; ++ } + entry.flags |= PHAR_ENT_PERM_DEF_DIR; + } else { + entry.is_dir = 0; diff --git a/SPECS/php.spec b/SPECS/php.spec index 03fe3e0..9e103e9 100644 --- a/SPECS/php.spec +++ b/SPECS/php.spec @@ -111,7 +111,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: 5.6.5 -Release: 7%{?dist} +Release: 8%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -180,6 +180,18 @@ Patch151: php-5.6.5-CVE-2015-2783.patch Patch152: php-5.6.5-CVE-2015-3329.patch Patch153: php-5.6.5-bug68819.patch Patch154: php-5.6.5-bug69152.patch +Patch155: php-5.6.5-CVE-2015-5589.patch +Patch156: php-5.6.5-CVE-2015-5590.patch +Patch157: php-5.6.5-CVE-2015-6833.patch +Patch158: php-5.6.5-CVE-2015-7803.patch +Patch159: php-5.6.5-CVE-2015-7804.patch +Patch160: php-5.6.5-CVE-2015-6837.patch +Patch161: php-5.6.5-CVE-2015-6835.patch +Patch162: php-5.6.5-CVE-2015-6834-1.patch +Patch163: php-5.6.5-CVE-2015-6832.patch +Patch164: php-5.6.5-CVE-2015-6831.patch +Patch165: php-5.6.5-CVE-2015-6834-2.patch +Patch166: php-5.6.5-CVE-2015-6836.patch # Fixes for tests (300+) @@ -769,6 +781,18 @@ support for using the enchant library to PHP. %patch152 -p1 -b .cve3329 %patch153 -p1 -b .bug68819 %patch154 -p1 -b .bug69152 +%patch155 -p1 -b .cve5589 +%patch156 -p1 -b .cve5590 +%patch157 -p1 -b .cve6833 +%patch158 -p1 -b .cve7803 +%patch159 -p1 -b .cve7804 +%patch160 -p1 -b .cve6837 +%patch161 -p1 -b .cve6835 +%patch162 -p1 -b .cve6834 +%patch163 -p1 -b .cve6832 +%patch164 -p1 -b .cve6831 +%patch165 -p1 -b .cve6834 +%patch166 -p1 -b .cve6836 # Fixes for tests %patch300 -p1 -b .datetests @@ -1691,6 +1715,30 @@ fi %changelog +* Mon Feb 15 2016 Remi Collet - 5.6.5-8 +- Phar: fix segmentation fault in Phar::convertToData on + invalid file CVE-2015-5589 +- Phar: fix buffer overflow and stack smashing error in + phar_fix_filepath CVE-2015-5590 +- Phar: fix files from archive can be extracted outside of + destination directory using phar CVE-2015-6833 +- Phar: NULL pointer dereference in phar_get_fp_offset() + CVE-2015-7803 +- Phar: uninitialized pointer in phar_make_dirstream() + CVE-2015-7804 +- Xslt: fix NULL pointer dereference in XSLTProcessor class + CVE-2015-6837 CVE-2015-6838 +- Core: fix use-after-free vulnerability in session + deserializer CVE-2015-6835 +- Core: fix multiple unserialization use-after-free issues + CVE-2015-6834 +- Spl: fix dangling pointer in the unserialization of + ArrayObject items CVE-2015-6832 +- Spl: fix Use After Free Vulnerability in unserialize() + CVE-2015-6831 +- Soap: fix type confusion in SOAP serialize_function_call() + CVE-2015-6836 + * Wed Jun 10 2015 Remi Collet - 5.6.5-7 - fix more functions accept paths with NUL character #1213407