From a8f2f28972795631274d2e2206e4a80779c9bf08 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 5 Jan 2021 10:37:01 +0100 Subject: [PATCH 1/2] Prevent double-free of Phar ZIP stream We must not alias the closed stream to `phar_archive_data.fp`. --- ext/phar/zip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 1b94943ad302e..09cd6c1cab2cc 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -665,8 +665,6 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia zend_hash_str_add_mem(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry, sizeof(phar_entry_info)); } - mydata->fp = fp; - if (zend_hash_str_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) { mydata->is_data = 0; } else { @@ -683,6 +681,8 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia return FAILURE; } + mydata->fp = fp; + zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len, mydata); if (actual_alias) { From e4357a3d6ba2fdd18d0afb68d4f6335b6d7cef0c Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 5 Jan 2021 12:52:00 +0100 Subject: [PATCH 2/2] Use PHAR_ZIP_FAIL() --- ext/phar/tests/zip/require_hash.phpt | 2 +- ext/phar/zip.c | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/ext/phar/tests/zip/require_hash.phpt b/ext/phar/tests/zip/require_hash.phpt index 23943550ae33b..994cc0eb676a4 100644 --- a/ext/phar/tests/zip/require_hash.phpt +++ b/ext/phar/tests/zip/require_hash.phpt @@ -45,7 +45,7 @@ try { @unlink(__DIR__ . '/require_hash.zip'); ?> --EXPECTF-- -zip-based phar "%srequire_hash.phar.zip" does not have a signature +phar error: signature is missing in zip-based phar "%srequire_hash.phar.zip" bool(false) array(2) { ["hash"]=> diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 09cd6c1cab2cc..f3aef85cd9a43 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -673,12 +673,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia /* ensure signature set */ if (!mydata->is_data && PHAR_G(require_hash) && !mydata->signature) { - php_stream_close(fp); - phar_destroy_phar_data(mydata); - if (error) { - spprintf(error, 0, "zip-based phar \"%s\" does not have a signature", fname); - } - return FAILURE; + PHAR_ZIP_FAIL("signature is missing"); } mydata->fp = fp;