diff --git a/unzip-zipbomb-part4.patch b/unzip-zipbomb-part4.patch index 3dce6e3..beffa2c 100644 --- a/unzip-zipbomb-part4.patch +++ b/unzip-zipbomb-part4.patch @@ -1,95 +1,25 @@ -From 122050bac16fae82a460ff739fb1ca0f106e9d85 Mon Sep 17 00:00:00 2001 +From 5e2efcd633a4a1fb95a129a75508e7d769e767be Mon Sep 17 00:00:00 2001 From: Mark Adler -Date: Sat, 2 Jan 2021 13:09:34 -0800 -Subject: [PATCH] Determine Zip64 status entry-by-entry instead of for entire - file. +Date: Sun, 9 Feb 2020 20:36:28 -0800 +Subject: [PATCH] Fix bug in UZbunzip2() that incorrectly updated G.incnt. -Fixes a bug for zip files with mixed Zip64 and not Zip64 entries, -which resulted in an incorrect data descriptor length. The bug is -seen when a Zip64 entry precedes a non-Zip64 entry, in which case -the data descriptor would have been assumed to be larger than it -is, resulting in an incorrect bomb warning due to a perceived -overlap with the next entry. This commit determines and saves the -Zip64 status for each entry based on the central directory, and -then computes the length of each data descriptor accordingly. +The update assumed a full buffer, which is not always full. This +could result in a false overlapped element detection when a small +bzip2-compressed file was unzipped. This commit remedies that. --- - extract.c | 5 +++-- - globals.h | 2 -- - process.c | 4 +--- - unzpriv.h | 1 + - 4 files changed, 5 insertions(+), 7 deletions(-) + extract.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract.c b/extract.c -index 504afd6..878817d 100644 +index d9866f9..0cb7bfc 100644 --- a/extract.c +++ b/extract.c -@@ -658,6 +658,7 @@ int extract_or_test_files(__G) /* return PK-type error code */ - break; - } - } -+ G.pInfo->zip64 = FALSE; - if ((error = do_string(__G__ G.crec.extra_field_length, - EXTRA_FIELD)) != 0) - { -@@ -2187,12 +2188,12 @@ static int extract_or_test_member(__G) /* return PK-type error code */ - (clen == SIG && /* if not SIG, no signature */ - ((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */ - (ulen == SIG && /* if not SIG, no signature */ -- (G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG -+ (G.pInfo->zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG - /* if not SIG, have signature */ - ))))) - /* skip four more bytes to account for signature */ - shy += 4 - readbuf((char *)buf, 4); -- if (G.zip64) -+ if (G.pInfo->zip64) - shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */ - if (shy) - error = PK_ERR; -diff --git a/globals.h b/globals.h -index f9c6daf..a883c90 100644 ---- a/globals.h -+++ b/globals.h -@@ -261,8 +261,6 @@ typedef struct Globals { - ecdir_rec ecrec; /* used in unzip.c, extract.c */ - z_stat statbuf; /* used by main, mapname, check_for_newer */ - -- int zip64; /* true if Zip64 info in extra field */ -- - int mem_mode; - uch *outbufptr; /* extract.c static */ - ulg outsize; /* extract.c static */ -diff --git a/process.c b/process.c -index d75d405..d643c6f 100644 ---- a/process.c -+++ b/process.c -@@ -1903,8 +1903,6 @@ int getZip64Data(__G__ ef_buf, ef_len) - #define Z64FLGS 0xffff - #define Z64FLGL 0xffffffff - -- G.zip64 = FALSE; -- - if (ef_len == 0 || ef_buf == NULL) - return PK_COOL; - -@@ -1943,7 +1941,7 @@ int getZip64Data(__G__ ef_buf, ef_len) - break; /* Expect only one EF_PKSZ64 block. */ - #endif /* 0 */ - -- G.zip64 = TRUE; -+ G.pInfo->zip64 = TRUE; - } - - /* Skip this extra field block. */ -diff --git a/unzpriv.h b/unzpriv.h -index 09f288e..75b3359 100644 ---- a/unzpriv.h -+++ b/unzpriv.h -@@ -2034,6 +2034,7 @@ typedef struct min_info { - #ifdef UNICODE_SUPPORT - unsigned GPFIsUTF8: 1; /* crec gen_purpose_flag UTF-8 bit 11 is set */ - #endif -+ unsigned zip64: 1; /* true if entry has Zip64 extra block */ - #ifndef SFX - char Far *cfilname; /* central header version of filename */ +@@ -3010,7 +3010,7 @@ __GDEF #endif + + G.inptr = (uch *)bstrm.next_in; +- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */ ++ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */ + + uzbunzip_cleanup_exit: + err = BZ2_bzDecompressEnd(&bstrm); diff --git a/unzip-zipbomb-part5.patch b/unzip-zipbomb-part5.patch new file mode 100644 index 0000000..ca6a43a --- /dev/null +++ b/unzip-zipbomb-part5.patch @@ -0,0 +1,26 @@ +From 5c572555cf5d80309a07c30cf7a54b2501493720 Mon Sep 17 00:00:00 2001 +From: Mark Adler +Date: Sun, 9 Feb 2020 21:39:09 -0800 +Subject: [PATCH] Fix bug in UZinflate() that incorrectly updated G.incnt. + +The update assumed a full buffer, which is not always full. This +could result in a false overlapped element detection when a small +deflate-compressed file was unzipped using an old zlib. This +commit remedies that. +--- + inflate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/inflate.c b/inflate.c +index 2f5a015..70e3cc0 100644 +--- a/inflate.c ++++ b/inflate.c +@@ -700,7 +700,7 @@ int UZinflate(__G__ is_defl64) + G.dstrm.total_out)); + + G.inptr = (uch *)G.dstrm.next_in; +- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */ ++ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */ + + uzinflate_cleanup_exit: + err = inflateReset(&G.dstrm); diff --git a/unzip-zipbomb-part6.patch b/unzip-zipbomb-part6.patch new file mode 100644 index 0000000..3dce6e3 --- /dev/null +++ b/unzip-zipbomb-part6.patch @@ -0,0 +1,95 @@ +From 122050bac16fae82a460ff739fb1ca0f106e9d85 Mon Sep 17 00:00:00 2001 +From: Mark Adler +Date: Sat, 2 Jan 2021 13:09:34 -0800 +Subject: [PATCH] Determine Zip64 status entry-by-entry instead of for entire + file. + +Fixes a bug for zip files with mixed Zip64 and not Zip64 entries, +which resulted in an incorrect data descriptor length. The bug is +seen when a Zip64 entry precedes a non-Zip64 entry, in which case +the data descriptor would have been assumed to be larger than it +is, resulting in an incorrect bomb warning due to a perceived +overlap with the next entry. This commit determines and saves the +Zip64 status for each entry based on the central directory, and +then computes the length of each data descriptor accordingly. +--- + extract.c | 5 +++-- + globals.h | 2 -- + process.c | 4 +--- + unzpriv.h | 1 + + 4 files changed, 5 insertions(+), 7 deletions(-) + +diff --git a/extract.c b/extract.c +index 504afd6..878817d 100644 +--- a/extract.c ++++ b/extract.c +@@ -658,6 +658,7 @@ int extract_or_test_files(__G) /* return PK-type error code */ + break; + } + } ++ G.pInfo->zip64 = FALSE; + if ((error = do_string(__G__ G.crec.extra_field_length, + EXTRA_FIELD)) != 0) + { +@@ -2187,12 +2188,12 @@ static int extract_or_test_member(__G) /* return PK-type error code */ + (clen == SIG && /* if not SIG, no signature */ + ((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */ + (ulen == SIG && /* if not SIG, no signature */ +- (G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG ++ (G.pInfo->zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG + /* if not SIG, have signature */ + ))))) + /* skip four more bytes to account for signature */ + shy += 4 - readbuf((char *)buf, 4); +- if (G.zip64) ++ if (G.pInfo->zip64) + shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */ + if (shy) + error = PK_ERR; +diff --git a/globals.h b/globals.h +index f9c6daf..a883c90 100644 +--- a/globals.h ++++ b/globals.h +@@ -261,8 +261,6 @@ typedef struct Globals { + ecdir_rec ecrec; /* used in unzip.c, extract.c */ + z_stat statbuf; /* used by main, mapname, check_for_newer */ + +- int zip64; /* true if Zip64 info in extra field */ +- + int mem_mode; + uch *outbufptr; /* extract.c static */ + ulg outsize; /* extract.c static */ +diff --git a/process.c b/process.c +index d75d405..d643c6f 100644 +--- a/process.c ++++ b/process.c +@@ -1903,8 +1903,6 @@ int getZip64Data(__G__ ef_buf, ef_len) + #define Z64FLGS 0xffff + #define Z64FLGL 0xffffffff + +- G.zip64 = FALSE; +- + if (ef_len == 0 || ef_buf == NULL) + return PK_COOL; + +@@ -1943,7 +1941,7 @@ int getZip64Data(__G__ ef_buf, ef_len) + break; /* Expect only one EF_PKSZ64 block. */ + #endif /* 0 */ + +- G.zip64 = TRUE; ++ G.pInfo->zip64 = TRUE; + } + + /* Skip this extra field block. */ +diff --git a/unzpriv.h b/unzpriv.h +index 09f288e..75b3359 100644 +--- a/unzpriv.h ++++ b/unzpriv.h +@@ -2034,6 +2034,7 @@ typedef struct min_info { + #ifdef UNICODE_SUPPORT + unsigned GPFIsUTF8: 1; /* crec gen_purpose_flag UTF-8 bit 11 is set */ + #endif ++ unsigned zip64: 1; /* true if entry has Zip64 extra block */ + #ifndef SFX + char Far *cfilname; /* central header version of filename */ + #endif diff --git a/unzip.spec b/unzip.spec index 1730107..087bd99 100644 --- a/unzip.spec +++ b/unzip.spec @@ -6,7 +6,7 @@ Summary: A utility for unpacking zip files Name: unzip Version: 6.0 -Release: 51%{?dist} +Release: 52%{?dist} License: BSD Source: http://downloads.sourceforge.net/infozip/unzip60.tar.gz @@ -68,6 +68,8 @@ Patch27: unzip-zipbomb-part2.patch Patch28: unzip-zipbomb-part3.patch Patch29: unzip-zipbomb-manpage.patch Patch30: unzip-zipbomb-part4.patch +Patch31: unzip-zipbomb-part5.patch +Patch32: unzip-zipbomb-part6.patch URL: http://www.info-zip.org/UnZip.html BuildRequires: make @@ -117,6 +119,8 @@ a zip archive. %patch28 -p1 %patch29 -p1 %patch30 -p1 +%patch31 -p1 +%patch32 -p1 %build # IZ_HAVE_UXUIDGID is needed for right functionality of unzip -X @@ -135,6 +139,11 @@ make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT%{_ %{_mandir}/*/* %changelog +* Thu Apr 29 2021 Jakub Martisko - 6.0-52 +- Sync the zipbomb false postives fixes with rhel +- zipbomb-part4 patch introduced in 6.0-51 has been renamed to part6 and part4 and part5 have been ported from rhel +Resolves: 1953565 + * Thu Mar 25 2021 Jakub Martisko - 6.0-51 - Fix false positive in the zipbomb detection Related: 1920632