From e27ef53794f9e90abacfa0bd10f47509b7944330 Mon Sep 17 00:00:00 2001 From: Albert Schwarzkopf Date: Sat, 24 Dec 2022 15:23:28 +0100 Subject: [PATCH] unzip: sync patches from Fedora etc. Sync a number of (CVE-related) patches from other distros: unzip-zipbomb-part{4,5,6}.patch: Fedora CVE-2021-4217.patch: Archlinux CVE-2022-0529.patch,CVE-2022-0530.patch: Ubuntu --- srcpkgs/unzip/patches/CVE-2021-4217.patch | 19 ++++ srcpkgs/unzip/patches/CVE-2022-0529.patch | 37 ++++++++ srcpkgs/unzip/patches/CVE-2022-0530.patch | 28 ++++++ srcpkgs/unzip/patches/series | 7 ++ ...e-overlap-detection-on-32bit-systems.patch | 50 ++++++++++ .../unzip/patches/unzip-zipbomb-part4.patch | 25 +++++ .../unzip/patches/unzip-zipbomb-part5.patch | 26 +++++ .../unzip/patches/unzip-zipbomb-part6.patch | 95 +++++++++++++++++++ srcpkgs/unzip/template | 2 +- 9 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 srcpkgs/unzip/patches/CVE-2021-4217.patch create mode 100644 srcpkgs/unzip/patches/CVE-2022-0529.patch create mode 100644 srcpkgs/unzip/patches/CVE-2022-0530.patch create mode 100644 srcpkgs/unzip/patches/unzip-6.0-fix-false-overlap-detection-on-32bit-systems.patch create mode 100644 srcpkgs/unzip/patches/unzip-zipbomb-part4.patch create mode 100644 srcpkgs/unzip/patches/unzip-zipbomb-part5.patch create mode 100644 srcpkgs/unzip/patches/unzip-zipbomb-part6.patch diff --git a/srcpkgs/unzip/patches/CVE-2021-4217.patch b/srcpkgs/unzip/patches/CVE-2021-4217.patch new file mode 100644 index 000000000000..37b83cca0575 --- /dev/null +++ b/srcpkgs/unzip/patches/CVE-2021-4217.patch @@ -0,0 +1,19 @@ +diff --git a/process.c b/process.c +index d2a846e..cba2463 100644 +--- a/process.c ++++ b/process.c +@@ -2064,10 +2064,14 @@ int getUnicodeData(__G__ ef_buf, ef_len) + G.unipath_checksum = makelong(offset + ef_buf); + offset += 4; + ++ if (!G.filename_full) { ++ /* Check if we have a unicode extra section but no filename set */ ++ return PK_ERR; ++ } ++ + /* + * Compute 32-bit crc + */ +- + chksum = crc32(chksum, (uch *)(G.filename_full), + strlen(G.filename_full)); diff --git a/srcpkgs/unzip/patches/CVE-2022-0529.patch b/srcpkgs/unzip/patches/CVE-2022-0529.patch new file mode 100644 index 000000000000..f38abf414d2e --- /dev/null +++ b/srcpkgs/unzip/patches/CVE-2022-0529.patch @@ -0,0 +1,37 @@ +From: Enrico Zini +Subject: Fix wide string conversion +Bug-Debian: https://bugs.debian.org/1010355 +X-Debian-version: 6.0-27 + +--- unzip-6.0.orig/process.c ++++ unzip-6.0/process.c +@@ -2511,13 +2511,15 @@ char *wide_to_local_string(wide_string, + char buf[9]; + char *buffer = NULL; + char *local_string = NULL; ++ size_t buffer_size; + + 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; ++ if ((buffer = (char *)malloc(buffer_size)) == NULL) { + return NULL; + } + +@@ -2556,7 +2558,11 @@ char *wide_to_local_string(wide_string, + /* 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 = strlen(buffer); ++ size_t escape_string_len = strlen(escape_string); ++ if (buffer_len + escape_string_len + 1 > buffer_size) ++ escape_string_len = buffer_size - buffer_len - 1; ++ strncat(buffer, escape_string, escape_string_len); + free(escape_string); + } + } diff --git a/srcpkgs/unzip/patches/CVE-2022-0530.patch b/srcpkgs/unzip/patches/CVE-2022-0530.patch new file mode 100644 index 000000000000..5e7627abc2ea --- /dev/null +++ b/srcpkgs/unzip/patches/CVE-2022-0530.patch @@ -0,0 +1,28 @@ +From: Enrico Zini +Subject: Fix null pointer dereference on invalid UTF-8 input +Bug-Debian: https://bugs.debian.org/1010355 +X-Debian-version: 6.0-27 + +--- unzip-6.0.orig/fileio.c ++++ unzip-6.0/fileio.c +@@ -2364,6 +2364,9 @@ int do_string(__G__ length, option) /* + /* convert UTF-8 to local character set */ + fn = utf8_to_local_string(G.unipath_filename, + G.unicode_escape_all); ++ if (fn == NULL) ++ return PK_ERR; ++ + /* make sure filename is short enough */ + if (strlen(fn) >= FILNAMSIZ) { + fn[FILNAMSIZ - 1] = '\0'; +--- unzip-6.0.orig/process.c ++++ unzip-6.0/process.c +@@ -2615,6 +2615,8 @@ char *utf8_to_local_string(utf8_string, + int escape_all; + { + zwchar *wide = utf8_to_wide_string(utf8_string); ++ if (wide == NULL) ++ return NULL; + char *loc = wide_to_local_string(wide, escape_all); + free(wide); + return loc; diff --git a/srcpkgs/unzip/patches/series b/srcpkgs/unzip/patches/series index cd67627dfc41..c4f3fc1b2bda 100644 --- a/srcpkgs/unzip/patches/series +++ b/srcpkgs/unzip/patches/series @@ -27,3 +27,10 @@ unzip-zipbomb-part1.patch unzip-zipbomb-part2.patch unzip-zipbomb-part3.patch unzip-zipbomb-manpage.patch +unzip-zipbomb-part4.patch +unzip-zipbomb-part5.patch +unzip-zipbomb-part6.patch +CVE-2021-4217.patch +CVE-2022-0529.patch +CVE-2022-0530.patch +unzip-6.0-fix-false-overlap-detection-on-32bit-systems.patch diff --git a/srcpkgs/unzip/patches/unzip-6.0-fix-false-overlap-detection-on-32bit-systems.patch b/srcpkgs/unzip/patches/unzip-6.0-fix-false-overlap-detection-on-32bit-systems.patch new file mode 100644 index 000000000000..ad6a157c568a --- /dev/null +++ b/srcpkgs/unzip/patches/unzip-6.0-fix-false-overlap-detection-on-32bit-systems.patch @@ -0,0 +1,50 @@ +From 13f0260beae851f7d5dd96e9ef757d8d6d7daac1 Mon Sep 17 00:00:00 2001 +From: Mark Adler +Date: Sun, 9 Feb 2020 07:20:13 -0800 +Subject: [PATCH] Fix false overlapped components detection on 32-bit systems. + +32-bit systems with ZIP64_SUPPORT enabled could have different +size types for zoff_t and zusz_t. That resulted in bad parameter +passing to the bound tracking functions, itself due to the lack of +use of C function prototypes in unzip. This commit assures that +parameters are cast properly for those calls. + +This problem occurred only for ill-chosen make options, which give +a 32-bit zoff_t. A proper build will result in a zoff_t of 64 bits, +even on 32-bit systems. +--- + extract.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/extract.c b/extract.c +index 1b73cb0..d9866f9 100644 +--- a/extract.c ++++ b/extract.c +@@ -329,7 +329,7 @@ static ZCONST char Far OverlappedComponents[] = + + + /* A growable list of spans. */ +-typedef zoff_t bound_t; ++typedef zusz_t bound_t; + typedef struct { + bound_t beg; /* start of the span */ + bound_t end; /* one past the end of the span */ +@@ -518,7 +518,8 @@ int extract_or_test_files(__G) /* return PK-type error code */ + return PK_MEM; + } + if ((G.extra_bytes != 0 && +- cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) || ++ cover_add((cover_t *)G.cover, ++ (bound_t)0, (bound_t)G.extra_bytes) != 0) || + (G.ecrec.have_ecr64 && + cover_add((cover_t *)G.cover, G.ecrec.ec64_start, + G.ecrec.ec64_end) != 0) || +@@ -1216,7 +1217,7 @@ 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 (cover_within((cover_t *)G.cover, (bound_t)request)) { + Info(slide, 0x401, ((char *)slide, + LoadFarString(OverlappedComponents))); + return PK_BOMB; diff --git a/srcpkgs/unzip/patches/unzip-zipbomb-part4.patch b/srcpkgs/unzip/patches/unzip-zipbomb-part4.patch new file mode 100644 index 000000000000..beffa2c99872 --- /dev/null +++ b/srcpkgs/unzip/patches/unzip-zipbomb-part4.patch @@ -0,0 +1,25 @@ +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/srcpkgs/unzip/patches/unzip-zipbomb-part5.patch b/srcpkgs/unzip/patches/unzip-zipbomb-part5.patch new file mode 100644 index 000000000000..ca6a43a7c5be --- /dev/null +++ b/srcpkgs/unzip/patches/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/srcpkgs/unzip/patches/unzip-zipbomb-part6.patch b/srcpkgs/unzip/patches/unzip-zipbomb-part6.patch new file mode 100644 index 000000000000..3dce6e3421e1 --- /dev/null +++ b/srcpkgs/unzip/patches/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/srcpkgs/unzip/template b/srcpkgs/unzip/template index 94c85876e9d6..a625a153bd09 100644 --- a/srcpkgs/unzip/template +++ b/srcpkgs/unzip/template @@ -1,7 +1,7 @@ # Template file for 'unzip' pkgname=unzip version=6.0 -revision=14 +revision=15 makedepends="bzip2-devel" short_desc="List, test and extract compressed files in a ZIP archive" maintainer="Enno Boland "