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