apply fixes for CVE-2022-0529 and CVE-2022-0530

from debian
ok tb mbuhl
This commit is contained in:
tj 2022-08-10 17:59:55 +00:00
parent 0586dde312
commit 9564521003
3 changed files with 164 additions and 20 deletions

View File

@ -5,7 +5,7 @@ COMMENT = extract, list & test files in a ZIP archive
VERSION = 6.0
DISTNAME = unzip${VERSION:S/.//}
PKGNAME = unzip-${VERSION}
REVISION = 15
REVISION = 16
CATEGORIES = archivers
MASTER_SITES = ${MASTER_SITE_SOURCEFORGE:=infozip/} \
ftp://ftp.info-zip.org/pub/infozip/src/

View File

@ -3,11 +3,21 @@ Fix CVE-2018-1000035: buffer overflow for password-protected archives
https://security-tracker.debian.org/tracker/CVE-2018-1000035
Fix CVE-2019-13232: a zip bomb using overlapped entries
https://github.com/madler/unzip/commit/47b3ceae397d21bf822bc2ac73052a4b1daf8e1c
Fix CVE-2022-0529 and CVE-2022-0530
https://bugs.debian.org/1010355
Index: fileio.c
--- fileio.c.orig
+++ fileio.c
@@ -176,6 +176,8 @@ static ZCONST char Far FilenameTooLongTrunc[] =
@@ -171,11 +171,15 @@ static ZCONST char Far ReadError[] = "error: zipfile
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";
@ -16,7 +26,7 @@ Index: fileio.c
#ifdef WINDLL
static ZCONST char Far DiskFullQuery[] =
@@ -530,8 +532,10 @@ void undefer_input(__G)
@@ -530,8 +534,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)
@ -28,7 +38,7 @@ Index: fileio.c
G.incnt = G.incnt_leftover + (int)G.csize;
G.inptr = G.inptr_leftover - (int)G.csize;
G.incnt_leftover = 0;
@@ -1580,7 +1584,11 @@ int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, ef
@@ -1580,7 +1586,11 @@ int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, ef
int r = IZ_PW_ENTERED;
char *m;
char *prompt;
@ -41,7 +51,7 @@ Index: fileio.c
#ifndef REENTRANT
/* tell picky compilers to shut up about "unused variable" warnings */
pG = pG;
@@ -1588,7 +1596,15 @@ int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, ef
@@ -1588,7 +1598,15 @@ int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, ef
if (*rcnt == 0) { /* First call for current entry */
*rcnt = 2;
@ -58,7 +68,7 @@ Index: fileio.c
sprintf(prompt, LoadFarString(PasswPrompt),
FnFilter1(zfn), FnFilter2(efn));
m = prompt;
@@ -2295,7 +2311,12 @@ int do_string(__G__ length, option) /* return PK-typ
@@ -2295,7 +2313,12 @@ int do_string(__G__ length, option) /* return PK-typ
if (readbuf(__G__ (char *)G.extra_field, length) == 0)
return PK_EOF;
/* Looks like here is where extra fields are read */
@ -72,3 +82,42 @@ Index: fileio.c
#ifdef UNICODE_SUPPORT
G.unipath_filename = NULL;
if (G.UzO.U_flag < 2) {
@@ -2340,16 +2363,30 @@ int do_string(__G__ length, option) /* return PK-typ
/* 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;
}
- /* replace filename with converted UTF-8 */
- strcpy(G.filename, fn);
- free(fn);
+ 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);
+ }
}
# endif /* UNICODE_WCHAR */
if (G.unipath_filename != G.filename_full)

View File

