Blame SOURCES/CVE-2018-16548.part1.patch

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