From 53f96085caff90be3a3fa087b352aab0b206447a Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 10 May 2022 03:19:27 -0400 Subject: [PATCH] import unzip-6.0-46.el8 --- SOURCES/unzip-zipbomb-manpage.patch | 2 +- SOURCES/unzip-zipbomb-switch.patch | 215 ++++++++++++++++++++++++++++ SPECS/unzip.spec | 11 +- 3 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 SOURCES/unzip-zipbomb-switch.patch diff --git a/SOURCES/unzip-zipbomb-manpage.patch b/SOURCES/unzip-zipbomb-manpage.patch index cdeeea5..bcee827 100644 --- a/SOURCES/unzip-zipbomb-manpage.patch +++ b/SOURCES/unzip-zipbomb-manpage.patch @@ -16,7 +16,7 @@ index 21816d1..4d66073 100644 .IP 11 no matching files were found. +.IP 12 -+invalid zip file with overlapped components (possible zip bomb). ++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 diff --git a/SOURCES/unzip-zipbomb-switch.patch b/SOURCES/unzip-zipbomb-switch.patch new file mode 100644 index 0000000..c6d33c0 --- /dev/null +++ b/SOURCES/unzip-zipbomb-switch.patch @@ -0,0 +1,215 @@ +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 data descriptor (harder than it sounds, due to signature + * ambiguity) + */ +@@ -2189,16 +2196,16 @@ static int extract_or_test_member(__G) /* return PK-type error code */ + ((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 */ ++ /* if not SIG, have signature */ + ))))) +- /* skip four more bytes to account for signature */ +- shy += 4 - readbuf((char *)buf, 4); ++ /* 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 */ ++ shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */ + if (shy) +- error = PK_ERR; ++ error = PK_ERR; ++ } + } +- + 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/SPECS/unzip.spec b/SPECS/unzip.spec index 33b73be..45d6b59 100644 --- a/SPECS/unzip.spec +++ b/SPECS/unzip.spec @@ -7,7 +7,7 @@ Summary: A utility for unpacking zip files Name: unzip Version: 6.0 -Release: 45%{?dist} +Release: 46%{?dist} License: BSD Group: Applications/Archiving Source: http://downloads.sourceforge.net/infozip/unzip60.tar.gz @@ -74,6 +74,8 @@ Patch30: unzip-zipbomb-manpage.patch Patch31: unzip-zipbomb-part4.patch Patch32: unzip-zipbomb-part5.patch Patch33: unzip-zipbomb-part6.patch + +Patch34: unzip-zipbomb-switch.patch URL: http://www.info-zip.org/UnZip.html BuildRequires: bzip2-devel @@ -126,6 +128,7 @@ a zip archive. %patch31 -p1 %patch32 -p1 %patch33 -p1 +%patch34 -p1 %build # IZ_HAVE_UXUIDGID is needed for right functionality of unzip -X @@ -146,12 +149,14 @@ make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT/%{ %{_mandir}/*/* %changelog +* Thu Dec 16 2021 Jakub Martisko - 6.0-46 +- Add environment variable that disables the zipbomb detection +- Resolves: rhbz#2020320 + * Tue Nov 24 2020 Jakub Martisko - 6.0-45 Fix a false positive zipbomb detection Related: 1954649 Related: 1953565 -Related: 1969876 -Resolves: 1970326 * Tue Nov 24 2020 Jakub Martisko - 6.0-44 * Fix out of memory errors while checking for zip-bombs