@ -9,6 +9,8 @@ Fix: restore uid and gid information when requested
Fix CVE-2019-13232: a zip bomb using overlapped entries
https://github.com/madler/unzip/commit/47b3ceae397d21bf822bc2ac73052a4b1daf8e1c
https://github.com/madler/unzip/commit/6d351831be705cc26d897db44f878a978f4138fc
Fix CVE-2022-0529 and CVE-2022-0530
https://bugs.debian.org/1010355
Index: process.c
--- process.c.orig
@ -20,7 +22,16 @@ Index: process.c
See the accompanying file LICENSE, version 2009-Jan-02 or later
(the contents of which are also included in unzip.h) for terms of use.
@@ -637,6 +637,13 @@ void free_G_buffers(__G) /* releases all memory al
@@ -222,6 +222,8 @@ static ZCONST char Far ZipfileCommTrunc1[] =
"\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
@@ -637,6 +639,13 @@ void free_G_buffers(__G) /* releases all memory al
}
#endif
@ -34,7 +45,7 @@ Index: process.c
} /* end function free_G_buffers() */
@@ -1401,6 +1408,10 @@ static int find_ecrec64(__G__ searchlen) /* re
@@ -1401,6 +1410,10 @@ static int find_ecrec64(__G__ searchlen) /* re
/* Now, we are (almost) sure that we have a Zip64 archive. */
G.ecrec.have_ecr64 = 1;
@ -45,7 +56,7 @@ Index: process.c
/* Update the "end-of-central-dir offset" for later checks. */
G.real_ecrec_offset = ecrec64_start_offset;
@@ -1535,6 +1546,8 @@ static int find_ecrec(__G__ searchlen) /* ret
@@ -1535,6 +1548,8 @@ static int find_ecrec(__G__ searchlen) /* ret
makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
G.ecrec.zipfile_comment_length =
makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
@ -54,7 +65,7 @@ Index: process.c
/* Now, we have to read the archive comment, BEFORE the file pointer
is moved away backwards to seek for a Zip64 ECLOC64 structure.
@@ -1729,6 +1742,13 @@ int process_cdir_file_hdr(__G) /* return PK-type er
@@ -1729,6 +1744,13 @@ int process_cdir_file_hdr(__G) /* return PK-type er
else if (uO.L_flag > 1) /* let -LL force lower case for all names */
G.pInfo->lcflag = 1;
@ -68,7 +79,7 @@ Index: process.c
/* do Amigas (AMIGA_) also have volume labels? */
if (IS_VOLID(G.crec.external_file_attributes) &&
(G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ ||
@@ -1751,6 +1771,12 @@ int process_cdir_file_hdr(__G) /* return PK-type er
@@ -1751,6 +1773,12 @@ int process_cdir_file_hdr(__G) /* return PK-type er
= (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11);
#endif
@ -81,12 +92,12 @@ Index: process.c
return PK_COOL;
} /* end function process_cdir_file_hdr() */
@@ -1888,48 +1914,84 @@ int getZip64Data(__G__ ef_buf, ef_len)
@@ -1888,48 +1916,85 @@ int getZip64Data(__G__ ef_buf, ef_len)
and a 4-byte version of disk start number.
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
@ -122,10 +133,11 @@ Index: process.c
break;
}
- if (eb_id == EF_PKSZ64) {
-
- int offset = EB_HEADSIZE;
+ if (eb_id == EF_PKSZ64)
+ {
int offset = EB_HEADSIZE;
+ unsigned offset = EB_HEADSIZE;
- if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
- G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
@ -182,7 +194,16 @@ Index: process.c
ef_buf += (eb_len + EB_HEADSIZE);
ef_len -= (eb_len + EB_HEADSIZE);
}
@@ -2037,6 +2099,8 @@ int getUnicodeData(__G__ ef_buf, ef_len)
@@ -1984,7 +2049,7 @@ int getUnicodeData(__G__ ef_buf, ef_len)
}
if (eb_id == EF_UNIPATH) {
- int offset = EB_HEADSIZE;
+ unsigned offset = EB_HEADSIZE;
ush ULen = eb_len - 5;
ulg chksum = CRCVAL_INITIAL;
@@ -2037,6 +2102,8 @@ int getUnicodeData(__G__ ef_buf, ef_len)
(ZCONST char *)(offset + ef_buf), ULen);
G.unipath_filename[ULen] = '\0';
}
@ -191,7 +212,81 @@ Index: process.c
}
/* Skip this extra field block */
@@ -2867,10 +2931,13 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
@@ -2440,16 +2507,17 @@ char *wide_to_local_string(wide_string, escape_all)
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;
}
@@ -2487,8 +2555,28 @@ char *wide_to_local_string(wide_string, escape_all)
} 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);
}
}
@@ -2540,9 +2628,18 @@ char *utf8_to_local_string(utf8_string, escape_all)
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;
}
@@ -2867,10 +2964,13 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
break;
case EF_IZUNIX2:
@ -207,7 +302,7 @@ Index: process.c
#ifdef IZ_HAVE_UXUIDGID
if (have_new_type_eb > 1)
break; /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
@@ -2886,6 +2953,8 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
@@ -2886,6 +2986,8 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
/* new 3rd generation Unix ef */
have_new_type_eb = 2;
@ -216,7 +311,7 @@ Index: process.c
/*
Version 1 byte version of this extra field, currently 1
UIDSize 1 byte Size of UID field
@@ -2897,7 +2966,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
@@ -2897,7 +2999,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
#ifdef IZ_HAVE_UXUIDGID
if (eb_len >= EB_UX3_MINLEN
&& z_uidgid != NULL
@ -225,7 +320,7 @@ Index: process.c
/* only know about version 1 */
{
uch uid_size;
@@ -2906,13 +2975,11 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
@@ -2906,13 +3008,11 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
uid_size = *((EB_HEADSIZE + 1) + ef_buf);
gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);