| From 9411bde3e4a70a81ff3ffd256b71927b2d90dcbb Mon Sep 17 00:00:00 2001 |
| From: jmoellers <josef.moellers@suse.com> |
| Date: Fri, 7 Sep 2018 11:32:04 +0200 |
| Subject: [PATCH] Avoid memory leak from __zzip_parse_root_directory(). |
| |
| [Retrieved (and slightly updated to remove test.zip) from: |
| https://github.com/gdraheim/zziplib/commit/9411bde3e4a70a81ff3ffd256b71927b2d90dcbb] |
| Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com> |
| --- |
| test/test.zip | Bin 1361 -> 1361 bytes |
| zzip/zip.c | 36 ++++++++++++++++++++++++++++++++++-- |
| 2 files changed, 34 insertions(+), 2 deletions(-) |
| |
| diff --git a/zzip/zip.c b/zzip/zip.c |
| index 88b833b..a685280 100644 |
| --- a/zzip/zip.c |
| +++ b/zzip/zip.c |
| @@ -475,9 +475,15 @@ __zzip_parse_root_directory(int fd, |
| } else |
| { |
| if (io->fd.seeks(fd, zz_rootseek + zz_offset, SEEK_SET) < 0) |
| + { |
| + free(hdr0); |
| return ZZIP_DIR_SEEK; |
| + } |
| if (io->fd.read(fd, &dirent, sizeof(dirent)) < __sizeof(dirent)) |
| + { |
| + free(hdr0); |
| return ZZIP_DIR_READ; |
| + } |
| d = &dirent; |
| } |
| |
| @@ -577,12 +583,38 @@ __zzip_parse_root_directory(int fd, |
| |
| if (hdr_return) |
| *hdr_return = hdr0; |
| + else |
| + { |
| + /* If it is not assigned to *hdr_return, it will never be free()'d */ |
| + free(hdr0); |
| + /* Make sure we don't free it again in case of error */ |
| + hdr0 = NULL; |
| + } |
| } /* else zero (sane) entries */ |
| # ifndef ZZIP_ALLOW_MODULO_ENTRIES |
| - return (entries != zz_entries ? ZZIP_CORRUPTED : 0); |
| + if (entries != zz_entries) |
| + { |
| + /* If it was assigned to *hdr_return, undo assignment */ |
| + if (p_reclen && hdr_return) |
| + *hdr_return = NULL; |
| + /* Free it, if it was not already free()'d */ |
| + if (hdr0 != NULL) |
| + free(hdr0); |
| + return ZZIP_CORRUPTED; |
| + } |
| # else |
| - return ((entries & (unsigned)0xFFFF) != zz_entries ? ZZIP_CORRUPTED : 0); |
| + if (((entries & (unsigned)0xFFFF) != zz_entries) |
| + { |
| + /* If it was assigned to *hdr_return, undo assignment */ |
| + if (p_reclen && hdr_return) |
| + *hdr_return = NULL; |
| + /* Free it, if it was not already free()'d */ |
| + if (hdr0 != NULL) |
| + free(hdr0); |
| + return ZZIP_CORRUPTED; |
| + } |
| # endif |
| + return 0; |
| } |
| |
| /* ------------------------- high-level interface ------------------------- */ |