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,9 +1949,10 @@ ef_len - EB_HEADSIZE)); break; } + 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; }