summary refs log tree commit diff
path: root/gnu/packages/patches/unzip-zipbomb-part3.patch
diff options
context:
space:
mode:
authorLéo Le Bouter <lle-bout@zaclys.net>2021-03-10 08:29:53 +0100
committerLéo Le Bouter <lle-bout@zaclys.net>2021-03-14 06:11:20 +0100
commit31d289a4759909d24dd309ac24d42902a8c20da0 (patch)
tree1896b64e72e6c18e65455d7323468d8659125ca5 /gnu/packages/patches/unzip-zipbomb-part3.patch
parent92d0949a268fe8479af5851d5bb3733e207a5c81 (diff)
downloadguix-31d289a4759909d24dd309ac24d42902a8c20da0.tar.gz
gnu: unzip: Add patches from Fedora [security fixes].
Non-exhaustively fixes CVE-2016-9844, CVE-2018-1000035, CVE-2018-18384, and
CVE-2019-13232.

* gnu/packages/patches/unzip-COVSCAN-fix-unterminated-string.patch,
gnu/packages/patches/unzip-CVE-2016-9844.patch,
gnu/packages/patches/unzip-CVE-2018-1000035.patch,
gnu/packages/patches/unzip-CVE-2018-18384.patch,
gnu/packages/patches/unzip-case-insensitive.patch,
gnu/packages/patches/unzip-alt-iconv-utf8-print.patch,
gnu/packages/patches/unzip-alt-iconv-utf8.patch,
gnu/packages/patches/unzip-close.patch,
gnu/packages/patches/unzip-exec-shield.patch,
gnu/packages/patches/unzip-fix-recmatch.patch,
gnu/packages/patches/unzip-manpage-fix.patch,
gnu/packages/patches/unzip-overflow.patch,
gnu/packages/patches/unzip-symlink.patch,
gnu/packages/patches/unzip-timestamp.patch,
gnu/packages/patches/unzip-valgrind.patch,
gnu/packages/patches/unzip-x-option.patch,
gnu/packages/patches/unzip-zipbomb-manpage.patch,
gnu/packages/patches/unzip-zipbomb-part1.patch,
gnu/packages/patches/unzip-zipbomb-part2.patch,
gnu/packages/patches/unzip-zipbomb-part3.patch: New patches.
* gnu/local.mk (dist_patch_DATA): Register them.
* gnu/packages/compression.scm (unzip/fixed): New variable. Apply patches.
(unzip)[replacement]: Graft.
Diffstat (limited to 'gnu/packages/patches/unzip-zipbomb-part3.patch')
-rw-r--r--gnu/packages/patches/unzip-zipbomb-part3.patch112
1 files changed, 112 insertions, 0 deletions
diff --git a/gnu/packages/patches/unzip-zipbomb-part3.patch b/gnu/packages/patches/unzip-zipbomb-part3.patch
new file mode 100644
index 0000000000..3b8d67b773
--- /dev/null
+++ b/gnu/packages/patches/unzip-zipbomb-part3.patch
@@ -0,0 +1,112 @@
+From 6d351831be705cc26d897db44f878a978f4138fc Mon Sep 17 00:00:00 2001
+From: Mark Adler <madler@alumni.caltech.edu>
+Date: Thu, 25 Jul 2019 20:43:17 -0700
+Subject: [PATCH] Do not raise a zip bomb alert for a misplaced central
+ directory.
+
+There is a zip-like file in the Firefox distribution, omni.ja,
+which is a zip container with the central directory placed at the
+start of the file instead of after the local entries as required
+by the zip standard. This commit marks the actual location of the
+central directory, as well as the end of central directory records,
+as disallowed locations. This now permits such containers to not
+raise a zip bomb alert, where in fact there are no overlaps.
+---
+ extract.c | 25 +++++++++++++++++++------
+ process.c |  6 ++++++
+ unzpriv.h | 10 ++++++++++
+ 3 files changed, 35 insertions(+), 6 deletions(-)
+
+diff --git a/extract.c b/extract.c
+index 0973a33..1b73cb0 100644
+--- a/extract.c
++++ b/extract.c
+@@ -493,8 +493,11 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+     }
+ #endif /* !SFX || SFX_EXDIR */
+ 
+-    /* One more: initialize cover structure for bomb detection. Start with a
+-       span that covers the central directory though the end of the file. */
++    /* One more: initialize cover structure for bomb detection. Start with
++       spans that cover any extra bytes at the start, the central directory,
++       the end of central directory record (including the Zip64 end of central
++       directory locator, if present), and the Zip64 end of central directory
++       record, if present. */
+     if (G.cover == NULL) {
+         G.cover = malloc(sizeof(cover_t));
+         if (G.cover == NULL) {
+@@ -506,15 +509,25 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+         ((cover_t *)G.cover)->max = 0;
+     }
+     ((cover_t *)G.cover)->num = 0;
+-    if ((G.extra_bytes != 0 &&
+-         cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
+-        cover_add((cover_t *)G.cover,
++    if (cover_add((cover_t *)G.cover,
+                   G.extra_bytes + G.ecrec.offset_start_central_directory,
+-                  G.ziplen) != 0) {
++                  G.extra_bytes + G.ecrec.offset_start_central_directory +
++                  G.ecrec.size_central_directory) != 0) {
+         Info(slide, 0x401, ((char *)slide,
+           LoadFarString(NotEnoughMemCover)));
+         return PK_MEM;
+     }
++    if ((G.extra_bytes != 0 &&
++         cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
++        (G.ecrec.have_ecr64 &&
++         cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
++                   G.ecrec.ec64_end) != 0) ||
++        cover_add((cover_t *)G.cover, G.ecrec.ec_start,
++                  G.ecrec.ec_end) != 0) {
++        Info(slide, 0x401, ((char *)slide,
++          LoadFarString(OverlappedComponents)));
++        return PK_BOMB;
++    }
+ 
+ /*---------------------------------------------------------------------------
+     The basic idea of this function is as follows.  Since the central di-
+diff --git a/process.c b/process.c
+index d2e4dc3..d75d405 100644
+--- a/process.c
++++ b/process.c
+@@ -1408,6 +1408,10 @@ static int find_ecrec64(__G__ searchlen)         /* return PK-class error */
+ 
+     /* Now, we are (almost) sure that we have a Zip64 archive. */
+     G.ecrec.have_ecr64 = 1;
++    G.ecrec.ec_start -= ECLOC64_SIZE+4;
++    G.ecrec.ec64_start = ecrec64_start_offset;
++    G.ecrec.ec64_end = ecrec64_start_offset +
++                       12 + makeint64(&byterec[ECREC64_LENGTH]);
+ 
+     /* Update the "end-of-central-dir offset" for later checks. */
+     G.real_ecrec_offset = ecrec64_start_offset;
+@@ -1542,6 +1546,8 @@ static int find_ecrec(__G__ searchlen)          /* return PK-class error */
+       makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
+     G.ecrec.zipfile_comment_length =
+       makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
++    G.ecrec.ec_start = G.real_ecrec_offset;
++    G.ecrec.ec_end = G.ecrec.ec_start + 22 + G.ecrec.zipfile_comment_length;
+ 
+     /* Now, we have to read the archive comment, BEFORE the file pointer
+        is moved away backwards to seek for a Zip64 ECLOC64 structure.
+diff --git a/unzpriv.h b/unzpriv.h
+index dc9eff5..297b3c7 100644
+--- a/unzpriv.h
++++ b/unzpriv.h
+@@ -2185,6 +2185,16 @@ typedef struct VMStimbuf {
+        int have_ecr64;                  /* valid Zip64 ecdir-record exists */
+        int is_zip64_archive;            /* Zip64 ecdir-record is mandatory */
+        ush zipfile_comment_length;
++       zusz_t ec_start, ec_end;         /* offsets of start and end of the
++                                           end of central directory record,
++                                           including if present the Zip64
++                                           end of central directory locator,
++                                           which immediately precedes the
++                                           end of central directory record */
++       zusz_t ec64_start, ec64_end;     /* if have_ecr64 is true, then these
++                                           are the offsets of the start and
++                                           end of the Zip64 end of central
++                                           directory record */
+    } ecdir_rec;
+ 
+