From aee6344e2469dd0d896a79ae963d4a95d52f47e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Wed, 25 Dec 2013 17:00:32 +0100 Subject: Add ZEND_ARG_CALLABLE_INFO to allow internal function to type hint against callable. --- Zend/zend_API.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 84acfcac88..17672ffc99 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -101,6 +101,7 @@ typedef struct _zend_fcall_info_cache { #define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref}, #define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref}, #define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, allow_null, pass_by_ref}, +#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_CALLABLE, allow_null, pass_by_ref }, #define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref}, #define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref}, #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ -- cgit v1.2.1 From 75f40ae1f3a7ca837d230f099627d121f9b3a32f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 27 Mar 2015 18:40:58 +0300 Subject: Fixed bug #69293 --- ext/soap/php_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 31f1f7c800..13be2a5326 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -464,7 +464,7 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml xmlNodeSetName(node, BAD_CAST(Z_STRVAL_PP(zname))); } if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS && - Z_TYPE_PP(zname) == IS_STRING) { + Z_TYPE_PP(znamens) == IS_STRING) { xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens)); xmlSetNs(node, nsp); } -- cgit v1.2.1 From caecd88237f260c78428feb0acc6578618fa231b Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 1 Apr 2015 23:43:33 -0700 Subject: Revert "Merge branch 'PHP-5.4' of https://git.php.net/repository/php-src into PHP-5.4" This reverts commit fe0ca2745f00940a27bfc8e87db534541a19af70, reversing changes made to 968fbc6acf0bc27be17c0209be7f966e89a55943. --- Zend/zend_API.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 17672ffc99..84acfcac88 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -101,7 +101,6 @@ typedef struct _zend_fcall_info_cache { #define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref}, #define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref}, #define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, allow_null, pass_by_ref}, -#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_CALLABLE, allow_null, pass_by_ref }, #define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref}, #define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref}, #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ -- cgit v1.2.1 From afbf725e7380dfb3ff43a993e43abd9759a66c2b Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Sat, 13 Dec 2014 09:03:44 +0100 Subject: Fix bug #68601 buffer read overflow in gd_gif_in.c --- NEWS | 3 +++ ext/gd/libgd/gd_gif_in.c | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 365615418d..7596b002aa 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2015 PHP 5.4.40 +- GD: + . Fixed bug #68601 (buffer read overflow in gd_gif_in.c). (Remi) + - SOAP: . Fixed bug #69152 (Type Confusion Infoleak Vulnerability in unserialize() with SoapFault). (Dmitry) diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index ee88a2fc8e..491e9422db 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -72,8 +72,10 @@ static struct { #define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) +#define CSD_BUF_SIZE 280 + typedef struct { - unsigned char buf[280]; + unsigned char buf[CSD_BUF_SIZE]; int curbit, lastbit, done, last_byte; } CODE_STATIC_DATA; @@ -400,7 +402,12 @@ GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroD ret = 0; for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) - ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + if (i < CSD_BUF_SIZE * 8) { + ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j; + } else { + ret = -1; + break; + } scd->curbit += code_size; return ret; -- cgit v1.2.1 From bd31cb756399101234258c5491443531099957c3 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 17 Dec 2014 10:59:36 +0100 Subject: Better fix for #68601 for perf https://bitbucket.org/libgd/gd-libgd/commits/81e9a993f2893d651d225646378e3fd1b7465467 --- ext/gd/libgd/gd_gif_in.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index 491e9422db..f41ec8460a 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -400,14 +400,14 @@ GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroD scd->lastbit = (2+count)*8 ; } - ret = 0; - for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) - if (i < CSD_BUF_SIZE * 8) { + if ((scd->curbit + code_size - 1) >= (CSD_BUF_SIZE * 8)) { + ret = -1; + } else { + ret = 0; + for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) { ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j; - } else { - ret = -1; - break; } + } scd->curbit += code_size; return ret; -- cgit v1.2.1 From 5ae20c624781bdd39ba14b2f856234c168f7ea38 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 5 Apr 2015 22:27:02 -0700 Subject: Fix bug #66550 (SQLite prepared statement use-after-free) --- NEWS | 3 +++ ext/sqlite3/sqlite3.c | 16 ++++++++++++++++ ext/sqlite3/tests/bug66550.phpt | 23 +++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 ext/sqlite3/tests/bug66550.phpt diff --git a/NEWS b/NEWS index 7596b002aa..f8f046c056 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,9 @@ PHP NEWS . Fixed bug #69152 (Type Confusion Infoleak Vulnerability in unserialize() with SoapFault). (Dmitry) +- Sqlite3: + . Fixed bug #66550 (SQLite prepared statement use-after-free). (Sean Heelan) + - Postgres: . Fixed bug #68741 (Null pointer deference) (CVE-2015-1352). (Xinchen Hui) diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 21e5634453..f013d6054a 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1274,6 +1274,8 @@ PHP_METHOD(sqlite3stmt, paramCount) php_sqlite3_stmt *stmt_obj; zval *object = getThis(); stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) if (zend_parse_parameters_none() == FAILURE) { return; @@ -1290,6 +1292,8 @@ PHP_METHOD(sqlite3stmt, close) php_sqlite3_stmt *stmt_obj; zval *object = getThis(); stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) if (zend_parse_parameters_none() == FAILURE) { return; @@ -1308,6 +1312,8 @@ PHP_METHOD(sqlite3stmt, reset) php_sqlite3_stmt *stmt_obj; zval *object = getThis(); stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) if (zend_parse_parameters_none() == FAILURE) { return; @@ -1328,6 +1334,8 @@ PHP_METHOD(sqlite3stmt, clear) php_sqlite3_stmt *stmt_obj; zval *object = getThis(); stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) if (zend_parse_parameters_none() == FAILURE) { return; @@ -1349,6 +1357,8 @@ PHP_METHOD(sqlite3stmt, readOnly) php_sqlite3_stmt *stmt_obj; zval *object = getThis(); stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) if (zend_parse_parameters_none() == FAILURE) { return; @@ -1416,6 +1426,8 @@ PHP_METHOD(sqlite3stmt, bindParam) zval *object = getThis(); struct php_sqlite3_bound_param param = {0}; stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) param.param_number = -1; param.type = SQLITE3_TEXT; @@ -1447,6 +1459,8 @@ PHP_METHOD(sqlite3stmt, bindValue) zval *object = getThis(); struct php_sqlite3_bound_param param = {0}; stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) param.param_number = -1; param.type = SQLITE3_TEXT; @@ -1482,6 +1496,8 @@ PHP_METHOD(sqlite3stmt, execute) stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); + SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) + if (zend_parse_parameters_none() == FAILURE) { return; } diff --git a/ext/sqlite3/tests/bug66550.phpt b/ext/sqlite3/tests/bug66550.phpt new file mode 100644 index 0000000000..a44515b0d9 --- /dev/null +++ b/ext/sqlite3/tests/bug66550.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #66550 (SQLite prepared statement use-after-free) +--SKIPIF-- + +--FILE-- +exec('CREATE TABLE foo (id INTEGER, bar STRING)'); + +$stmt = $db->prepare('SELECT bar FROM foo WHERE id=:id'); +// Close the database connection and free the internal sqlite3_stmt object +$db->close(); +// Access the sqlite3_stmt object via the php_sqlite3_stmt container +$stmt->reset(); +?> +==DONE== +--EXPECTF-- +Warning: SQLite3Stmt::reset(): The SQLite3 object has not been correctly initialised in %s +==DONE== -- cgit v1.2.1 From 9a404df382d041127eaa601b3113587df45d510d Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 1 Apr 2015 00:41:46 +0300 Subject: Fixed bug #68740 (NULL Pointer Dereference) (cherry picked from commit 124fb22a13fafa3648e4e15b4f207c7096d8155e) --- NEWS | 3 +++ ext/ereg/regex/regcomp.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/NEWS b/NEWS index f8f046c056..0a83818e2e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2015 PHP 5.4.40 +- Ereg: + . Fixed bug #68740 (NULL Pointer Dereference). (Laruence) + - GD: . Fixed bug #68601 (buffer read overflow in gd_gif_in.c). (Remi) diff --git a/ext/ereg/regex/regcomp.c b/ext/ereg/regex/regcomp.c index f4bfc1c167..c2223d7dbe 100644 --- a/ext/ereg/regex/regcomp.c +++ b/ext/ereg/regex/regcomp.c @@ -1284,6 +1284,10 @@ int c; register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; register unsigned uc = (unsigned char)c; + if (!g->setbits) { + return(0); + } + for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) if (col[uc] != 0) return(1); -- cgit v1.2.1 From 920a0afbf8f83962c70aaf9a144810f320be92b3 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 29 Jan 2015 00:00:09 +0800 Subject: Fixed bug #68901 (use after free) --- NEWS | 3 +++ ext/phar/phar_object.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 0a83818e2e..584defdc4e 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,9 @@ PHP NEWS - Sqlite3: . Fixed bug #66550 (SQLite prepared statement use-after-free). (Sean Heelan) +- Phar: + . Fixed bug #68901 (use after free). (bugreports at internot dot info) + - Postgres: . Fixed bug #68741 (Null pointer deference) (CVE-2015-1352). (Xinchen Hui) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index a021200fda..add1fa0d5c 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2211,8 +2211,8 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c } its_ok: if (SUCCESS == php_stream_stat_path(newpath, &ssb)) { - efree(oldpath); zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "phar \"%s\" exists and must be unlinked prior to conversion", newpath); + efree(oldpath); return NULL; } if (!phar->is_data) { -- cgit v1.2.1 From f938112c495b0d26572435c0be73ac0bfe642ecd Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 4 Apr 2015 15:01:37 -0700 Subject: Fix bug #68819 (Fileinfo on specific file causes spurious OOM and/or segfault) --- ext/fileinfo/libmagic/softmagic.c | 3 +++ ext/fileinfo/tests/bug68819_001.phpt | 18 ++++++++++++++++++ ext/fileinfo/tests/bug68819_002.phpt | 26 ++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 ext/fileinfo/tests/bug68819_001.phpt create mode 100644 ext/fileinfo/tests/bug68819_002.phpt diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index e7b7855eef..54c1a03ef7 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -1037,6 +1037,9 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, if (bytecnt > nbytes) { bytecnt = nbytes; } + if (offset > bytecnt) { + offset = bytecnt; + } if (s == NULL) { ms->search.s_len = 0; ms->search.s = NULL; diff --git a/ext/fileinfo/tests/bug68819_001.phpt b/ext/fileinfo/tests/bug68819_001.phpt new file mode 100644 index 0000000000..ce39ee61db --- /dev/null +++ b/ext/fileinfo/tests/bug68819_001.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #68819 Fileinfo on specific file causes spurious OOM and/or segfault, var 1 +--SKIPIF-- + +--FILE-- +buffer($string); + +var_dump($type); +?> +--EXPECT-- +string(60) "ASCII text, with very long lines, with CRLF line terminators" diff --git a/ext/fileinfo/tests/bug68819_002.phpt b/ext/fileinfo/tests/bug68819_002.phpt new file mode 100644 index 0000000000..cec238d63e --- /dev/null +++ b/ext/fileinfo/tests/bug68819_002.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #68819 Fileinfo on specific file causes spurious OOM and/or segfault, var 2 +--SKIPIF-- + +--FILE-- + 8192 +$string .= str_repeat(chr(rand(32, 127)), 8184); + +// Ending in this string +$string .= "say"; + +$finfo = new finfo(); +$type = $finfo->buffer($string); +var_dump($type); + +?> +--EXPECT-- +string(60) "ASCII text, with very long lines, with CRLF line terminators" -- cgit v1.2.1 From 809610f5ea38a83b284e1125d1fff129bdd615e7 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 4 Apr 2015 15:03:46 -0700 Subject: Fix bug #68486 and bug #69218 (segfault in apache2handler with apache 2.4) --- sapi/apache2handler/sapi_apache2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index e97f11c69b..cfebc5f5c6 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -688,6 +688,7 @@ zend_first_try { } zend_end_try(); } apr_brigade_cleanup(brigade); + apr_pool_cleanup_run(r->pool, (void *)&SG(server_context), php_server_context_cleanup); } else { ctx->r = parent_req; } -- cgit v1.2.1 From 0ea75af9be8a40836951fc89f723dd5390b8b46f Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 4 Apr 2015 15:58:27 -0700 Subject: Fixed bug #69316 (Use-after-free in php_curl related to CURLOPT_FILE/_INFILE/_WRITEHEADER) --- ext/curl/interface.c | 4 ++++ ext/curl/tests/bug69316.phpt | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 ext/curl/tests/bug69316.phpt diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 0423f71f9a..7f8f276791 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1051,6 +1051,7 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_WRITEFUNCTION"); length = -1; } else if (retval_ptr) { + _php_curl_verify_handlers(ch, 1 TSRMLS_CC); if (Z_TYPE_P(retval_ptr) != IS_LONG) { convert_to_long_ex(&retval_ptr); } @@ -1124,6 +1125,7 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double if (error == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION"); } else if (retval_ptr) { + _php_curl_verify_handlers(ch, 1 TSRMLS_CC); if (Z_TYPE_P(retval_ptr) != IS_LONG) { convert_to_long_ex(&retval_ptr); } @@ -1200,6 +1202,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) length = CURL_READFUNC_ABORT; #endif } else if (retval_ptr) { + _php_curl_verify_handlers(ch, 1 TSRMLS_CC); if (Z_TYPE_P(retval_ptr) == IS_STRING) { length = MIN((int) (size * nmemb), Z_STRLEN_P(retval_ptr)); memcpy(data, Z_STRVAL_P(retval_ptr), length); @@ -1274,6 +1277,7 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_HEADERFUNCTION"); length = -1; } else if (retval_ptr) { + _php_curl_verify_handlers(ch, 1 TSRMLS_CC); if (Z_TYPE_P(retval_ptr) != IS_LONG) { convert_to_long_ex(&retval_ptr); } diff --git a/ext/curl/tests/bug69316.phpt b/ext/curl/tests/bug69316.phpt new file mode 100644 index 0000000000..2a88eb2bc9 --- /dev/null +++ b/ext/curl/tests/bug69316.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #69316: Use-after-free in php_curl related to CURLOPT_FILE/_INFILE/_WRITEHEADER +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: curl_exec(): CURLOPT_FILE resource has gone away, resetting to default in %s on line %d +===DONE=== -- cgit v1.2.1 From 9faaee66fa493372c7340b1ab05f8fd115131a42 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 5 Apr 2015 15:07:36 -0700 Subject: 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 ec82351410..bf0c985a7c 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 c9306c15f4..fcfc86457d 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); diff --git a/ext/phar/tests/bug69324.phar b/ext/phar/tests/bug69324.phar new file mode 100644 index 0000000000..0882d88c22 Binary files /dev/null and b/ext/phar/tests/bug69324.phar differ diff --git a/ext/phar/tests/bug69324.phpt b/ext/phar/tests/bug69324.phpt new file mode 100644 index 0000000000..70e3f972e7 --- /dev/null +++ b/ext/phar/tests/bug69324.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #69324: Buffer Over-read in unserialize when parsing Phar +--SKIPIF-- + +--FILE-- +getMetadata(); +var_dump($meta); +} catch(Exception $e) { + echo $e->getMessage(); +} +--EXPECTF-- +internal corruption of phar "%s" (truncated manifest entry) \ No newline at end of file -- cgit v1.2.1 From 4435b9142ff9813845d5c97ab29a5d637bedb257 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 5 Apr 2015 16:01:24 -0700 Subject: Fixed bug #69353 (Missing null byte checks for paths in various PHP extensions) --- ext/dom/document.c | 5 ++++- ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt | 5 +++++ ext/fileinfo/fileinfo.c | 5 +++++ ext/fileinfo/tests/finfo_file_basic.phpt | 4 ++++ ext/gd/gd.c | 8 ++++---- ext/hash/hash.c | 7 ++++++- ext/hash/tests/hash_hmac_file_error.phpt | 7 +++++++ ext/pgsql/pgsql.c | 2 +- ext/standard/link.c | 2 +- ext/standard/streamsfuncs.c | 2 +- ext/xmlwriter/php_xmlwriter.c | 4 ++-- ext/zlib/zlib.c | 4 ++-- 12 files changed, 42 insertions(+), 13 deletions(-) diff --git a/ext/dom/document.c b/ext/dom/document.c index f105f6d7fe..4666746ad2 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1580,6 +1580,9 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int sourc xmlInitParser(); if (mode == DOM_LOAD_FILE) { + if (CHECK_NULL_PATH(source, source_len)) { + return NULL; + } char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC); if (file_dest) { ctxt = xmlCreateFileParserCtxt(file_dest); @@ -2168,7 +2171,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ id = getThis(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &source, &source_len, &options) == FAILURE) { return; } diff --git a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt index e59ff56c5a..75004e2a74 100644 --- a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt +++ b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt @@ -13,6 +13,11 @@ assert.bail=true $doc = new DOMDocument(); $result = $doc->loadHTMLFile(""); assert('$result === false'); +$doc = new DOMDocument(); +$result = $doc->loadHTMLFile("text.html\0something"); +assert('$result === null'); ?> --EXPECTF-- %r(PHP ){0,1}%rWarning: DOMDocument::loadHTMLFile(): Empty string supplied as input %s + +%r(PHP ){0,1}%rWarning: DOMDocument::loadHTMLFile() expects parameter 1 to be a valid path, string given %s diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 2d523ab498..5fd9511745 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -506,6 +506,11 @@ static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mime RETVAL_FALSE; goto clean; } + if (CHECK_NULL_PATH(buffer, buffer_len)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path"); + RETVAL_FALSE; + goto clean; + } wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0 TSRMLS_CC); diff --git a/ext/fileinfo/tests/finfo_file_basic.phpt b/ext/fileinfo/tests/finfo_file_basic.phpt index 20223fd88e..ee70e2e253 100644 --- a/ext/fileinfo/tests/finfo_file_basic.phpt +++ b/ext/fileinfo/tests/finfo_file_basic.phpt @@ -19,6 +19,7 @@ echo "*** Testing finfo_file() : basic functionality ***\n"; var_dump( finfo_file( $finfo, __FILE__) ); var_dump( finfo_file( $finfo, __FILE__, FILEINFO_CONTINUE ) ); var_dump( finfo_file( $finfo, $magicFile ) ); +var_dump( finfo_file( $finfo, $magicFile.chr(0).$magicFile) ); ?> ===DONE=== @@ -27,4 +28,7 @@ var_dump( finfo_file( $finfo, $magicFile ) ); string(28) "text/x-php; charset=us-ascii" string(22) "PHP script, ASCII text" string(25) "text/plain; charset=utf-8" + +Warning: finfo_file(): Invalid path in %s/finfo_file_basic.php on line %d +bool(false) ===DONE=== diff --git a/ext/gd/gd.c b/ext/gd/gd.c index e5657f7424..d258c3dbc7 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -1495,7 +1495,7 @@ PHP_FUNCTION(imageloadfont) gdFontPtr font; php_stream *stream; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_name) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &file, &file_name) == FAILURE) { return; } @@ -2438,7 +2438,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, long ignore_warning; #endif if (image_type == PHP_GDIMG_TYPE_GD2PART) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll", &file, &file_len, &srcx, &srcy, &width, &height) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pllll", &file, &file_len, &srcx, &srcy, &width, &height) == FAILURE) { return; } if (width < 1 || height < 1) { @@ -2446,7 +2446,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, RETURN_FALSE; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &file, &file_len) == FAILURE) { return; } } @@ -4178,7 +4178,7 @@ PHP_FUNCTION(imagepsencodefont) char *enc, **enc_vector; int enc_len, *f_ind; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &fnt, &enc, &enc_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &fnt, &enc, &enc_len) == FAILURE) { return; } diff --git a/ext/hash/hash.c b/ext/hash/hash.c index bd9dcca59f..f5988c9c66 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -142,6 +142,7 @@ static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_ } if (isfilename) { if (CHECK_NULL_PATH(data, data_len)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path"); RETURN_FALSE; } stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT); @@ -222,6 +223,10 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename, RETURN_FALSE; } if (isfilename) { + if (CHECK_NULL_PATH(data, data_len)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path"); + RETURN_FALSE; + } stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT); if (!stream) { /* Stream will report errors opening file */ @@ -449,7 +454,7 @@ PHP_FUNCTION(hash_update_file) char *filename, buf[1024]; int filename_len, n; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) { return; } diff --git a/ext/hash/tests/hash_hmac_file_error.phpt b/ext/hash/tests/hash_hmac_file_error.phpt index 42ab122285..26ba8aacbe 100644 --- a/ext/hash/tests/hash_hmac_file_error.phpt +++ b/ext/hash/tests/hash_hmac_file_error.phpt @@ -28,6 +28,9 @@ hash_hmac_file('crc32', $file, $key, TRUE, $extra_arg); echo "\n-- Testing hash_hmac_file() function with invalid hash algorithm --\n"; hash_hmac_file('foo', $file, $key, TRUE); +echo "\n-- Testing hash_hmac_file() function with bad path --\n"; +hash_hmac_file('crc32', $file.chr(0).$file, $key, TRUE); + ?> ===Done=== --EXPECTF-- @@ -51,4 +54,8 @@ Warning: hash_hmac_file() expects at most 4 parameters, 5 given in %s on line %d -- Testing hash_hmac_file() function with invalid hash algorithm -- Warning: hash_hmac_file(): Unknown hashing algorithm: foo in %s on line %d + +-- Testing hash_hmac_file() function with bad path -- + +Warning: hash_hmac_file(): Invalid path in %s on line %d ===Done=== \ No newline at end of file diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index eb55777758..cd51143c90 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -3014,7 +3014,7 @@ PHP_FUNCTION(pg_trace) php_stream *stream; id = PGG(default_link); - if (zend_parse_parameters(argc TSRMLS_CC, "s|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "p|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) { return; } diff --git a/ext/standard/link.c b/ext/standard/link.c index c57484e766..686dd3e306 100644 --- a/ext/standard/link.c +++ b/ext/standard/link.c @@ -59,7 +59,7 @@ PHP_FUNCTION(readlink) char buff[MAXPATHLEN]; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &link, &link_len) == FAILURE) { return; } diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index b1b318044e..b8f15e32c2 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1549,7 +1549,7 @@ PHP_FUNCTION(stream_resolve_include_path) char *filename, *resolved_path; int filename_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { return; } diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index 7bc35dabc4..acb87541d8 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -1738,7 +1738,7 @@ static PHP_FUNCTION(xmlwriter_write_dtd_entity) /* }}} */ #endif -/* {{{ proto resource xmlwriter_open_uri(resource xmlwriter, string source) +/* {{{ proto resource xmlwriter_open_uri(string source) Create new xmlwriter using source uri for output */ static PHP_FUNCTION(xmlwriter_open_uri) { @@ -1759,7 +1759,7 @@ static PHP_FUNCTION(xmlwriter_open_uri) void *ioctx; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &source, &source_len) == FAILURE) { return; } diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 705fb5dd5f..431dfde547 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -581,7 +581,7 @@ static PHP_FUNCTION(gzopen) php_stream *stream; long use_include_path = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) { return; } @@ -609,7 +609,7 @@ static PHP_FUNCTION(readgzfile) int size; long use_include_path = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &use_include_path) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &use_include_path) == FAILURE) { return; } -- cgit v1.2.1 From a894a8155fab068d68a04bf181dbaddfa01ccbb0 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 5 Apr 2015 17:30:59 -0700 Subject: More fixes for bug #69152 --- Zend/zend_exceptions.c | 3 +++ ext/standard/tests/serialize/bug69152.phpt | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 ext/standard/tests/serialize/bug69152.phpt diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index bf90ae7be3..1ca2eadbf4 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -591,6 +591,9 @@ ZEND_METHOD(exception, getTraceAsString) str = &res; trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC); + if(Z_TYPE_P(trace) != IS_ARRAY) { + RETURN_FALSE; + } zend_hash_apply_with_arguments(Z_ARRVAL_P(trace) TSRMLS_CC, (apply_func_args_t)_build_trace_string, 3, str, len, &num); s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 7 + 1); diff --git a/ext/standard/tests/serialize/bug69152.phpt b/ext/standard/tests/serialize/bug69152.phpt new file mode 100644 index 0000000000..4e741685cc --- /dev/null +++ b/ext/standard/tests/serialize/bug69152.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #69152: Type Confusion Infoleak Vulnerability in unserialize() +--FILE-- +test(); + +?> +--EXPECTF-- +exception 'Exception' in %s:%d +Stack trace: +#0 {main} + +Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "unknown" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in %s on line %d -- cgit v1.2.1 From 12d3bdee3dfa6605024a72080d8a17c165c5ed24 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 11 Apr 2015 16:42:16 -0700 Subject: Additional fix for bug #69324 Not so happy about duplication but needed due to bug #69429 --- ext/phar/phar.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index bf0c985a7c..c5c8b467bc 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -600,27 +600,28 @@ int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len * * Meta-data is in this format: * [len32][data...] - * + * * data is the serialized zval */ int phar_parse_metadata(char **buffer, zval **metadata, php_uint32 zip_metadata_len TSRMLS_DC) /* {{{ */ { - const unsigned char *p; php_unserialize_data_t var_hash; if (zip_metadata_len) { + const unsigned char *p, *p_buff = estrndup(*buffer, zip_metadata_len); + p = p_buff; ALLOC_ZVAL(*metadata); INIT_ZVAL(**metadata); - p = (const unsigned char*) *buffer; PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(metadata, &p, p + zip_metadata_len, &var_hash TSRMLS_CC)) { + efree(p_buff); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); zval_ptr_dtor(metadata); *metadata = NULL; return FAILURE; } - + efree(p_buff); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); if (PHAR_G(persist)) { @@ -643,7 +644,7 @@ int phar_parse_metadata(char **buffer, zval **metadata, php_uint32 zip_metadata_ * * Parse a new one and add it to the cache, returning either SUCCESS or * FAILURE, and setting pphar to the pointer to the manifest entry - * + * * This is used by phar_open_from_filename to process the manifest, but can be called * directly. */ @@ -2236,7 +2237,7 @@ last_time: /** * Process a phar stream name, ensuring we can handle any of: - * + * * - whatever.phar * - whatever.phar.gz * - whatever.phar.bz2 -- cgit v1.2.1