diff -r 7665830787a5 -r 4e8085696007 components/php-5_3/php-sapi/patches/261_php_20936509.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/php-5_3/php-sapi/patches/261_php_20936509.patch Wed Jun 17 15:47:38 2015 -0700 @@ -0,0 +1,174 @@ +CVE-2015-2783 +Community BUG: +https://bugs.php.net/bug.php?id=69324 +Community CODE: +http://git.php.net/?p=php-src.git;a=commit;h=9faaee66fa493372c7340b1ab05f8fd115131a42 +Below is the community patch. + +Not including the test files at the moment: +ext/phar/tests/bug69324.phar +ext/phar/tests/bug69324.phpt +because our version of gpatch doesn't understand the git binary data file. + + + +From 9faaee66fa493372c7340b1ab05f8fd115131a42 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 5 Apr 2015 15:07:36 -0700 +Subject: [PATCH] Fixed bug #69324 (Buffer Over-read in unserialize when + parsing Phar) + +--- + ext/phar/phar.c | 65 ++++++++++++++++++++----------------------- + ext/phar/phar_internal.h | 2 +- + ext/phar/tests/bug69324.phar | Bin 0 -> 269 bytes + ext/phar/tests/bug69324.phpt | 17 +++++++++++ + 4 files changed, 48 insertions(+), 36 deletions(-) + create mode 100644 ext/phar/tests/bug69324.phar + create mode 100644 ext/phar/tests/bug69324.phpt + +diff --git a/ext/phar/phar.c b/ext/phar/phar.c +index ec82351..bf0c985 100644 +--- a/ext/phar/phar.c ++++ b/ext/phar/phar.c +@@ -603,25 +603,18 @@ int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len + * + * data is the serialized zval + */ +-int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC) /* {{{ */ ++int phar_parse_metadata(char **buffer, zval **metadata, php_uint32 zip_metadata_len TSRMLS_DC) /* {{{ */ + { + const unsigned char *p; +- php_uint32 buf_len; + php_unserialize_data_t var_hash; + +- if (!zip_metadata_len) { +- PHAR_GET_32(*buffer, buf_len); +- } else { +- buf_len = zip_metadata_len; +- } +- +- if (buf_len) { ++ if (zip_metadata_len) { + ALLOC_ZVAL(*metadata); + INIT_ZVAL(**metadata); + p = (const unsigned char*) *buffer; + PHP_VAR_UNSERIALIZE_INIT(var_hash); + +- if (!php_var_unserialize(metadata, &p, p + buf_len, &var_hash TSRMLS_CC)) { ++ if (!php_var_unserialize(metadata, &p, p + zip_metadata_len, &var_hash TSRMLS_CC)) { + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + zval_ptr_dtor(metadata); + *metadata = NULL; +@@ -633,19 +626,14 @@ int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSR + if (PHAR_G(persist)) { + /* lazy init metadata */ + zval_ptr_dtor(metadata); +- *metadata = (zval *) pemalloc(buf_len, 1); +- memcpy(*metadata, *buffer, buf_len); +- *buffer += buf_len; ++ *metadata = (zval *) pemalloc(zip_metadata_len, 1); ++ memcpy(*metadata, *buffer, zip_metadata_len); + return SUCCESS; + } + } else { + *metadata = NULL; + } + +- if (!zip_metadata_len) { +- *buffer += buf_len; +- } +- + return SUCCESS; + } + /* }}}*/ +@@ -666,6 +654,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char + phar_entry_info entry; + php_uint32 manifest_len, manifest_count, manifest_flags, manifest_index, tmp_len, sig_flags; + php_uint16 manifest_ver; ++ php_uint32 len; + long offset; + int sig_len, register_alias = 0, temp_alias = 0; + char *signature = NULL; +@@ -1031,16 +1020,21 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char + mydata->is_persistent = PHAR_G(persist); + + /* check whether we have meta data, zero check works regardless of byte order */ ++ PHAR_GET_32(buffer, len); + if (mydata->is_persistent) { +- PHAR_GET_32(buffer, mydata->metadata_len); +- if (phar_parse_metadata(&buffer, &mydata->metadata, mydata->metadata_len TSRMLS_CC) == FAILURE) { +- MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\""); +- } +- } else { +- if (phar_parse_metadata(&buffer, &mydata->metadata, 0 TSRMLS_CC) == FAILURE) { +- MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\""); ++ mydata->metadata_len = len; ++ if(!len) { ++ /* FIXME: not sure why this is needed but removing it breaks tests */ ++ PHAR_GET_32(buffer, len); + } + } ++ if(len > endbuffer - buffer) { ++ MAPPHAR_FAIL("internal corruption of phar \"%s\" (trying to read past buffer end)"); ++ } ++ if (phar_parse_metadata(&buffer, &mydata->metadata, len TSRMLS_CC) == FAILURE) { ++ MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\""); ++ } ++ buffer += len; + + /* set up our manifest */ + zend_hash_init(&mydata->manifest, manifest_count, +@@ -1075,7 +1069,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char + entry.manifest_pos = manifest_index; + } + +- if (buffer + entry.filename_len + 20 > endbuffer) { ++ if (entry.filename_len + 20 > endbuffer - buffer) { + MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest entry)"); + } + +@@ -1111,19 +1105,20 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char + entry.flags |= PHAR_ENT_PERM_DEF_DIR; + } + ++ PHAR_GET_32(buffer, len); + if (entry.is_persistent) { +- PHAR_GET_32(buffer, entry.metadata_len); +- if (!entry.metadata_len) buffer -= 4; +- if (phar_parse_metadata(&buffer, &entry.metadata, entry.metadata_len TSRMLS_CC) == FAILURE) { +- pefree(entry.filename, entry.is_persistent); +- MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\""); +- } ++ entry.metadata_len = len; + } else { +- if (phar_parse_metadata(&buffer, &entry.metadata, 0 TSRMLS_CC) == FAILURE) { +- pefree(entry.filename, entry.is_persistent); +- MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\""); +- } ++ entry.metadata_len = 0; ++ } ++ if (len > endbuffer - buffer) { ++ MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest entry)"); ++ } ++ if (phar_parse_metadata(&buffer, &entry.metadata, len TSRMLS_CC) == FAILURE) { ++ pefree(entry.filename, entry.is_persistent); ++ MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\""); + } ++ buffer += len; + + entry.offset = entry.offset_abs = offset; + offset += entry.compressed_filesize; +diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h +index c9306c1..fcfc864 100644 +--- a/ext/phar/phar_internal.h ++++ b/ext/phar/phar_internal.h +@@ -654,7 +654,7 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, + char *phar_find_in_include_path(char *file, int file_len, phar_archive_data **pphar TSRMLS_DC); + char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC); + phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC); +-int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC); ++int phar_parse_metadata(char **buffer, zval **metadata, php_uint32 zip_metadata_len TSRMLS_DC); + void destroy_phar_manifest_entry(void *pDest); + int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position, int follow_links TSRMLS_DC); + php_stream *phar_get_efp(phar_entry_info *entry, int follow_links TSRMLS_DC);