|
| 1 | +From 246a2f17066dff57d4a5253de258374a7e99154a Mon Sep 17 00:00:00 2001 |
| 2 | +From: kavyasree <kkaitepalli@microsoft.com> |
| 3 | +Date: Mon, 25 Nov 2024 10:50:21 +0530 |
| 4 | +Subject: [PATCH] Fix CVE-2022-0529 and CVE-2022-0530 |
| 5 | +Reference: https://git.launchpad.net/ubuntu/+source/unzip/commit/?h=applied/ubuntu/devel&id=d5d5037f4ca1b40578015085b77ae322d1406f56 |
| 6 | +--- |
| 7 | + fileio.c | 34 +++++++++++++++++++++++++--------- |
| 8 | + process.c | 55 +++++++++++++++++++++++++++++++++++++++++++------------ |
| 9 | + 2 files changed, 68 insertions(+), 21 deletions(-) |
| 10 | + |
| 11 | +diff --git a/fileio.c b/fileio.c |
| 12 | +index eb2a115..285f7fe 100644 |
| 13 | +--- a/fileio.c |
| 14 | ++++ b/fileio.c |
| 15 | +@@ -171,8 +171,10 @@ static ZCONST char Far ReadError[] = "error: zipfile read error\n"; |
| 16 | + static ZCONST char Far FilenameTooLongTrunc[] = |
| 17 | + "warning: filename too long--truncating.\n"; |
| 18 | + #ifdef UNICODE_SUPPORT |
| 19 | ++ static ZCONST char Far UFilenameCorrupt[] = |
| 20 | ++ "error: Unicode filename corrupt.\n"; |
| 21 | + static ZCONST char Far UFilenameTooLongTrunc[] = |
| 22 | +- "warning: Converted unicode filename too long--truncating.\n"; |
| 23 | ++ "warning: Converted Unicode filename too long--truncating.\n"; |
| 24 | + #endif |
| 25 | + static ZCONST char Far ExtraFieldTooLong[] = |
| 26 | + "warning: extra field too long (%d). Ignoring...\n"; |
| 27 | +@@ -2355,16 +2357,30 @@ int do_string(__G__ length, option) /* return PK-type error code */ |
| 28 | + /* convert UTF-8 to local character set */ |
| 29 | + fn = utf8_to_local_string(G.unipath_filename, |
| 30 | + G.unicode_escape_all); |
| 31 | +- /* make sure filename is short enough */ |
| 32 | +- if (strlen(fn) >= FILNAMSIZ) { |
| 33 | +- fn[FILNAMSIZ - 1] = '\0'; |
| 34 | ++ |
| 35 | ++ /* 2022-07-22 SMS, et al. CVE-2022-0530 |
| 36 | ++ * Detect conversion failure, emit message. |
| 37 | ++ * Continue with unconverted name. |
| 38 | ++ */ |
| 39 | ++ if (fn == NULL) |
| 40 | ++ { |
| 41 | + Info(slide, 0x401, ((char *)slide, |
| 42 | +- LoadFarString(UFilenameTooLongTrunc))); |
| 43 | +- error = PK_WARN; |
| 44 | ++ LoadFarString(UFilenameCorrupt))); |
| 45 | ++ error = PK_ERR; |
| 46 | ++ } |
| 47 | ++ else |
| 48 | ++ { |
| 49 | ++ /* make sure filename is short enough */ |
| 50 | ++ if (strlen(fn) >= FILNAMSIZ) { |
| 51 | ++ fn[FILNAMSIZ - 1] = '\0'; |
| 52 | ++ Info(slide, 0x401, ((char *)slide, |
| 53 | ++ LoadFarString(UFilenameTooLongTrunc))); |
| 54 | ++ error = PK_WARN; |
| 55 | ++ } |
| 56 | ++ /* replace filename with converted UTF-8 */ |
| 57 | ++ strcpy(G.filename, fn); |
| 58 | ++ free(fn); |
| 59 | + } |
| 60 | +- /* replace filename with converted UTF-8 */ |
| 61 | +- strcpy(G.filename, fn); |
| 62 | +- free(fn); |
| 63 | + } |
| 64 | + # endif /* UNICODE_WCHAR */ |
| 65 | + if (G.unipath_filename != G.filename_full) |
| 66 | +diff --git a/process.c b/process.c |
| 67 | +index 4e06a35..09d54f7 100644 |
| 68 | +--- a/process.c |
| 69 | ++++ b/process.c |
| 70 | +@@ -222,6 +222,8 @@ static ZCONST char Far ZipfileCommTrunc1[] = |
| 71 | + "\nwarning: Unicode Path version > 1\n"; |
| 72 | + static ZCONST char Far UnicodeMismatchError[] = |
| 73 | + "\nwarning: Unicode Path checksum invalid\n"; |
| 74 | ++ static ZCONST char Far UFilenameTooLongTrunc[] = |
| 75 | ++ "warning: filename too long (P1) -- truncating.\n"; |
| 76 | + #endif |
| 77 | + |
| 78 | + |
| 79 | +@@ -1902,7 +1904,7 @@ int getZip64Data(__G__ ef_buf, ef_len) |
| 80 | + Sets both local header and central header fields. Not terribly clever, |
| 81 | + but it means that this procedure is only called in one place. |
| 82 | + |
| 83 | +- 2014-12-05 SMS. |
| 84 | ++ 2014-12-05 SMS. (oCERT.org report.) CVE-2014-8141. |
| 85 | + Added checks to ensure that enough data are available before calling |
| 86 | + makeint64() or makelong(). Replaced various sizeof() values with |
| 87 | + simple ("4" or "8") constants. (The Zip64 structures do not depend |
| 88 | +@@ -1937,8 +1939,7 @@ int getZip64Data(__G__ ef_buf, ef_len) |
| 89 | + |
| 90 | + if (eb_id == EF_PKSZ64) |
| 91 | + { |
| 92 | +- int offset = EB_HEADSIZE; |
| 93 | +- |
| 94 | ++ unsigned offset = EB_HEADSIZE; |
| 95 | + if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL)) |
| 96 | + { |
| 97 | + if (offset+ 8 > ef_len) |
| 98 | +@@ -2036,7 +2037,7 @@ int getUnicodeData(__G__ ef_buf, ef_len) |
| 99 | + } |
| 100 | + if (eb_id == EF_UNIPATH) { |
| 101 | + |
| 102 | +- int offset = EB_HEADSIZE; |
| 103 | ++ unsigned offset = EB_HEADSIZE; |
| 104 | + ush ULen = eb_len - 5; |
| 105 | + ulg chksum = CRCVAL_INITIAL; |
| 106 | + |
| 107 | +@@ -2492,16 +2493,17 @@ char *wide_to_local_string(wide_string, escape_all) |
| 108 | + int state_dependent; |
| 109 | + int wsize = 0; |
| 110 | + int max_bytes = MB_CUR_MAX; |
| 111 | +- char buf[9]; |
| 112 | ++ char buf[ MB_CUR_MAX+ 1]; /* ("+1" not really needed?) */ |
| 113 | + char *buffer = NULL; |
| 114 | + char *local_string = NULL; |
| 115 | ++ size_t buffer_size; /* CVE-2022-0529 */ |
| 116 | + |
| 117 | + for (wsize = 0; wide_string[wsize]; wsize++) ; |
| 118 | + |
| 119 | + if (max_bytes < MAX_ESCAPE_BYTES) |
| 120 | + max_bytes = MAX_ESCAPE_BYTES; |
| 121 | +- |
| 122 | +- if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) { |
| 123 | ++ buffer_size = wsize * max_bytes + 1; /* Reused below. */ |
| 124 | ++ if ((buffer = (char *)malloc( buffer_size)) == NULL) { |
| 125 | + return NULL; |
| 126 | + } |
| 127 | + |
| 128 | +@@ -2539,8 +2541,28 @@ char *wide_to_local_string(wide_string, escape_all) |
| 129 | + } else { |
| 130 | + /* no MB for this wide */ |
| 131 | + /* use escape for wide character */ |
| 132 | +- char *escape_string = wide_to_escape_string(wide_string[i]); |
| 133 | +- strcat(buffer, escape_string); |
| 134 | ++ size_t buffer_len; |
| 135 | ++ size_t escape_string_len; |
| 136 | ++ char *escape_string; |
| 137 | ++ int err_msg = 0; |
| 138 | ++ |
| 139 | ++ escape_string = wide_to_escape_string(wide_string[i]); |
| 140 | ++ buffer_len = strlen( buffer); |
| 141 | ++ escape_string_len = strlen( escape_string); |
| 142 | ++ |
| 143 | ++ /* Append escape string, as space allows. */ |
| 144 | ++ /* 2022-07-18 SMS, et al. CVE-2022-0529 */ |
| 145 | ++ if (escape_string_len > buffer_size- buffer_len- 1) |
| 146 | ++ { |
| 147 | ++ escape_string_len = buffer_size- buffer_len- 1; |
| 148 | ++ if (err_msg == 0) |
| 149 | ++ { |
| 150 | ++ err_msg = 1; |
| 151 | ++ Info(slide, 0x401, ((char *)slide, |
| 152 | ++ LoadFarString( UFilenameTooLongTrunc))); |
| 153 | ++ } |
| 154 | ++ } |
| 155 | ++ strncat( buffer, escape_string, escape_string_len); |
| 156 | + free(escape_string); |
| 157 | + } |
| 158 | + } |
| 159 | +@@ -2592,9 +2614,18 @@ char *utf8_to_local_string(utf8_string, escape_all) |
| 160 | + ZCONST char *utf8_string; |
| 161 | + int escape_all; |
| 162 | + { |
| 163 | +- zwchar *wide = utf8_to_wide_string(utf8_string); |
| 164 | +- char *loc = wide_to_local_string(wide, escape_all); |
| 165 | +- free(wide); |
| 166 | ++ zwchar *wide; |
| 167 | ++ char *loc = NULL; |
| 168 | ++ |
| 169 | ++ wide = utf8_to_wide_string( utf8_string); |
| 170 | ++ |
| 171 | ++ /* 2022-07-25 SMS, et al. CVE-2022-0530 */ |
| 172 | ++ if (wide != NULL) |
| 173 | ++ { |
| 174 | ++ loc = wide_to_local_string( wide, escape_all); |
| 175 | ++ free( wide); |
| 176 | ++ } |
| 177 | ++ |
| 178 | + return loc; |
| 179 | + } |
| 180 | + |
| 181 | +-- |
| 182 | +2.34.1 |
| 183 | + |
0 commit comments