From 77fce88b418f0d088842a292a34eefed6f7824ae Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 30 Sep 2021 13:52:56 +0200 Subject: [PATCH 1/2] Fix #81490: ZipArchive::extractTo() may leak memory We always need to free the CWD state. --- ext/zip/php_zip.c | 1 + ext/zip/tests/bug81490.phpt | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 ext/zip/tests/bug81490.phpt diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 57aa4df34f9e3..23f4a77c1c1b7 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -161,6 +161,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t virtual_file_ex(&new_state, file, NULL, CWD_EXPAND); path_cleaned = php_zip_make_relative_path(new_state.cwd, new_state.cwd_length); if(!path_cleaned) { + CWD_STATE_FREE(new_state.cwd); return 0; } path_cleaned_len = strlen(path_cleaned); diff --git a/ext/zip/tests/bug81490.phpt b/ext/zip/tests/bug81490.phpt new file mode 100644 index 0000000000000..1cc32547e5644 --- /dev/null +++ b/ext/zip/tests/bug81490.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #81490 (ZipArchive::extractTo() may leak memory) +--SKIPIF-- + +--FILE-- +open(__DIR__ . "/bug81490.zip", ZipArchive::CREATE|ZipArchive::OVERWRITE); +$zip->addFromString("", "yada yada"); +mkdir(__DIR__ . "/bug81490"); +$zip->open(__DIR__ . "/bug81490.zip"); +$zip->extractTo(__DIR__ . "/bug81490", ""); +?> +--EXPECT-- +--CLEAN-- + \ No newline at end of file From 9d0f89cd315cd54089cf56695397a6c9c1f8428d Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 30 Sep 2021 14:15:41 +0200 Subject: [PATCH 2/2] Fix further related memory leaks Pointed out by @remicollet. --- ext/zip/php_zip.c | 3 ++- ext/zip/tests/bug81490.phpt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 23f4a77c1c1b7..08f49a3a56028 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -167,6 +167,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t path_cleaned_len = strlen(path_cleaned); if (path_cleaned_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) { + CWD_STATE_FREE(new_state.cwd); return 0; } @@ -201,8 +202,8 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t efree(file_dirname_fullpath); if (!is_dir_only) { zend_string_release_ex(file_basename, 0); - CWD_STATE_FREE(new_state.cwd); } + CWD_STATE_FREE(new_state.cwd); return 0; } } diff --git a/ext/zip/tests/bug81490.phpt b/ext/zip/tests/bug81490.phpt index 1cc32547e5644..7c9a33a427cd9 100644 --- a/ext/zip/tests/bug81490.phpt +++ b/ext/zip/tests/bug81490.phpt @@ -18,4 +18,4 @@ $zip->extractTo(__DIR__ . "/bug81490", ""); \ No newline at end of file +?>