diff --git a/.fmf/version b/.fmf/version deleted file mode 100644 index d00491f..0000000 --- a/.fmf/version +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/plans/all.fmf b/plans/all.fmf deleted file mode 100644 index 437777e..0000000 --- a/plans/all.fmf +++ /dev/null @@ -1,6 +0,0 @@ -summary: Basic smoke test -discover: - how: fmf - url: https://src.fedoraproject.org/tests/unzip.git -execute: - how: tmt diff --git a/unzip-6.0-COVSCAN-fix-unterminated-string.patch b/unzip-6.0-COVSCAN-fix-unterminated-string.patch deleted file mode 100644 index 7173771..0000000 --- a/unzip-6.0-COVSCAN-fix-unterminated-string.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 06d1b08aef94984256cad3c5a54cedb10295681f Mon Sep 17 00:00:00 2001 -From: Jakub Martisko -Date: Thu, 8 Nov 2018 09:31:18 +0100 -Subject: [PATCH] Possible unterminated string fix - ---- - unix/unix.c | 4 +++- - unix/unxcfg.h | 2 +- - unzip.c | 12 ++++++++---- - zipinfo.c | 12 ++++++++---- - 4 files changed, 20 insertions(+), 10 deletions(-) - -diff --git a/unix/unix.c b/unix/unix.c -index 59b622d..cd57f80 100644 ---- a/unix/unix.c -+++ b/unix/unix.c -@@ -1945,7 +1945,9 @@ void init_conversion_charsets() - for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++) - if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) { - strncpy(OEM_CP, dos_charset_map[i].archive_charset, -- sizeof(OEM_CP)); -+ MAX_CP_NAME - 1); -+ -+ OEM_CP[MAX_CP_NAME - 1] = '\0'; - break; - } - } -diff --git a/unix/unxcfg.h b/unix/unxcfg.h -index 8729de2..9ee8cfe 100644 ---- a/unix/unxcfg.h -+++ b/unix/unxcfg.h -@@ -228,7 +228,7 @@ typedef struct stat z_stat; - /* and notfirstcall are used by do_wild(). */ - - --#define MAX_CP_NAME 25 -+#define MAX_CP_NAME 25 + 1 - - #ifdef SETLOCALE - # undef SETLOCALE -diff --git a/unzip.c b/unzip.c -index 2d94a38..a485f2b 100644 ---- a/unzip.c -+++ b/unzip.c -@@ -1561,7 +1561,8 @@ int uz_opts(__G__ pargc, pargv) - "error: a valid character encoding should follow the -I argument")); - return(PK_PARAM); - } -- strncpy(ISO_CP, s, sizeof(ISO_CP)); -+ strncpy(ISO_CP, s, MAX_CP_NAME - 1); -+ ISO_CP[MAX_CP_NAME - 1] = '\0'; - } else { /* -I charset */ - ++argv; - if(!(--argc > 0 && *argv != NULL && **argv != '-')) { -@@ -1570,7 +1571,8 @@ int uz_opts(__G__ pargc, pargv) - return(PK_PARAM); - } - s = *argv; -- strncpy(ISO_CP, s, sizeof(ISO_CP)); -+ strncpy(ISO_CP, s, MAX_CP_NAME - 1); -+ ISO_CP[MAX_CP_NAME - 1] = '\0'; - } - while(*(++s)); /* No params straight after charset name */ - } -@@ -1665,7 +1667,8 @@ int uz_opts(__G__ pargc, pargv) - "error: a valid character encoding should follow the -I argument")); - return(PK_PARAM); - } -- strncpy(OEM_CP, s, sizeof(OEM_CP)); -+ strncpy(OEM_CP, s, MAX_CP_NAME - 1); -+ OEM_CP[MAX_CP_NAME - 1] = '\0'; - } else { /* -O charset */ - ++argv; - if(!(--argc > 0 && *argv != NULL && **argv != '-')) { -@@ -1674,7 +1677,8 @@ int uz_opts(__G__ pargc, pargv) - return(PK_PARAM); - } - s = *argv; -- strncpy(OEM_CP, s, sizeof(OEM_CP)); -+ strncpy(OEM_CP, s, MAX_CP_NAME - 1); -+ OEM_CP[MAX_CP_NAME - 1] = '\0'; - } - while(*(++s)); /* No params straight after charset name */ - } -diff --git a/zipinfo.c b/zipinfo.c -index accca2a..cb7e08d 100644 ---- a/zipinfo.c -+++ b/zipinfo.c -@@ -519,7 +519,8 @@ int zi_opts(__G__ pargc, pargv) - "error: a valid character encoding should follow the -I argument")); - return(PK_PARAM); - } -- strncpy(ISO_CP, s, sizeof(ISO_CP)); -+ strncpy(ISO_CP, s, MAX_CP_NAME - 1); -+ ISO_CP[MAX_CP_NAME - 1] = '\0'; - } else { /* -I charset */ - ++argv; - if(!(--argc > 0 && *argv != NULL && **argv != '-')) { -@@ -528,7 +529,8 @@ int zi_opts(__G__ pargc, pargv) - return(PK_PARAM); - } - s = *argv; -- strncpy(ISO_CP, s, sizeof(ISO_CP)); -+ strncpy(ISO_CP, s, MAX_CP_NAME - 1); -+ ISO_CP[MAX_CP_NAME - 1] = '\0'; - } - while(*(++s)); /* No params straight after charset name */ - } -@@ -568,7 +570,8 @@ int zi_opts(__G__ pargc, pargv) - "error: a valid character encoding should follow the -I argument")); - return(PK_PARAM); - } -- strncpy(OEM_CP, s, sizeof(OEM_CP)); -+ strncpy(OEM_CP, s, MAX_CP_NAME - 1); -+ OEM_CP[MAX_CP_NAME - 1] = '\0'; - } else { /* -O charset */ - ++argv; - if(!(--argc > 0 && *argv != NULL && **argv != '-')) { -@@ -577,7 +580,8 @@ int zi_opts(__G__ pargc, pargv) - return(PK_PARAM); - } - s = *argv; -- strncpy(OEM_CP, s, sizeof(OEM_CP)); -+ strncpy(OEM_CP, s, MAX_CP_NAME - 1); -+ OEM_CP[MAX_CP_NAME - 1] = '\0'; - } - while(*(++s)); /* No params straight after charset name */ - } --- -2.14.5 - diff --git a/unzip-6.0-CVE-2022-0529-and-0530.patch b/unzip-6.0-CVE-2022-0529-and-0530.patch deleted file mode 100644 index 2b84b96..0000000 --- a/unzip-6.0-CVE-2022-0529-and-0530.patch +++ /dev/null @@ -1,170 +0,0 @@ -From: Steven M. Schweda -Subject: Fix for CVE-2022-0529 and CVE-2022-0530 -Bug-Debian: https://bugs.debian.org/1010355 -X-Debian-version: 6.0-27 - ---- a/fileio.c -+++ b/fileio.c -@@ -171,8 +171,10 @@ - static ZCONST char Far FilenameTooLongTrunc[] = - "warning: filename too long--truncating.\n"; - #ifdef UNICODE_SUPPORT -+ static ZCONST char Far UFilenameCorrupt[] = -+ "error: Unicode filename corrupt.\n"; - static ZCONST char Far UFilenameTooLongTrunc[] = -- "warning: Converted unicode filename too long--truncating.\n"; -+ "warning: Converted Unicode filename too long--truncating.\n"; - #endif - static ZCONST char Far ExtraFieldTooLong[] = - "warning: extra field too long (%d). Ignoring...\n"; -@@ -2361,16 +2363,30 @@ - /* convert UTF-8 to local character set */ - fn = utf8_to_local_string(G.unipath_filename, - G.unicode_escape_all); -- /* make sure filename is short enough */ -- if (strlen(fn) >= FILNAMSIZ) { -- fn[FILNAMSIZ - 1] = '\0'; -+ -+ /* 2022-07-22 SMS, et al. CVE-2022-0530 -+ * Detect conversion failure, emit message. -+ * Continue with unconverted name. -+ */ -+ if (fn == NULL) -+ { - Info(slide, 0x401, ((char *)slide, -- LoadFarString(UFilenameTooLongTrunc))); -- error = PK_WARN; -+ LoadFarString(UFilenameCorrupt))); -+ error = PK_ERR; -+ } -+ else -+ { -+ /* make sure filename is short enough */ -+ if (strlen(fn) >= FILNAMSIZ) { -+ fn[FILNAMSIZ - 1] = '\0'; -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString(UFilenameTooLongTrunc))); -+ error = PK_WARN; -+ } -+ /* replace filename with converted UTF-8 */ -+ strcpy(G.filename, fn); -+ free(fn); - } -- /* replace filename with converted UTF-8 */ -- strcpy(G.filename, fn); -- free(fn); - } - # endif /* UNICODE_WCHAR */ - if (G.unipath_filename != G.filename_full) ---- a/process.c -+++ b/process.c -@@ -222,6 +222,8 @@ - "\nwarning: Unicode Path version > 1\n"; - static ZCONST char Far UnicodeMismatchError[] = - "\nwarning: Unicode Path checksum invalid\n"; -+ static ZCONST char Far UFilenameTooLongTrunc[] = -+ "warning: filename too long (P1) -- truncating.\n"; - #endif - - -@@ -1915,7 +1917,7 @@ - Sets both local header and central header fields. Not terribly clever, - but it means that this procedure is only called in one place. - -- 2014-12-05 SMS. -+ 2014-12-05 SMS. (oCERT.org report.) CVE-2014-8141. - Added checks to ensure that enough data are available before calling - makeint64() or makelong(). Replaced various sizeof() values with - simple ("4" or "8") constants. (The Zip64 structures do not depend -@@ -1947,7 +1949,7 @@ - - if (eb_id == EF_PKSZ64) - { -- int offset = EB_HEADSIZE; -+ unsigned offset = EB_HEADSIZE; - - if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL)) - { -@@ -2046,7 +2049,7 @@ - } - if (eb_id == EF_UNIPATH) { - -- int offset = EB_HEADSIZE; -+ unsigned offset = EB_HEADSIZE; - ush ULen = eb_len - 5; - ulg chksum = CRCVAL_INITIAL; - -@@ -2504,16 +2507,17 @@ - int state_dependent; - int wsize = 0; - int max_bytes = MB_CUR_MAX; -- char buf[9]; -+ char buf[ MB_CUR_MAX+ 1]; /* ("+1" not really needed?) */ - char *buffer = NULL; - char *local_string = NULL; -+ size_t buffer_size; /* CVE-2022-0529 */ - - for (wsize = 0; wide_string[wsize]; wsize++) ; - - if (max_bytes < MAX_ESCAPE_BYTES) - max_bytes = MAX_ESCAPE_BYTES; -- -- if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) { -+ buffer_size = wsize * max_bytes + 1; /* Reused below. */ -+ if ((buffer = (char *)malloc( buffer_size)) == NULL) { - return NULL; - } - -@@ -2551,8 +2555,28 @@ - } else { - /* no MB for this wide */ - /* use escape for wide character */ -- char *escape_string = wide_to_escape_string(wide_string[i]); -- strcat(buffer, escape_string); -+ size_t buffer_len; -+ size_t escape_string_len; -+ char *escape_string; -+ int err_msg = 0; -+ -+ escape_string = wide_to_escape_string(wide_string[i]); -+ buffer_len = strlen( buffer); -+ escape_string_len = strlen( escape_string); -+ -+ /* Append escape string, as space allows. */ -+ /* 2022-07-18 SMS, et al. CVE-2022-0529 */ -+ if (escape_string_len > buffer_size- buffer_len- 1) -+ { -+ escape_string_len = buffer_size- buffer_len- 1; -+ if (err_msg == 0) -+ { -+ err_msg = 1; -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString( UFilenameTooLongTrunc))); -+ } -+ } -+ strncat( buffer, escape_string, escape_string_len); - free(escape_string); - } - } -@@ -2604,9 +2628,18 @@ - ZCONST char *utf8_string; - int escape_all; - { -- zwchar *wide = utf8_to_wide_string(utf8_string); -- char *loc = wide_to_local_string(wide, escape_all); -- free(wide); -+ zwchar *wide; -+ char *loc = NULL; -+ -+ wide = utf8_to_wide_string( utf8_string); -+ -+ /* 2022-07-25 SMS, et al. CVE-2022-0530 */ -+ if (wide != NULL) -+ { -+ loc = wide_to_local_string( wide, escape_all); -+ free( wide); -+ } -+ - return loc; - } - diff --git a/unzip-6.0-RHEL-86228.patch b/unzip-6.0-RHEL-86228.patch deleted file mode 100644 index 25c2fbb..0000000 --- a/unzip-6.0-RHEL-86228.patch +++ /dev/null @@ -1,19 +0,0 @@ -From: Roy Tam -Subject: Handle Microsoft ZIP64 files by ignoring invalid "Total number of disks" field -Origin: https://sourceforge.net/p/infozip/bugs/42/ -Bug: https://sourceforge.net/p/infozip/bugs/42/ -Bug-Debian: https://bugs.debian.org/1064000 -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/unzip/+bug/2051952 -X-Debian-version: 6.0-29 - ---- a/process.c -+++ b/process.c -@@ -1281,7 +1281,7 @@ - fprintf(stdout,"\nnumber of disks (ECR) %u, (ECLOC64) %lu\n", - G.ecrec.number_this_disk, ecloc64_total_disks); fflush(stdout); - #endif -- if ((G.ecrec.number_this_disk != 0xFFFF) && -+ if ((G.ecrec.number_this_disk != 0xFFFF) && ecloc64_total_disks && - (G.ecrec.number_this_disk != ecloc64_total_disks - 1)) { - /* Note: For some unknown reason, the developers at PKWARE decided to - store the "zip64 total disks" value as a counter starting from 1, diff --git a/unzip-6.0-alt-iconv-utf8.patch b/unzip-6.0-alt-iconv-utf8.patch index 1db3164..b9e3777 100644 --- a/unzip-6.0-alt-iconv-utf8.patch +++ b/unzip-6.0-alt-iconv-utf8.patch @@ -174,11 +174,11 @@ Index: unzip-6.0/unzip.c +#else /* UNIX */ +static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\ + -h print header line -t print totals for listed files or for all\n\ -+ -z print zipfile comment -T print file times in sortable decimal format\ -+\n -C be case-insensitive %s\ ++ -z print zipfile comment %c-T%c print file times in sortable decimal format\ ++\n %c-C%c be case-insensitive %s\ + -x exclude filenames that follow from listing\n\ -+ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\ -+ -I CHARSET specify a character encoding for UNIX and other archives\n"; ++ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\ ++ -I CHARSET specify a character encoding for UNIX and other archives\n"; +#endif /* !UNIX */ #ifdef MORE static ZCONST char Far ZipInfoUsageLine4[] = @@ -196,8 +196,8 @@ Index: unzip-6.0/unzip.c + -U use escapes for all non-ASCII Unicode -UU ignore any Unicode fields\n\ + -C match filenames case-insensitively -L make (some) names \ +lowercase\n %-42s -V retain VMS version numbers\n%s\ -+ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\ -+ -I CHARSET specify a character encoding for UNIX and other archives\n\n"; ++ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\ ++ -I CHARSET specify a character encoding for UNIX and other archives\n\n"; #else /* !VMS */ static ZCONST char Far UnzipUsageLine4[] = "\ modifiers:\n\ diff --git a/unzip-6.0-cve-2018-18384.patch b/unzip-6.0-cve-2018-18384.patch deleted file mode 100644 index 54d4b8c..0000000 --- a/unzip-6.0-cve-2018-18384.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- unzip60/list.c -+++ unzip60/list.c -@@ -97,7 +97,7 @@ int list_files(__G) /* return PK-type - { - int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL; - #ifndef WINDLL -- char sgn, cfactorstr[13]; -+ char sgn, cfactorstr[1+10+1+1]; /* %NUL */ - int longhdr=(uO.vflag>1); - #endif - int date_format; -@@ -389,9 +389,9 @@ int list_files(__G) /* return PK-type - } - #else /* !WINDLL */ - if (cfactor == 100) -- sprintf(cfactorstr, LoadFarString(CompFactor100)); -+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100)); - else -- sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor); -+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor); - if (longhdr) - Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats), - FmZofft(G.crec.ucsize, "8", "u"), methbuf, -@@ -471,9 +471,9 @@ int list_files(__G) /* return PK-type - - #else /* !WINDLL */ - if (cfactor == 100) -- sprintf(cfactorstr, LoadFarString(CompFactor100)); -+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100)); - else -- sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor); -+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor); - if (longhdr) { - Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer), - FmZofft(tot_ucsize, "8", "u"), FmZofft(tot_csize, "8", "u"), diff --git a/unzip-6.0-fix-warning-messages-on-big-files.patch b/unzip-6.0-fix-warning-messages-on-big-files.patch deleted file mode 100644 index 55a115a..0000000 --- a/unzip-6.0-fix-warning-messages-on-big-files.patch +++ /dev/null @@ -1,15 +0,0 @@ -From: "Steven M. Schweda" -Subject: Fix lame code in fileio.c -Bug-Debian: https://bugs.debian.org/929502 -X-Debian-version: 6.0-23 - ---- a/fileio.c -+++ b/fileio.c -@@ -2477,6 +2477,7 @@ - */ - return (((zusz_t)sig[7]) << 56) - + (((zusz_t)sig[6]) << 48) -+ + (((zusz_t)sig[5]) << 40) - + (((zusz_t)sig[4]) << 32) - + (zusz_t)((((ulg)sig[3]) << 24) - + (((ulg)sig[2]) << 16) diff --git a/unzip-6.0-sast.patch b/unzip-6.0-sast.patch deleted file mode 100644 index 71b7cb9..0000000 --- a/unzip-6.0-sast.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/envargs.c 2005-03-04 03:23:38.000000000 +0100 -+++ b/envargs.c 2024-11-26 13:17:22.289650230 +0100 -@@ -118,7 +118,7 @@ - - /* remove escape characters */ - while ((argstart = MBSCHR(argstart, '\\')) != (char *)NULL) { -- strcpy(argstart, argstart + 1); -+ memmove(argstart, argstart + 1, strlen(argstart + 1) + 1); - if (*argstart) - ++argstart; - } diff --git a/unzip-6.0-wcstombs-fortify.patch b/unzip-6.0-wcstombs-fortify.patch deleted file mode 100644 index 6e03cea..0000000 --- a/unzip-6.0-wcstombs-fortify.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- unzip60/extract.c 2023-01-25 07:05:58.742254870 -0500 -+++ unzip60.new/extract.c 2023-01-25 07:04:48.073435349 -0500 -@@ -2889,7 +2889,7 @@ char *fnfilter(raw, space, size) /* co - strcpy( (char *)space, raw); - return (char *)space; - } -- woslen = wcstombs( newraw, wostring, (woslen * MB_CUR_MAX) + 1); -+ woslen = wcstombs( newraw, wostring, woslen + 1); - - if (size > 0) { - slim = space + size - 4; diff --git a/unzip-gnu89-build.patch b/unzip-gnu89-build.patch deleted file mode 100644 index 706f125..0000000 --- a/unzip-gnu89-build.patch +++ /dev/null @@ -1,15 +0,0 @@ -unzip uses C89-only features, so it needs to be built in C89 mode. - -diff --git a/unix/Makefile b/unix/Makefile -index ab32270cf4b9b2cf..5eabbe13095e1f58 100644 ---- a/unix/Makefile -+++ b/unix/Makefile -@@ -545,7 +545,7 @@ generic: flags # now try autoconfigure first - # make $(MAKEF) unzips CF="${CF} `cat flags`" - - generic_gcc: -- $(MAKE) $(MAKEF) generic CC=gcc IZ_BZIP2="$(IZ_BZIP2)" -+ $(MAKE) $(MAKEF) generic CC="gcc -std=gnu89" IZ_BZIP2="$(IZ_BZIP2)" - - # extensions to perform SVR4 package-creation after compilation - generic_pkg: generic svr4package diff --git a/unzip-zipbomb-manpage.patch b/unzip-zipbomb-manpage.patch deleted file mode 100644 index bcee827..0000000 --- a/unzip-zipbomb-manpage.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6fe72291a5563cdbcd2bdd87e36528537b7cdcfb Mon Sep 17 00:00:00 2001 -From: Jakub Martisko -Date: Mon, 18 Nov 2019 14:17:46 +0100 -Subject: [PATCH] update the man page - ---- - man/unzip.1 | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/man/unzip.1 b/man/unzip.1 -index 21816d1..4d66073 100644 ---- a/man/unzip.1 -+++ b/man/unzip.1 -@@ -850,6 +850,8 @@ the specified zipfiles were not found. - invalid options were specified on the command line. - .IP 11 - no matching files were found. -+.IP 12 -+invalid zip file with overlapped components (possible zip-bomb). The zip-bomb checks can be disabled by using the UNZIP_DISABLE_ZIPBOMB_DETECTION=TRUE environment variable. - .IP 50 - the disk is (or was) full during extraction. - .IP 51 --- -2.23.0 - diff --git a/unzip-zipbomb-part1.patch b/unzip-zipbomb-part1.patch deleted file mode 100644 index 35cf856..0000000 --- a/unzip-zipbomb-part1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 41beb477c5744bc396fa1162ee0c14218ec12213 Mon Sep 17 00:00:00 2001 -From: Mark Adler -Date: Mon, 27 May 2019 08:20:32 -0700 -Subject: [PATCH] Fix bug in undefer_input() that misplaced the input state. - ---- - fileio.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/fileio.c b/fileio.c -index c042987..bc00d74 100644 ---- a/fileio.c -+++ b/fileio.c -@@ -530,8 +530,10 @@ void undefer_input(__G) - * This condition was checked when G.incnt_leftover was set > 0 in - * defer_leftover_input(), and it is NOT allowed to touch G.csize - * before calling undefer_input() when (G.incnt_leftover > 0) -- * (single exception: see read_byte()'s "G.csize <= 0" handling) !! -+ * (single exception: see readbyte()'s "G.csize <= 0" handling) !! - */ -+ if (G.csize < 0L) -+ G.csize = 0L; - G.incnt = G.incnt_leftover + (int)G.csize; - G.inptr = G.inptr_leftover - (int)G.csize; - G.incnt_leftover = 0; diff --git a/unzip-zipbomb-part2.patch b/unzip-zipbomb-part2.patch deleted file mode 100644 index 903c845..0000000 --- a/unzip-zipbomb-part2.patch +++ /dev/null @@ -1,349 +0,0 @@ -From 47b3ceae397d21bf822bc2ac73052a4b1daf8e1c Mon Sep 17 00:00:00 2001 -From: Mark Adler -Date: Tue, 11 Jun 2019 22:01:18 -0700 -Subject: [PATCH] Detect and reject a zip bomb using overlapped entries. - -This detects an invalid zip file that has at least one entry that -overlaps with another entry or with the central directory to the -end of the file. A Fifield zip bomb uses overlapped local entries -to vastly increase the potential inflation ratio. Such an invalid -zip file is rejected. - -See https://www.bamsoftware.com/hacks/zipbomb/ for David Fifield's -analysis, construction, and examples of such zip bombs. - -The detection maintains a list of covered spans of the zip files -so far, where the central directory to the end of the file and any -bytes preceding the first entry at zip file offset zero are -considered covered initially. Then as each entry is decompressed -or tested, it is considered covered. When a new entry is about to -be processed, its initial offset is checked to see if it is -contained by a covered span. If so, the zip file is rejected as -invalid. - -This commit depends on a preceding commit: "Fix bug in -undefer_input() that misplaced the input state." ---- - extract.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++- - globals.c | 1 + - globals.h | 3 + - process.c | 11 ++++ - unzip.h | 1 + - 5 files changed, 205 insertions(+), 1 deletion(-) - -diff --git a/extract.c b/extract.c -index 1acd769..0973a33 100644 ---- a/extract.c -+++ b/extract.c -@@ -319,6 +319,125 @@ static ZCONST char Far UnsupportedExtraField[] = - "\nerror: unsupported extra-field compression type (%u)--skipping\n"; - static ZCONST char Far BadExtraFieldCRC[] = - "error [%s]: bad extra-field CRC %08lx (should be %08lx)\n"; -+static ZCONST char Far NotEnoughMemCover[] = -+ "error: not enough memory for bomb detection\n"; -+static ZCONST char Far OverlappedComponents[] = -+ "error: invalid zip file with overlapped components (possible zip bomb)\n"; -+ -+ -+ -+ -+ -+/* A growable list of spans. */ -+typedef zoff_t bound_t; -+typedef struct { -+ bound_t beg; /* start of the span */ -+ bound_t end; /* one past the end of the span */ -+} span_t; -+typedef struct { -+ span_t *span; /* allocated, distinct, and sorted list of spans */ -+ size_t num; /* number of spans in the list */ -+ size_t max; /* allocated number of spans (num <= max) */ -+} cover_t; -+ -+/* -+ * Return the index of the first span in cover whose beg is greater than val. -+ * If there is no such span, then cover->num is returned. -+ */ -+static size_t cover_find(cover, val) -+ cover_t *cover; -+ bound_t val; -+{ -+ size_t lo = 0, hi = cover->num; -+ while (lo < hi) { -+ size_t mid = (lo + hi) >> 1; -+ if (val < cover->span[mid].beg) -+ hi = mid; -+ else -+ lo = mid + 1; -+ } -+ return hi; -+} -+ -+/* Return true if val lies within any one of the spans in cover. */ -+static int cover_within(cover, val) -+ cover_t *cover; -+ bound_t val; -+{ -+ size_t pos = cover_find(cover, val); -+ return pos > 0 && val < cover->span[pos - 1].end; -+} -+ -+/* -+ * Add a new span to the list, but only if the new span does not overlap any -+ * spans already in the list. The new span covers the values beg..end-1. beg -+ * must be less than end. -+ * -+ * Keep the list sorted and merge adjacent spans. Grow the allocated space for -+ * the list as needed. On success, 0 is returned. If the new span overlaps any -+ * existing spans, then 1 is returned and the new span is not added to the -+ * list. If the new span is invalid because beg is greater than or equal to -+ * end, then -1 is returned. If the list needs to be grown but the memory -+ * allocation fails, then -2 is returned. -+ */ -+static int cover_add(cover, beg, end) -+ cover_t *cover; -+ bound_t beg; -+ bound_t end; -+{ -+ size_t pos; -+ int prec, foll; -+ -+ if (beg >= end) -+ /* The new span is invalid. */ -+ return -1; -+ -+ /* Find where the new span should go, and make sure that it does not -+ overlap with any existing spans. */ -+ pos = cover_find(cover, beg); -+ if ((pos > 0 && beg < cover->span[pos - 1].end) || -+ (pos < cover->num && end > cover->span[pos].beg)) -+ return 1; -+ -+ /* Check for adjacencies. */ -+ prec = pos > 0 && beg == cover->span[pos - 1].end; -+ foll = pos < cover->num && end == cover->span[pos].beg; -+ if (prec && foll) { -+ /* The new span connects the preceding and following spans. Merge the -+ following span into the preceding span, and delete the following -+ span. */ -+ cover->span[pos - 1].end = cover->span[pos].end; -+ cover->num--; -+ memmove(cover->span + pos, cover->span + pos + 1, -+ (cover->num - pos) * sizeof(span_t)); -+ } -+ else if (prec) -+ /* The new span is adjacent only to the preceding span. Extend the end -+ of the preceding span. */ -+ cover->span[pos - 1].end = end; -+ else if (foll) -+ /* The new span is adjacent only to the following span. Extend the -+ beginning of the following span. */ -+ cover->span[pos].beg = beg; -+ else { -+ /* The new span has gaps between both the preceding and the following -+ spans. Assure that there is room and insert the span. */ -+ if (cover->num == cover->max) { -+ size_t max = cover->max == 0 ? 16 : cover->max << 1; -+ span_t *span = realloc(cover->span, max * sizeof(span_t)); -+ if (span == NULL) -+ return -2; -+ cover->span = span; -+ cover->max = max; -+ } -+ memmove(cover->span + pos + 1, cover->span + pos, -+ (cover->num - pos) * sizeof(span_t)); -+ cover->num++; -+ cover->span[pos].beg = beg; -+ cover->span[pos].end = end; -+ } -+ return 0; -+} - - - -@@ -374,6 +493,29 @@ 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. */ -+ if (G.cover == NULL) { -+ G.cover = malloc(sizeof(cover_t)); -+ if (G.cover == NULL) { -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString(NotEnoughMemCover))); -+ return PK_MEM; -+ } -+ ((cover_t *)G.cover)->span = NULL; -+ ((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, -+ G.extra_bytes + G.ecrec.offset_start_central_directory, -+ G.ziplen) != 0) { -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString(NotEnoughMemCover))); -+ return PK_MEM; -+ } -+ - /*--------------------------------------------------------------------------- - The basic idea of this function is as follows. Since the central di- - rectory lies at the end of the zipfile and the member files lie at the -@@ -591,7 +733,8 @@ int extract_or_test_files(__G) /* return PK-type error code */ - if (error > error_in_archive) - error_in_archive = error; - /* ...and keep going (unless disk full or user break) */ -- if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) { -+ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC || -+ error == PK_BOMB) { - /* clear reached_end to signal premature stop ... */ - reached_end = FALSE; - /* ... and cancel scanning the central directory */ -@@ -1060,6 +1203,11 @@ static int extract_or_test_entrylist(__G__ numchunk, - - /* seek_zipf(__G__ pInfo->offset); */ - request = G.pInfo->offset + G.extra_bytes; -+ if (cover_within((cover_t *)G.cover, request)) { -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString(OverlappedComponents))); -+ return PK_BOMB; -+ } - inbuf_offset = request % INBUFSIZ; - bufstart = request - inbuf_offset; - -@@ -1591,6 +1739,18 @@ static int extract_or_test_entrylist(__G__ numchunk, - return IZ_CTRLC; /* cancel operation by user request */ - } - #endif -+ error = cover_add((cover_t *)G.cover, request, -+ G.cur_zipfile_bufstart + (G.inptr - G.inbuf)); -+ if (error < 0) { -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString(NotEnoughMemCover))); -+ return PK_MEM; -+ } -+ if (error != 0) { -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString(OverlappedComponents))); -+ return PK_BOMB; -+ } - #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */ - UserStop(); - #endif -@@ -1992,6 +2152,34 @@ static int extract_or_test_member(__G) /* return PK-type error code */ - } - - undefer_input(__G); -+ -+ if ((G.lrec.general_purpose_bit_flag & 8) != 0) { -+ /* skip over data descriptor (harder than it sounds, due to signature -+ * ambiguity) -+ */ -+# define SIG 0x08074b50 -+# define LOW 0xffffffff -+ uch buf[12]; -+ unsigned shy = 12 - readbuf((char *)buf, 12); -+ ulg crc = shy ? 0 : makelong(buf); -+ ulg clen = shy ? 0 : makelong(buf + 4); -+ ulg ulen = shy ? 0 : makelong(buf + 8); /* or high clen if ZIP64 */ -+ if (crc == SIG && /* if not SIG, no signature */ -+ (G.lrec.crc32 != SIG || /* if not SIG, have signature */ -+ (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 -+ /* if not SIG, have signature */ -+ ))))) -+ /* skip four more bytes to account for signature */ -+ shy += 4 - readbuf((char *)buf, 4); -+ if (G.zip64) -+ shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */ -+ if (shy) -+ error = PK_ERR; -+ } -+ - return error; - - } /* end function extract_or_test_member() */ -diff --git a/globals.c b/globals.c -index fa8cca5..1e0f608 100644 ---- a/globals.c -+++ b/globals.c -@@ -181,6 +181,7 @@ Uz_Globs *globalsCtor() - # if (!defined(NO_TIMESTAMPS)) - uO.D_flag=1; /* default to '-D', no restoration of dir timestamps */ - # endif -+ G.cover = NULL; /* not allocated yet */ - #endif - - uO.lflag=(-1); -diff --git a/globals.h b/globals.h -index 11b7215..2bdcdeb 100644 ---- a/globals.h -+++ b/globals.h -@@ -260,12 +260,15 @@ 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 */ - int reported_backslash; /* extract.c static */ - int disk_full; - int newfile; -+ void **cover; /* used in extract.c for bomb detection */ - - int didCRlast; /* fileio static */ - ulg numlines; /* fileio static: number of lines printed */ -diff --git a/process.c b/process.c -index 1e9a1e1..d2e4dc3 100644 ---- a/process.c -+++ b/process.c -@@ -637,6 +637,13 @@ void free_G_buffers(__G) /* releases all memory allocated in global vars */ - } - #endif - -+ /* Free the cover span list and the cover structure. */ -+ if (G.cover != NULL) { -+ free(*(G.cover)); -+ free(G.cover); -+ G.cover = NULL; -+ } -+ - } /* end function free_G_buffers() */ - - -@@ -1890,6 +1897,8 @@ 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; - -@@ -1927,6 +1936,8 @@ int getZip64Data(__G__ ef_buf, ef_len) - #if 0 - break; /* Expect only one EF_PKSZ64 block. */ - #endif /* 0 */ -+ -+ G.zip64 = TRUE; - } - - /* Skip this extra field block. */ -diff --git a/unzip.h b/unzip.h -index 5b2a326..ed24a5b 100644 ---- a/unzip.h -+++ b/unzip.h -@@ -645,6 +645,7 @@ typedef struct _Uzp_cdir_Rec { - #define PK_NOZIP 9 /* zipfile not found */ - #define PK_PARAM 10 /* bad or illegal parameters specified */ - #define PK_FIND 11 /* no files found */ -+#define PK_BOMB 12 /* likely zip bomb */ - #define PK_DISK 50 /* disk full */ - #define PK_EOF 51 /* unexpected EOF */ - diff --git a/unzip-zipbomb-part3.patch b/unzip-zipbomb-part3.patch deleted file mode 100644 index 3b8d67b..0000000 --- a/unzip-zipbomb-part3.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 6d351831be705cc26d897db44f878a978f4138fc Mon Sep 17 00:00:00 2001 -From: Mark Adler -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; - - diff --git a/unzip-zipbomb-part4.patch b/unzip-zipbomb-part4.patch deleted file mode 100644 index beffa2c..0000000 --- a/unzip-zipbomb-part4.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 5e2efcd633a4a1fb95a129a75508e7d769e767be Mon Sep 17 00:00:00 2001 -From: Mark Adler -Date: Sun, 9 Feb 2020 20:36:28 -0800 -Subject: [PATCH] Fix bug in UZbunzip2() 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 -bzip2-compressed file was unzipped. This commit remedies that. ---- - extract.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/extract.c b/extract.c -index d9866f9..0cb7bfc 100644 ---- a/extract.c -+++ b/extract.c -@@ -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 deleted file mode 100644 index ca6a43a..0000000 --- a/unzip-zipbomb-part5.patch +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index 3dce6e3..0000000 --- a/unzip-zipbomb-part6.patch +++ /dev/null @@ -1,95 +0,0 @@ -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-zipbomb-part7.patch b/unzip-zipbomb-part7.patch deleted file mode 100644 index 4edc152..0000000 --- a/unzip-zipbomb-part7.patch +++ /dev/null @@ -1,172 +0,0 @@ -From af0d07f95809653b669d88aa0f424c6d5aa48ba0 Mon Sep 17 00:00:00 2001 -From: Mark Adler -Date: Sat, 2 Jul 2022 14:35:04 -0700 -Subject: [PATCH] Be more liberal in the acceptance of data descriptors. - -Previously the zip64 flag determined the size of the lengths in the -data descriptor. This is compliant with the zip format. However, a -bug in the Java zip library results in an incorrect setting of that -flag. This commit permits either 32-bit or 64-bit lengths, auto- -detecting which it is, which works around the Java bug. ---- - extract.c | 146 +++++++++++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 123 insertions(+), 23 deletions(-) - -diff --git a/extract.c b/extract.c -index 878817d..b1c74df 100644 ---- a/extract.c -+++ b/extract.c -@@ -2173,30 +2173,130 @@ static int extract_or_test_member(__G) /* return PK-type error code */ - undefer_input(__G); - - if ((G.lrec.general_purpose_bit_flag & 8) != 0) { -- /* skip over data descriptor (harder than it sounds, due to signature -- * ambiguity) -- */ --# define SIG 0x08074b50 --# define LOW 0xffffffff -- uch buf[12]; -- unsigned shy = 12 - readbuf((char *)buf, 12); -- ulg crc = shy ? 0 : makelong(buf); -- ulg clen = shy ? 0 : makelong(buf + 4); -- ulg ulen = shy ? 0 : makelong(buf + 8); /* or high clen if ZIP64 */ -- if (crc == SIG && /* if not SIG, no signature */ -- (G.lrec.crc32 != SIG || /* if not SIG, have signature */ -- (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.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.pInfo->zip64) -- shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */ -- if (shy) -+ // Skip over the data descriptor. We need to correctly position the -+ // read pointer after the data descriptor for the proper detection of -+ // overlapped zip file components. -+ // -+ // We need to resolve an ambiguity over four possible data descriptor -+ // formats. We check for all four, and pick the longest match. The data -+ // descriptor can have a signature or not, and it can use four or -+ // eight-byte lengths. The zip format requires resolving the ambiguity -+ // of a signature or not, but it uses the zip64 flag to determine -+ // whether the lengths are four or eight bytes. However there is a bug -+ // in the Java zip library that applies the wrong value of that flag. -+ // This works around that bug by always trying both length formats. -+ // -+ // So why the longest match? And does this resolve the ambiguity? No, -+ // it doesn't definitively resolve the ambiguity. However choosing the -+ // longest match at least resolves it for a normal zip file, where the -+ // bytes following the data descriptor must be another zip signature -+ // that is not a data descriptor signature. There are a few specific -+ // cases for which more than one of the formats will match the given -+ // CRC and lengths. The most plausible is between four and eight-byte -+ // lengths, either with or without a signature. That only occurs for an -+ // entry with an uncompressed size of zero. We consider the data -+ // descriptor to be a vector of four-byte values. Then the possible -+ // data descriptors are [(s) 0 c 0] and [(s) 0 c 0 0 0], where (s) is -+ // the optional signature, and c is the compressed length. c would be -+ // two for the Deflate compressed data format. These look the same, so -+ // if the file contains [(s) 0 c 0 0 0], then we cannot discriminate -+ // them. However if the data descriptor was intended to be [(s) 0 c 0], -+ // then it has been followed by eight zero bytes in the zip file for -+ // some reason. For a normal zip file this cannot be the case. The data -+ // descriptor would always be immediately followed by another zip file -+ // signature, which is four bytes that are not zeros. The other cases -+ // where more than one format matches are vanishingly unlikely, but the -+ // longest match strategy resolves those as well in a normal zip file. -+ // Those pairs are [s s s] vs. [s s s s], [s s s] vs. [s s s 0 s 0], -+ // and [s s s s s] vs. [s s s s s s]. For all, s is the signature for a -+ // data descriptor. For the first two we have an entry whose CRC, -+ // compressed length, and uncompressed length are all equal (!), and -+ // are all equal to the signature (!!). If this occurs, clearly someone -+ // is messing with us. However the strategy works nonetheless. We see -+ // that if the shorter descriptor, [s s s] were what was intended, then -+ // it has been followed by either four zero bytes or a data descriptor -+ // signature. Neither can occur for a normal zip file, where it must be -+ // followed by a signature that is not a data descriptor signature. So -+ // the longest match is the correct choice. The final case is outright -+ // insane, since the compressed and uncompressed lengths are the data -+ // descriptor signature repeated twice to make a 64-bit length, which -+ // is about 6e17. The largest drive available as I write this is 100TB, -+ // which is one six thousandth of that length. If I apply Moore's law -+ // to drive capacity, we might get to 6e17 about 25 years from now. If -+ // this code is still in use then (I've seen other code I've written in -+ // use for over 30 years), then we're still in luck. A data descriptor -+ // cannot be followed by a data descriptor signature in a normal zip -+ // file. The longest match strategy continues to work. -+ // -+ // So what is a not normal zip file, where these assumptions might fall -+ // apart? zip files have been used in a non-standard way as a poor -+ // substitute for a file system, with entries deleted and perhaps -+ // others replacing them partially, with fragmented zip files being the -+ // result. Then all bets are off as to what might or might not follow a -+ // data descriptor. Though if this sort of data descriptor ambiguity -+ // falls in one of those gaps, then there should be no adverse -+ // consequences for picking the unintended one. -+ int len = 0; -+# define SIG 0x08074b50 // optional data descriptor signature -+#ifdef LARGE_FILE_SUPPORT -+ uch buf[24]; -+ int got = readbuf((char *)buf, sizeof(buf)); -+ if (got >= 24 && makelong(buf) == SIG && -+ makelong(buf + 4) == G.lrec.crc32 && -+ makeint64(buf + 8) == G.lrec.csize && -+ makeint64(buf + 16) == G.lrec.ucsize) -+ // Have a data descriptor with a signature and 64-bit lengths. -+ len = 24; -+ else if (got >= 20 && makelong(buf) == G.lrec.crc32 && -+ makeint64(buf + 4) == G.lrec.csize && -+ makeint64(buf + 12) == G.lrec.ucsize) -+ // Have a data descriptor with no signature and 64-bit lengths. -+ len = 20; -+ else if ((G.lrec.csize >> 32) == 0 && (G.lrec.ucsize >> 32) == 0) -+ // Both lengths are short enough to fit in 32 bits. -+#else -+ uch buf[16]; -+ int got = readbuf((char *)buf, sizeof(buf)); -+#endif -+ { -+ if (got >= 16 && makelong(buf) == SIG && -+ makelong(buf + 4) == G.lrec.crc32 && -+ makelong(buf + 8) == G.lrec.csize && -+ makelong(buf + 12) == G.lrec.ucsize) -+ // Have a data descriptor with a signature and 32-bit lengths. -+ len = 16; -+ else if (got >= 12 && makelong(buf) == G.lrec.crc32 && -+ makelong(buf + 4) == G.lrec.csize && -+ makelong(buf + 8) == G.lrec.ucsize) -+ // Have a data descriptor with no signature and 32-bit lengths. -+ len = 12; -+ } -+ if (len == 0) -+ // There is no data descriptor that matches the entry CRC and -+ // length values. - error = PK_ERR; -+ -+ // Back up got-len bytes, to position the read pointer after the data -+ // descriptor. Or to where the data descriptor was supposed to be, in -+ // the event none was found. -+ int back = got - len; -+ if (G.incnt + back > INBUFSIZ) { -+ // Need to load the preceding buffer. We've been here before. -+ G.cur_zipfile_bufstart -= INBUFSIZ; -+#ifdef USE_STRM_INPUT -+ zfseeko(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET); -+#else /* !USE_STRM_INPUT */ -+ zlseek(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET); -+#endif /* ?USE_STRM_INPUT */ -+ read(G.zipfd, (char *)G.inbuf, INBUFSIZ); -+ G.incnt -= INBUFSIZ - back; -+ G.inptr += INBUFSIZ - back; -+ } -+ else { -+ // Back up within current buffer. -+ G.incnt += back; -+ G.inptr -= back; -+ } - } - - return error; diff --git a/unzip-zipbomb-switch.patch b/unzip-zipbomb-switch.patch deleted file mode 100644 index e355afd..0000000 --- a/unzip-zipbomb-switch.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 5b44c818b96193b3e240f38f61985fa2bc780eb7 Mon Sep 17 00:00:00 2001 -From: Jakub Martisko -Date: Tue, 30 Nov 2021 15:42:17 +0100 -Subject: [PATCH] Add an option to disable the zipbomb detection - -This can be done by settting a newly introduced environment variable -UNZIP_DISABLE_ZIPBOMB_DETECTION to {TRUE,True,true}. If the variable is unset, or -set to any other value the zipbomb detection is left enabled. - -Example: - UNZIP_DISABLE_ZIPBOMB_DETECTION=True unzip ./zbsm.zip -d ./test ---- - extract.c | 85 ++++++++++++++++++++++++++++++------------------------- - unzip.c | 15 ++++++++-- - unzip.h | 1 + - 3 files changed, 60 insertions(+), 41 deletions(-) - -diff --git a/extract.c b/extract.c -index 878817d..3e58071 100644 ---- a/extract.c -+++ b/extract.c -@@ -322,7 +322,8 @@ static ZCONST char Far BadExtraFieldCRC[] = - static ZCONST char Far NotEnoughMemCover[] = - "error: not enough memory for bomb detection\n"; - static ZCONST char Far OverlappedComponents[] = -- "error: invalid zip file with overlapped components (possible zip bomb)\n"; -+ "error: invalid zip file with overlapped components (possible zip bomb)\n \ -+To unzip the file anyway, rerun the command with UNZIP_DISABLE_ZIPBOMB_DETECTION=TRUE environmnent variable\n"; - - - -@@ -502,35 +503,37 @@ int extract_or_test_files(__G) /* return PK-type error code */ - 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) { -+ if (uO.zipbomb == TRUE) { -+ if (G.cover == NULL) { - G.cover = malloc(sizeof(cover_t)); - if (G.cover == NULL) { -- Info(slide, 0x401, ((char *)slide, -- LoadFarString(NotEnoughMemCover))); -- return PK_MEM; -+ Info(slide, 0x401, ((char *)slide, -+ LoadFarString(NotEnoughMemCover))); -+ return PK_MEM; - } - ((cover_t *)G.cover)->span = NULL; - ((cover_t *)G.cover)->max = 0; -- } -- ((cover_t *)G.cover)->num = 0; -- if (cover_add((cover_t *)G.cover, -- G.extra_bytes + G.ecrec.offset_start_central_directory, -- G.extra_bytes + G.ecrec.offset_start_central_directory + -- G.ecrec.size_central_directory) != 0) { -+ } -+ ((cover_t *)G.cover)->num = 0; -+ if (cover_add((cover_t *)G.cover, -+ G.extra_bytes + G.ecrec.offset_start_central_directory, -+ G.extra_bytes + G.ecrec.offset_start_central_directory + -+ G.ecrec.size_central_directory) != 0) { - Info(slide, 0x401, ((char *)slide, -- LoadFarString(NotEnoughMemCover))); -+ 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) { -+ } -+ 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))); -+ LoadFarString(OverlappedComponents))); - return PK_BOMB; -+ } - } - - /*--------------------------------------------------------------------------- -@@ -1222,10 +1225,12 @@ static int extract_or_test_entrylist(__G__ numchunk, - - /* seek_zipf(__G__ pInfo->offset); */ - request = G.pInfo->offset + G.extra_bytes; -- if (cover_within((cover_t *)G.cover, request)) { -+ if (uO.zipbomb == TRUE) { -+ if (cover_within((cover_t *)G.cover, request)) { - Info(slide, 0x401, ((char *)slide, -- LoadFarString(OverlappedComponents))); -+ LoadFarString(OverlappedComponents))); - return PK_BOMB; -+ } - } - inbuf_offset = request % INBUFSIZ; - bufstart = request - inbuf_offset; -@@ -1758,17 +1763,19 @@ reprompt: - return IZ_CTRLC; /* cancel operation by user request */ - } - #endif -- error = cover_add((cover_t *)G.cover, request, -- G.cur_zipfile_bufstart + (G.inptr - G.inbuf)); -- if (error < 0) { -+ if (uO.zipbomb == TRUE) { -+ error = cover_add((cover_t *)G.cover, request, -+ G.cur_zipfile_bufstart + (G.inptr - G.inbuf)); -+ if (error < 0) { - Info(slide, 0x401, ((char *)slide, -- LoadFarString(NotEnoughMemCover))); -+ LoadFarString(NotEnoughMemCover))); - return PK_MEM; -- } -- if (error != 0) { -+ } -+ if (error != 0) { - Info(slide, 0x401, ((char *)slide, -- LoadFarString(OverlappedComponents))); -+ LoadFarString(OverlappedComponents))); - return PK_BOMB; -+ } - } - #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */ - UserStop(); -@@ -2171,8 +2178,8 @@ static int extract_or_test_member(__G) /* return PK-type error code */ - } - - undefer_input(__G); -- -- if ((G.lrec.general_purpose_bit_flag & 8) != 0) { -+ if (uO.zipbomb == TRUE) { -+ if ((G.lrec.general_purpose_bit_flag & 8) != 0) { - // Skip over the data descriptor. We need to correctly position the - // read pointer after the data descriptor for the proper detection of - // overlapped zip file components. -@@ -2189,8 +2196,8 @@ static int extract_or_test_member(__G) /* return PK-type error code */ - G.incnt += back; - G.inptr -= back; - } -+ } - } -- - return error; - - } /* end function extract_or_test_member() */ -diff --git a/unzip.c b/unzip.c -index 8dbfc95..abb3644 100644 ---- a/unzip.c -+++ b/unzip.c -@@ -1329,10 +1329,9 @@ int uz_opts(__G__ pargc, pargv) - int *pargc; - char ***pargv; - { -- char **argv, *s; -+ char **argv, *s, *zipbomb_envar; - int argc, c, error=FALSE, negative=0, showhelp=0; - -- - argc = *pargc; - argv = *pargv; - -@@ -1923,6 +1922,18 @@ opts_done: /* yes, very ugly...but only used by UnZipSFX with -x xlist */ - else - G.extract_flag = TRUE; - -+ /* Disable the zipbomb detection, this is the only option set only via the shell variables but it should at least not clash with something in the future. */ -+ zipbomb_envar = getenv("UNZIP_DISABLE_ZIPBOMB_DETECTION"); -+ uO.zipbomb = TRUE; -+ if (zipbomb_envar != NULL) { -+ /* strcasecmp might be a better approach here but it is POSIX-only */ -+ if ((strcmp ("TRUE", zipbomb_envar) == 0) -+ || (strcmp ("True", zipbomb_envar) == 0) -+ || (strcmp ("true",zipbomb_envar) == 0)) { -+ uO.zipbomb = FALSE; -+ } -+ } -+ - *pargc = argc; - *pargv = argv; - return PK_OK; -diff --git a/unzip.h b/unzip.h -index ed24a5b..e7665e8 100644 ---- a/unzip.h -+++ b/unzip.h -@@ -559,6 +559,7 @@ typedef struct _UzpOpts { - #ifdef UNIX - int cflxflag; /* -^: allow control chars in extracted filenames */ - #endif -+ int zipbomb; - #endif /* !FUNZIP */ - } UzpOpts; - --- -2.33.0 - diff --git a/unzip.spec b/unzip.spec index ed8ee48..fda862f 100644 --- a/unzip.spec +++ b/unzip.spec @@ -1,3 +1,4 @@ + # Settings for EL <= 7 %if 0%{?rhel} && 0%{?rhel} <= 7 %{!?__global_ldflags: %global __global_ldflags -Wl,-z,relro} @@ -6,8 +7,9 @@ Summary: A utility for unpacking zip files Name: unzip Version: 6.0 -Release: 71%{?dist} -License: Info-ZIP +Release: 37%{?dist} +License: BSD +Group: Applications/Archiving Source: http://downloads.sourceforge.net/infozip/unzip60.tar.gz # Not sent to upstream. @@ -54,39 +56,12 @@ Patch21: 0001-Fix-CVE-2016-9844-rhbz-1404283.patch # restore unix timestamp accurately Patch22: unzip-6.0-timestamp.patch - # fix possible heap based stack overflow in passwd protected files Patch23: unzip-6.0-cve-2018-1000035-heap-based-overflow.patch -Patch24: unzip-6.0-cve-2018-18384.patch -# covscan issues -Patch25: unzip-6.0-COVSCAN-fix-unterminated-string.patch - -Patch26: unzip-zipbomb-part1.patch -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 -Patch33: unzip-zipbomb-part7.patch -Patch34: unzip-zipbomb-switch.patch - -Patch35: unzip-gnu89-build.patch -Patch36: unzip-6.0-wcstombs-fortify.patch - -Patch37: unzip-6.0-fix-warning-messages-on-big-files.patch -Patch38: unzip-6.0-sast.patch -Patch39: unzip-6.0-RHEL-86228.patch -#From Debian -Patch40: unzip-6.0-CVE-2022-0529-and-0530.patch - - - -URL: http://infozip.sourceforge.net -BuildRequires: make -BuildRequires: bzip2-devel, gcc +URL: http://www.info-zip.org/UnZip.html +BuildRequires: bzip2-devel %description The unzip utility is used to list, test, or extract files from a zip @@ -101,190 +76,54 @@ a zip archive. %prep %setup -q -n unzip60 -%patch -P1 -p1 -%patch -P2 -p1 -%patch -P3 -p1 -%patch -P4 -p1 -%patch -P5 -p1 -%patch -P6 -p1 -%patch -P7 -p1 -%patch -P8 -p1 -%patch -P9 -p1 -%patch -P10 -p1 -%patch -P11 -p1 -%patch -P12 -p1 -%patch -P13 -p1 -%patch -P14 -p1 -%patch -P15 -p1 -%patch -P16 -p1 -%patch -P17 -p1 -%patch -P18 -p1 -%patch -P19 -p1 -%patch -P20 -p1 -%patch -P21 -p1 -%patch -P22 -p1 -%patch -P23 -p1 -%patch -P24 -p1 -%patch -P25 -p1 - -%patch -P26 -p1 -%patch -P27 -p1 -%patch -P28 -p1 -%patch -P29 -p1 -%patch -P30 -p1 -%patch -P31 -p1 -%patch -P32 -p1 -%patch -P33 -p1 -%patch -P34 -p1 -%patch -P35 -p1 -%patch -P36 -p1 -%patch -P37 -p1 -%patch -P38 -p1 -%patch -P39 -p1 -%patch -P40 -p1 +%patch1 -p1 -b .bzip2-configure +%patch2 -p1 -b .exec-shield +%patch3 -p1 -b .close +%patch4 -p1 -b .attribs-overflow +%patch5 -p1 -b .configure +%patch6 -p1 -b .manpage-fix +%patch7 -p1 -b .recmatch +%patch8 -p1 -b .symlink +%patch9 -p1 -b .caseinsensitive +%patch10 -p1 -b .format-secure +%patch11 -p1 -b .valgrind +%patch12 -p1 -b .x-option +%patch13 -p1 -b .overflow +%patch14 -p1 -b .cve-2014-8139 +%patch15 -p1 -b .cve-2014-8140 +%patch16 -p1 -b .cve-2014-8141 +%patch17 -p1 -b .overflow-long-fsize +%patch18 -p1 -b .heap-overflow-infloop +%patch19 -p1 -b .utf +%patch20 -p1 -b .utf-print +%patch21 -p1 -b .cve-2016-9844 +%patch22 -p1 -b .timestamp +%patch23 -p1 -b .cve-2018-1000035 %build # IZ_HAVE_UXUIDGID is needed for right functionality of unzip -X -# NOMEMCPY solve problem with memory overlapping - decompression is slowly, +# NOMEMCPY solve problem with memory overlapping - decomression is slowly, # but successfull. -%make_build -f unix/Makefile CF_NOOPT="-I. -DUNIX $RPM_OPT_FLAGS -DNOMEMCPY -DIZ_HAVE_UXUIDGID -DNO_LCHMOD" \ - LFLAGS2="%{?__global_ldflags}" generic_gcc +make -f unix/Makefile CF_NOOPT="-I. -DUNIX $RPM_OPT_FLAGS -DNOMEMCPY -DIZ_HAVE_UXUIDGID -DNO_LCHMOD" \ + LFLAGS2="%{?__global_ldflags}" generic_gcc %{?_smp_mflags} %install -make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT%{_mandir}/man1 INSTALL="cp -p" install +rm -rf $RPM_BUILD_ROOT +make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT/%{_mandir}/man1 INSTALL="cp -p" install %files +%defattr(-,root,root) %license LICENSE COPYING.OLD %doc README BUGS %{_bindir}/* %{_mandir}/*/* %changelog -* Wed Jul 22 2026 Jakub Martisko - 6.0-71 -- Port some RHEL downstream patches to fedora -- Fixes for RHEL-86228, RHEL-45997 + some issues found by coverity and other scans -- Fixes for CVE-2022-0529 and 2022-0530 (Thanks Stewart Smith for the Heads up about these) - -* Fri Jul 17 2026 Fedora Release Engineering - 6.0-70 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild - -* Sat Jan 17 2026 Fedora Release Engineering - 6.0-69 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild - -* Wed Aug 20 2025 Jakub Martisko - 6.0-68 -- Another zipmbomb patch -Resolves: rhbz#2360938 - -* Fri Jul 25 2025 Fedora Release Engineering - 6.0-67 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Sun Jan 19 2025 Fedora Release Engineering - 6.0-66 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Mon Nov 25 2024 Jakub Martisko - 6.0-65 -- Zipinfo: remove the extra %c that cause invalid reads -- Zipinfo: fix the whitespace formating of the help message -Related: RHEL-59972 - -* Sat Jul 20 2024 Fedora Release Engineering - 6.0-64 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Sat Jan 27 2024 Fedora Release Engineering - 6.0-63 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Sat Jul 22 2023 Fedora Release Engineering - 6.0-62 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Thu Apr 13 2023 Lukáš Zaoral - 6.0-61 -- migrate to SPDX license format - -* Wed Jan 25 2023 Siddhesh Poyarekar - 6.0-60 -- Fix length passed to wcstombs call (#2164068) - -* Sat Jan 21 2023 Fedora Release Engineering - 6.0-59 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Wed Nov 09 2022 Jakub Martisko - 6.0-59 -- Rebuild with the -std=gnu89 flag -Resolves: rhbz#1750694 - -* Sat Jul 23 2022 Fedora Release Engineering - 6.0-58 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Sat Jan 22 2022 Fedora Release Engineering - 6.0-57 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Thu Dec 16 2021 Jakub Martisko - 6.0-56 -- Update the manpage regarding the 6.0-55 - -* Mon Dec 13 2021 Jakub Martisko - 6.0-55 -- Allow to opt-out of the zipbomb detection - -* Tue Nov 09 2021 Jakub Martisko - 6.0-54 -- Update the URL - -* Fri Jul 23 2021 Fedora Release Engineering - 6.0-53 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* 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 - -* Wed Jan 27 2021 Fedora Release Engineering - 6.0-50 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Wed Jul 29 2020 Fedora Release Engineering - 6.0-49 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Tue Jul 14 2020 Tom Stellard - 6.0-48 -- Use make macros -- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro - -* Fri Jan 31 2020 Fedora Release Engineering - 6.0-47 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Mon Nov 18 2019 Jakub Martisko - 6.0-46 -- Mention the zipbomb exit code in the manpage - Related: CVE-2019-13232 - -* Wed Oct 23 2019 Jakub Martisko - 6.0-45 -- Fix possible zipbomb in unzip - Resolves: CVE-2019-13232 - -* Sat Jul 27 2019 Fedora Release Engineering - 6.0-44 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Sun Feb 03 2019 Fedora Release Engineering - 6.0-43 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Thu Nov 08 2018 Jakub Martisko - 6.0-42 -- fix several possibly unterminated strings - When copying to OEM_CP and ISO_CP strings, the string could end unterminated - (stncpy does not append '\0'). - -* Thu Nov 08 2018 Jakub Martisko - 6.0-41 -- Fix CVE-2018-18384 - Resolves: CVE-2018-18384 - -* Sat Jul 14 2018 Fedora Release Engineering - 6.0-40 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Thu Mar 01 2018 Jakub Martisko - 6.0-39 -- Add gcc to buildrequires - -* Tue Feb 13 2018 Jakub Martisko - 6.0-38 +* Tue Feb 13 2018 Jakub Martisko - 6.0-37 - Fix CVE-2018-1000035 - heap based buffer overflow when opening password protected files. Resolves: 1537043 -* Fri Feb 09 2018 Fedora Release Engineering - 6.0-37 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - * Thu Aug 03 2017 Fedora Release Engineering - 6.0-36 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild