diff options
author | Virendra Thakur <virendra.thakur@kpit.com> | 2022-02-24 20:41:59 +0530 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-03-09 17:30:48 +0000 |
commit | 6bba192936c25702316589ca59403daa1bf574da (patch) | |
tree | 764f551fcb2b865b1a8843008125639a7aebfdf6 | |
parent | 9426c3c83d2a06ae3941d833b76d58ad04e2a294 (diff) | |
download | poky-6bba192936c25702316589ca59403daa1bf574da.tar.gz |
libarchive: Fix for CVE-2021-36976
Add patch to fix CVE-2021-36976
CVE-2021-36976 fix are provided by below mentioned pull request.
1) https://github.com/libarchive/libarchive/pull/1491
2) https://github.com/libarchive/libarchive/pull/1492
3) https://github.com/libarchive/libarchive/pull/1493
(From OE-Core rev: 6c356aec8dabc08bd98da3106780896dc7b52501)
Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com>
Signed-off-by: virendra thakur <thakur.virendra1810@gmail.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
4 files changed, 540 insertions, 1 deletions
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch new file mode 100644 index 0000000000..fca53fc9b6 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch | |||
@@ -0,0 +1,321 @@ | |||
1 | From 05ebb55896d10a9737dad9ae0303f7f45489ba6f Mon Sep 17 00:00:00 2001 | ||
2 | From: Grzegorz Antoniak <ga@anadoxin.org> | ||
3 | Date: Sat, 13 Feb 2021 09:08:13 +0100 | ||
4 | Subject: [PATCH] RAR5 reader: fixed out of bounds read in some files | ||
5 | |||
6 | Added more range checks in the bit stream reading functions | ||
7 | (read_bits_16 and read_bits_32) in order to better guard against out of | ||
8 | memory reads. | ||
9 | |||
10 | This commit contains a test with OSSFuzz sample #30448. | ||
11 | |||
12 | Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-1.patch?h=applied/3.4.3-2ubuntu0.1] | ||
13 | CVE: CVE-2021-36976 | ||
14 | Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com> | ||
15 | --- | ||
16 | Makefile.am | 1 + | ||
17 | libarchive/archive_read_support_format_rar5.c | 108 ++++++++++-------- | ||
18 | libarchive/test/test_read_format_rar5.c | 16 +++ | ||
19 | ...r5_decode_number_out_of_bounds_read.rar.uu | 10 ++ | ||
20 | 4 files changed, 89 insertions(+), 46 deletions(-) | ||
21 | create mode 100644 libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu | ||
22 | |||
23 | --- a/Makefile.am | ||
24 | +++ b/Makefile.am | ||
25 | @@ -883,6 +883,7 @@ libarchive_test_EXTRA_DIST=\ | ||
26 | libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \ | ||
27 | libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ | ||
28 | libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ | ||
29 | + libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ | ||
30 | libarchive/test/test_read_format_raw.bufr.uu \ | ||
31 | libarchive/test/test_read_format_raw.data.gz.uu \ | ||
32 | libarchive/test/test_read_format_raw.data.Z.uu \ | ||
33 | --- a/libarchive/archive_read_support_format_rar5.c | ||
34 | +++ b/libarchive/archive_read_support_format_rar5.c | ||
35 | @@ -1012,7 +1012,16 @@ static int read_var_sized(struct archive | ||
36 | return ret; | ||
37 | } | ||
38 | |||
39 | -static int read_bits_32(struct rar5* rar, const uint8_t* p, uint32_t* value) { | ||
40 | +static int read_bits_32(struct archive_read* a, struct rar5* rar, | ||
41 | + const uint8_t* p, uint32_t* value) | ||
42 | +{ | ||
43 | + if(rar->bits.in_addr >= rar->cstate.cur_block_size) { | ||
44 | + archive_set_error(&a->archive, | ||
45 | + ARCHIVE_ERRNO_PROGRAMMER, | ||
46 | + "Premature end of stream during extraction of data (#1)"); | ||
47 | + return ARCHIVE_FATAL; | ||
48 | + } | ||
49 | + | ||
50 | uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24; | ||
51 | bits |= p[rar->bits.in_addr + 1] << 16; | ||
52 | bits |= p[rar->bits.in_addr + 2] << 8; | ||
53 | @@ -1023,7 +1032,16 @@ static int read_bits_32(struct rar5* rar | ||
54 | return ARCHIVE_OK; | ||
55 | } | ||
56 | |||
57 | -static int read_bits_16(struct rar5* rar, const uint8_t* p, uint16_t* value) { | ||
58 | +static int read_bits_16(struct archive_read* a, struct rar5* rar, | ||
59 | + const uint8_t* p, uint16_t* value) | ||
60 | +{ | ||
61 | + if(rar->bits.in_addr >= rar->cstate.cur_block_size) { | ||
62 | + archive_set_error(&a->archive, | ||
63 | + ARCHIVE_ERRNO_PROGRAMMER, | ||
64 | + "Premature end of stream during extraction of data (#2)"); | ||
65 | + return ARCHIVE_FATAL; | ||
66 | + } | ||
67 | + | ||
68 | int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16; | ||
69 | bits |= (int) p[rar->bits.in_addr + 1] << 8; | ||
70 | bits |= (int) p[rar->bits.in_addr + 2]; | ||
71 | @@ -1039,8 +1057,8 @@ static void skip_bits(struct rar5* rar, | ||
72 | } | ||
73 | |||
74 | /* n = up to 16 */ | ||
75 | -static int read_consume_bits(struct rar5* rar, const uint8_t* p, int n, | ||
76 | - int* value) | ||
77 | +static int read_consume_bits(struct archive_read* a, struct rar5* rar, | ||
78 | + const uint8_t* p, int n, int* value) | ||
79 | { | ||
80 | uint16_t v; | ||
81 | int ret, num; | ||
82 | @@ -1051,7 +1069,7 @@ static int read_consume_bits(struct rar5 | ||
83 | return ARCHIVE_FATAL; | ||
84 | } | ||
85 | |||
86 | - ret = read_bits_16(rar, p, &v); | ||
87 | + ret = read_bits_16(a, rar, p, &v); | ||
88 | if(ret != ARCHIVE_OK) | ||
89 | return ret; | ||
90 | |||
91 | @@ -2425,13 +2443,13 @@ static int create_decode_tables(uint8_t* | ||
92 | static int decode_number(struct archive_read* a, struct decode_table* table, | ||
93 | const uint8_t* p, uint16_t* num) | ||
94 | { | ||
95 | - int i, bits, dist; | ||
96 | + int i, bits, dist, ret; | ||
97 | uint16_t bitfield; | ||
98 | uint32_t pos; | ||
99 | struct rar5* rar = get_context(a); | ||
100 | |||
101 | - if(ARCHIVE_OK != read_bits_16(rar, p, &bitfield)) { | ||
102 | - return ARCHIVE_EOF; | ||
103 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &bitfield))) { | ||
104 | + return ret; | ||
105 | } | ||
106 | |||
107 | bitfield &= 0xfffe; | ||
108 | @@ -2537,14 +2555,6 @@ static int parse_tables(struct archive_r | ||
109 | for(i = 0; i < HUFF_TABLE_SIZE;) { | ||
110 | uint16_t num; | ||
111 | |||
112 | - if((rar->bits.in_addr + 6) >= rar->cstate.cur_block_size) { | ||
113 | - /* Truncated data, can't continue. */ | ||
114 | - archive_set_error(&a->archive, | ||
115 | - ARCHIVE_ERRNO_FILE_FORMAT, | ||
116 | - "Truncated data in huffman tables (#2)"); | ||
117 | - return ARCHIVE_FATAL; | ||
118 | - } | ||
119 | - | ||
120 | ret = decode_number(a, &rar->cstate.bd, p, &num); | ||
121 | if(ret != ARCHIVE_OK) { | ||
122 | archive_set_error(&a->archive, | ||
123 | @@ -2561,8 +2571,8 @@ static int parse_tables(struct archive_r | ||
124 | /* 16..17: repeat previous code */ | ||
125 | uint16_t n; | ||
126 | |||
127 | - if(ARCHIVE_OK != read_bits_16(rar, p, &n)) | ||
128 | - return ARCHIVE_EOF; | ||
129 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) | ||
130 | + return ret; | ||
131 | |||
132 | if(num == 16) { | ||
133 | n >>= 13; | ||
134 | @@ -2590,8 +2600,8 @@ static int parse_tables(struct archive_r | ||
135 | /* other codes: fill with zeroes `n` times */ | ||
136 | uint16_t n; | ||
137 | |||
138 | - if(ARCHIVE_OK != read_bits_16(rar, p, &n)) | ||
139 | - return ARCHIVE_EOF; | ||
140 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) | ||
141 | + return ret; | ||
142 | |||
143 | if(num == 18) { | ||
144 | n >>= 13; | ||
145 | @@ -2707,22 +2717,22 @@ static int parse_block_header(struct arc | ||
146 | } | ||
147 | |||
148 | /* Convenience function used during filter processing. */ | ||
149 | -static int parse_filter_data(struct rar5* rar, const uint8_t* p, | ||
150 | - uint32_t* filter_data) | ||
151 | +static int parse_filter_data(struct archive_read* a, struct rar5* rar, | ||
152 | + const uint8_t* p, uint32_t* filter_data) | ||
153 | { | ||
154 | - int i, bytes; | ||
155 | + int i, bytes, ret; | ||
156 | uint32_t data = 0; | ||
157 | |||
158 | - if(ARCHIVE_OK != read_consume_bits(rar, p, 2, &bytes)) | ||
159 | - return ARCHIVE_EOF; | ||
160 | + if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, p, 2, &bytes))) | ||
161 | + return ret; | ||
162 | |||
163 | bytes++; | ||
164 | |||
165 | for(i = 0; i < bytes; i++) { | ||
166 | uint16_t byte; | ||
167 | |||
168 | - if(ARCHIVE_OK != read_bits_16(rar, p, &byte)) { | ||
169 | - return ARCHIVE_EOF; | ||
170 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &byte))) { | ||
171 | + return ret; | ||
172 | } | ||
173 | |||
174 | /* Cast to uint32_t will ensure the shift operation will not | ||
175 | @@ -2765,16 +2775,17 @@ static int parse_filter(struct archive_r | ||
176 | uint16_t filter_type; | ||
177 | struct filter_info* filt = NULL; | ||
178 | struct rar5* rar = get_context(ar); | ||
179 | + int ret; | ||
180 | |||
181 | /* Read the parameters from the input stream. */ | ||
182 | - if(ARCHIVE_OK != parse_filter_data(rar, p, &block_start)) | ||
183 | - return ARCHIVE_EOF; | ||
184 | + if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_start))) | ||
185 | + return ret; | ||
186 | |||
187 | - if(ARCHIVE_OK != parse_filter_data(rar, p, &block_length)) | ||
188 | - return ARCHIVE_EOF; | ||
189 | + if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_length))) | ||
190 | + return ret; | ||
191 | |||
192 | - if(ARCHIVE_OK != read_bits_16(rar, p, &filter_type)) | ||
193 | - return ARCHIVE_EOF; | ||
194 | + if(ARCHIVE_OK != (ret = read_bits_16(ar, rar, p, &filter_type))) | ||
195 | + return ret; | ||
196 | |||
197 | filter_type >>= 13; | ||
198 | skip_bits(rar, 3); | ||
199 | @@ -2814,8 +2825,8 @@ static int parse_filter(struct archive_r | ||
200 | if(filter_type == FILTER_DELTA) { | ||
201 | int channels; | ||
202 | |||
203 | - if(ARCHIVE_OK != read_consume_bits(rar, p, 5, &channels)) | ||
204 | - return ARCHIVE_EOF; | ||
205 | + if(ARCHIVE_OK != (ret = read_consume_bits(ar, rar, p, 5, &channels))) | ||
206 | + return ret; | ||
207 | |||
208 | filt->channels = channels + 1; | ||
209 | } | ||
210 | @@ -2823,10 +2834,11 @@ static int parse_filter(struct archive_r | ||
211 | return ARCHIVE_OK; | ||
212 | } | ||
213 | |||
214 | -static int decode_code_length(struct rar5* rar, const uint8_t* p, | ||
215 | - uint16_t code) | ||
216 | +static int decode_code_length(struct archive_read* a, struct rar5* rar, | ||
217 | + const uint8_t* p, uint16_t code) | ||
218 | { | ||
219 | int lbits, length = 2; | ||
220 | + | ||
221 | if(code < 8) { | ||
222 | lbits = 0; | ||
223 | length += code; | ||
224 | @@ -2838,7 +2850,7 @@ static int decode_code_length(struct rar | ||
225 | if(lbits > 0) { | ||
226 | int add; | ||
227 | |||
228 | - if(ARCHIVE_OK != read_consume_bits(rar, p, lbits, &add)) | ||
229 | + if(ARCHIVE_OK != read_consume_bits(a, rar, p, lbits, &add)) | ||
230 | return -1; | ||
231 | |||
232 | length += add; | ||
233 | @@ -2933,7 +2945,7 @@ static int do_uncompress_block(struct ar | ||
234 | continue; | ||
235 | } else if(num >= 262) { | ||
236 | uint16_t dist_slot; | ||
237 | - int len = decode_code_length(rar, p, num - 262), | ||
238 | + int len = decode_code_length(a, rar, p, num - 262), | ||
239 | dbits, | ||
240 | dist = 1; | ||
241 | |||
242 | @@ -2975,12 +2987,12 @@ static int do_uncompress_block(struct ar | ||
243 | uint16_t low_dist; | ||
244 | |||
245 | if(dbits > 4) { | ||
246 | - if(ARCHIVE_OK != read_bits_32( | ||
247 | - rar, p, &add)) { | ||
248 | + if(ARCHIVE_OK != (ret = read_bits_32( | ||
249 | + a, rar, p, &add))) { | ||
250 | /* Return EOF if we | ||
251 | * can't read more | ||
252 | * data. */ | ||
253 | - return ARCHIVE_EOF; | ||
254 | + return ret; | ||
255 | } | ||
256 | |||
257 | skip_bits(rar, dbits - 4); | ||
258 | @@ -3015,11 +3027,11 @@ static int do_uncompress_block(struct ar | ||
259 | /* dbits is one of [0,1,2,3] */ | ||
260 | int add; | ||
261 | |||
262 | - if(ARCHIVE_OK != read_consume_bits(rar, | ||
263 | - p, dbits, &add)) { | ||
264 | + if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, | ||
265 | + p, dbits, &add))) { | ||
266 | /* Return EOF if we can't read | ||
267 | * more data. */ | ||
268 | - return ARCHIVE_EOF; | ||
269 | + return ret; | ||
270 | } | ||
271 | |||
272 | dist += add; | ||
273 | @@ -3076,7 +3088,11 @@ static int do_uncompress_block(struct ar | ||
274 | return ARCHIVE_FATAL; | ||
275 | } | ||
276 | |||
277 | - len = decode_code_length(rar, p, len_slot); | ||
278 | + len = decode_code_length(a, rar, p, len_slot); | ||
279 | + if (len == -1) { | ||
280 | + return ARCHIVE_FATAL; | ||
281 | + } | ||
282 | + | ||
283 | rar->cstate.last_len = len; | ||
284 | |||
285 | if(ARCHIVE_OK != copy_string(a, len, dist)) | ||
286 | --- a/libarchive/test/test_read_format_rar5.c | ||
287 | +++ b/libarchive/test/test_read_format_rar5.c | ||
288 | @@ -1271,3 +1271,20 @@ DEFINE_TEST(test_read_format_rar5_block_ | ||
289 | |||
290 | EPILOGUE(); | ||
291 | } | ||
292 | + | ||
293 | +DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read) | ||
294 | +{ | ||
295 | + /* oss fuzz 30448 */ | ||
296 | + | ||
297 | + char buf[4096]; | ||
298 | + PROLOGUE("test_read_format_rar5_decode_number_out_of_bounds_read.rar"); | ||
299 | + | ||
300 | + /* Return codes of those calls are ignored, because this sample file | ||
301 | + * is invalid. However, the unpacker shouldn't produce any SIGSEGV | ||
302 | + * errors during processing. */ | ||
303 | + | ||
304 | + (void) archive_read_next_header(a, &ae); | ||
305 | + while(0 < archive_read_data(a, buf, sizeof(buf))) {} | ||
306 | + | ||
307 | + EPILOGUE(); | ||
308 | +} | ||
309 | --- /dev/null | ||
310 | +++ b/libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu | ||
311 | @@ -0,0 +1,10 @@ | ||
312 | +begin 644 test_read_format_rar5_decode_number_out_of_bounds_read.rar | ||
313 | +M4F%R(1H'`0!3@"KT`P+G(@(0("`@@`L!!"`@("`@(($D_[BJ2"!::7!)210V | ||
314 | +M+0#ZF#)Q!`+>YPW_("`@("``_R````````````````````````````!__P`` | ||
315 | +M``````!T72`@/EW_(/\@("`@("`@("`@("`@("`@("`@("`@("`@(/\@("`@ | ||
316 | +M("`@("#_("`@("`@("`@("`@("`@("`@("`@("`@("#_("`@("`@("`@_R`@ | ||
317 | +M("`@("`@("`@("`@("`@("`@("`@("`@_R`@("`@("`@(/\@("`@("`@("`@ | ||
318 | +M("`@("`@("`@("`@("`@(/\@("`@("`@("#_("`@("`@("`@("`@("`@("`@ | ||
319 | +E("`@("`@("#_("`@("`@("`@_R`@("`@("`@("`@("`@("`@(``` | ||
320 | +` | ||
321 | +end | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch new file mode 100644 index 0000000000..b5da44ec7b --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch | |||
@@ -0,0 +1,121 @@ | |||
1 | From 17f4e83c0f0fc3bacf4b2bbacb01f987bb5aff5f Mon Sep 17 00:00:00 2001 | ||
2 | From: Grzegorz Antoniak <ga@anadoxin.org> | ||
3 | Date: Fri, 12 Feb 2021 20:18:31 +0100 | ||
4 | Subject: [PATCH] RAR5 reader: fix invalid memory access in some files | ||
5 | |||
6 | RAR5 reader uses several variables to manage the window buffer during | ||
7 | extraction: the buffer itself (`window_buf`), the current size of the | ||
8 | window buffer (`window_size`), and a helper variable (`window_mask`) | ||
9 | that is used to constrain read and write offsets to the window buffer. | ||
10 | |||
11 | Some specially crafted files can force the unpacker to update the | ||
12 | `window_mask` variable to a value that is out of sync with current | ||
13 | buffer size. If the `window_mask` will be bigger than the actual buffer | ||
14 | size, then an invalid access operation can happen (SIGSEGV). | ||
15 | |||
16 | This commit ensures that if the `window_size` and `window_mask` will be | ||
17 | changed, the window buffer will be reallocated to the proper size, so no | ||
18 | invalid memory operation should be possible. | ||
19 | |||
20 | This commit contains a test file from OSSFuzz #30442. | ||
21 | |||
22 | Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-2.patch?h=applied/3.4.3-2ubuntu0.1] | ||
23 | CVE: CVE-2021-36976 | ||
24 | Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com> | ||
25 | |||
26 | --- | ||
27 | Makefile.am | 1 + | ||
28 | libarchive/archive_read_support_format_rar5.c | 27 ++++++++++++++----- | ||
29 | libarchive/test/test_read_format_rar5.c | 17 ++++++++++++ | ||
30 | ...mat_rar5_window_buf_and_size_desync.rar.uu | 11 ++++++++ | ||
31 | 4 files changed, 50 insertions(+), 6 deletions(-) | ||
32 | create mode 100644 libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu | ||
33 | |||
34 | --- a/Makefile.am | ||
35 | +++ b/Makefile.am | ||
36 | @@ -884,6 +884,7 @@ libarchive_test_EXTRA_DIST=\ | ||
37 | libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ | ||
38 | libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ | ||
39 | libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ | ||
40 | + libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ | ||
41 | libarchive/test/test_read_format_raw.bufr.uu \ | ||
42 | libarchive/test/test_read_format_raw.data.gz.uu \ | ||
43 | libarchive/test/test_read_format_raw.data.Z.uu \ | ||
44 | --- a/libarchive/archive_read_support_format_rar5.c | ||
45 | +++ b/libarchive/archive_read_support_format_rar5.c | ||
46 | @@ -1730,14 +1730,29 @@ static int process_head_file(struct arch | ||
47 | } | ||
48 | } | ||
49 | |||
50 | - /* If we're currently switching volumes, ignore the new definition of | ||
51 | - * window_size. */ | ||
52 | - if(rar->cstate.switch_multivolume == 0) { | ||
53 | - /* Values up to 64M should fit into ssize_t on every | ||
54 | - * architecture. */ | ||
55 | - rar->cstate.window_size = (ssize_t) window_size; | ||
56 | + if(rar->cstate.window_size < (ssize_t) window_size && | ||
57 | + rar->cstate.window_buf) | ||
58 | + { | ||
59 | + /* If window_buf has been allocated before, reallocate it, so | ||
60 | + * that its size will match new window_size. */ | ||
61 | + | ||
62 | + uint8_t* new_window_buf = | ||
63 | + realloc(rar->cstate.window_buf, window_size); | ||
64 | + | ||
65 | + if(!new_window_buf) { | ||
66 | + archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, | ||
67 | + "Not enough memory when trying to realloc the window " | ||
68 | + "buffer."); | ||
69 | + return ARCHIVE_FATAL; | ||
70 | + } | ||
71 | + | ||
72 | + rar->cstate.window_buf = new_window_buf; | ||
73 | } | ||
74 | |||
75 | + /* Values up to 64M should fit into ssize_t on every | ||
76 | + * architecture. */ | ||
77 | + rar->cstate.window_size = (ssize_t) window_size; | ||
78 | + | ||
79 | if(rar->file.solid > 0 && rar->file.solid_window_size == 0) { | ||
80 | /* Solid files have to have the same window_size across | ||
81 | whole archive. Remember the window_size parameter | ||
82 | --- a/libarchive/test/test_read_format_rar5.c | ||
83 | +++ b/libarchive/test/test_read_format_rar5.c | ||
84 | @@ -1206,6 +1206,23 @@ DEFINE_TEST(test_read_format_rar5_differ | ||
85 | EPILOGUE(); | ||
86 | } | ||
87 | |||
88 | +DEFINE_TEST(test_read_format_rar5_window_buf_and_size_desync) | ||
89 | +{ | ||
90 | + /* oss fuzz 30442 */ | ||
91 | + | ||
92 | + char buf[4096]; | ||
93 | + PROLOGUE("test_read_format_rar5_window_buf_and_size_desync.rar"); | ||
94 | + | ||
95 | + /* Return codes of those calls are ignored, because this sample file | ||
96 | + * is invalid. However, the unpacker shouldn't produce any SIGSEGV | ||
97 | + * errors during processing. */ | ||
98 | + | ||
99 | + (void) archive_read_next_header(a, &ae); | ||
100 | + while(0 < archive_read_data(a, buf, 46)) {} | ||
101 | + | ||
102 | + EPILOGUE(); | ||
103 | +} | ||
104 | + | ||
105 | DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary) | ||
106 | { | ||
107 | char buf[4096]; | ||
108 | --- /dev/null | ||
109 | +++ b/libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu | ||
110 | @@ -0,0 +1,11 @@ | ||
111 | +begin 644 test_read_format_rar5_window_buf_and_size_desync.rar | ||
112 | +M4F%R(1H'`0`]/-[E`@$`_P$`1#[Z5P("`PL``BXB"?\`!(@B@0`)6.-AF?_1 | ||
113 | +M^0DI&0GG(F%R(0<:)`!3@"KT`P+G(@O_X[\``#&``(?!!0$$[:L``$.M*E)A | ||
114 | +M<B$`O<\>P0";/P1%``A*2DI*2DYQ<6TN9'%*2DI*2DI*``!D<F--``````"Z | ||
115 | +MNC*ZNKJZNFYO=&%I;+JZNKJZNKJZOKJZ.KJZNKJZNKKZU@4%````0$!`0$!` | ||
116 | +M0$!`0$!`0$!`0$#_________/T#`0$!`0$!`-UM`0$!`0$!`0$!`0$!`0$!` | ||
117 | +M0$!`0'!,J+:O!IZ-WN4'@`!3*F0````````````````````````````````` | ||
118 | +M``````````````#T`P)287(A&@<!`%.`*O0#`N<B`_,F@`'[__\``(`4`01S | ||
119 | +J'`/H/O\H@?\D`#O9GIZ>GN<B"_]%``(``&1RGIZ>GIZ>8_^>GE/_``!. | ||
120 | +` | ||
121 | +end | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch new file mode 100644 index 0000000000..0e1549f229 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch | |||
@@ -0,0 +1,93 @@ | |||
1 | From 313bcd7ac547f7cc25945831f63507420c0874d7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Grzegorz Antoniak <ga@anadoxin.org> | ||
3 | Date: Sat, 13 Feb 2021 10:13:22 +0100 | ||
4 | Subject: [PATCH] RAR5 reader: add more checks for invalid extraction | ||
5 | parameters | ||
6 | |||
7 | Some specially crafted files declare invalid extraction parameters that | ||
8 | can confuse the RAR5 reader. | ||
9 | |||
10 | One of the arguments is the declared window size parameter that the | ||
11 | archive file can declare for each file stored in the archive. Some | ||
12 | crafted files declare window size equal to 0, which is clearly wrong. | ||
13 | |||
14 | This commit adds additional safety checks decreasing the tolerance of | ||
15 | the RAR5 format. | ||
16 | |||
17 | This commit also contains OSSFuzz sample #30459. | ||
18 | --- | ||
19 | Makefile.am | 1 + | ||
20 | libarchive/archive_read_support_format_rar5.c | 10 ++++++++++ | ||
21 | libarchive/test/test_read_format_rar5.c | 19 +++++++++++++++++++ | ||
22 | ...t_rar5_bad_window_sz_in_mltarc_file.rar.uu | 7 +++++++ | ||
23 | 4 files changed, 37 insertions(+) | ||
24 | create mode 100644 libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu | ||
25 | |||
26 | Upstream-Status: Backport [https://github.com/libarchive/libarchive/pull/1493/commits/313bcd7ac547f7cc25945831f63507420c0874d7] | ||
27 | CVE: CVE-2021-36976 | ||
28 | Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com> | ||
29 | |||
30 | --- libarchive-3.4.2.orig/Makefile.am | ||
31 | +++ libarchive-3.4.2/Makefile.am | ||
32 | @@ -882,6 +882,7 @@ libarchive_test_EXTRA_DIST=\ | ||
33 | libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ | ||
34 | libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ | ||
35 | libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ | ||
36 | + libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \ | ||
37 | libarchive/test/test_read_format_raw.bufr.uu \ | ||
38 | libarchive/test/test_read_format_raw.data.gz.uu \ | ||
39 | libarchive/test/test_read_format_raw.data.Z.uu \ | ||
40 | --- libarchive-3.4.2.orig/libarchive/archive_read_support_format_rar5.c | ||
41 | +++ libarchive-3.4.2/libarchive/archive_read_support_format_rar5.c | ||
42 | @@ -3637,6 +3637,16 @@ static int do_uncompress_file(struct arc | ||
43 | rar->cstate.initialized = 1; | ||
44 | } | ||
45 | |||
46 | + /* Don't allow extraction if window_size is invalid. */ | ||
47 | + if(rar->cstate.window_size == 0) { | ||
48 | + archive_set_error(&a->archive, | ||
49 | + ARCHIVE_ERRNO_FILE_FORMAT, | ||
50 | + "Invalid window size declaration in this file"); | ||
51 | + | ||
52 | + /* This should never happen in valid files. */ | ||
53 | + return ARCHIVE_FATAL; | ||
54 | + } | ||
55 | + | ||
56 | if(rar->cstate.all_filters_applied == 1) { | ||
57 | /* We use while(1) here, but standard case allows for just 1 | ||
58 | * iteration. The loop will iterate if process_block() didn't | ||
59 | --- libarchive-3.4.2.orig/libarchive/test/test_read_format_rar5.c | ||
60 | +++ libarchive-3.4.2/libarchive/test/test_read_format_rar5.c | ||
61 | @@ -1305,3 +1305,22 @@ DEFINE_TEST(test_read_format_rar5_decode | ||
62 | |||
63 | EPILOGUE(); | ||
64 | } | ||
65 | + | ||
66 | +DEFINE_TEST(test_read_format_rar5_bad_window_size_in_multiarchive_file) | ||
67 | +{ | ||
68 | + /* oss fuzz 30459 */ | ||
69 | + | ||
70 | + char buf[4096]; | ||
71 | + PROLOGUE("test_read_format_rar5_bad_window_sz_in_mltarc_file.rar"); | ||
72 | + | ||
73 | + /* This file is damaged, so those functions should return failure. | ||
74 | + * Additionally, SIGSEGV shouldn't be raised during execution | ||
75 | + * of those functions. */ | ||
76 | + | ||
77 | + (void) archive_read_next_header(a, &ae); | ||
78 | + while(0 < archive_read_data(a, buf, sizeof(buf))) {} | ||
79 | + (void) archive_read_next_header(a, &ae); | ||
80 | + while(0 < archive_read_data(a, buf, sizeof(buf))) {} | ||
81 | + | ||
82 | + EPILOGUE(); | ||
83 | +} | ||
84 | --- /dev/null | ||
85 | +++ libarchive-3.4.2/libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu | ||
86 | @@ -0,0 +1,7 @@ | ||
87 | +begin 644 test_read_format_rar5_bad_window_size_in_multiarchive_file.rar | ||
88 | +M4F%R(1H'`0`]/-[E`@$`_R`@1#[Z5P("`PL`("`@@"(`"?\@("#___\@("`@ | ||
89 | +M("`@("`@("`@4X`J]`,"YR(#$($@("`@``$@("`@@<L0("`@("`@("`@("`@ | ||
90 | +M("`@(""LCTJA`P$%`B`@`2!3@"KT`P+G(@,@("`@_P,!!B`@(/___R`@(('+ | ||
91 | +5$"`OX2`@[.SL[.S_("`@("`@("`@ | ||
92 | +` | ||
93 | +end | ||
diff --git a/meta/recipes-extended/libarchive/libarchive_3.4.2.bb b/meta/recipes-extended/libarchive/libarchive_3.4.2.bb index 0ab40fc096..b7426a1be8 100644 --- a/meta/recipes-extended/libarchive/libarchive_3.4.2.bb +++ b/meta/recipes-extended/libarchive/libarchive_3.4.2.bb | |||
@@ -32,7 +32,11 @@ PACKAGECONFIG[mbedtls] = "--with-mbedtls,--without-mbedtls,mbedtls," | |||
32 | 32 | ||
33 | EXTRA_OECONF += "--enable-largefile" | 33 | EXTRA_OECONF += "--enable-largefile" |
34 | 34 | ||
35 | SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz" | 35 | SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \ |
36 | file://CVE-2021-36976-1.patch \ | ||
37 | file://CVE-2021-36976-2.patch \ | ||
38 | file://CVE-2021-36976-3.patch \ | ||
39 | " | ||
36 | 40 | ||
37 | SRC_URI[md5sum] = "d953ed6b47694dadf0e6042f8f9ff451" | 41 | SRC_URI[md5sum] = "d953ed6b47694dadf0e6042f8f9ff451" |
38 | SRC_URI[sha256sum] = "b60d58d12632ecf1e8fad7316dc82c6b9738a35625746b47ecdcaf4aed176176" | 42 | SRC_URI[sha256sum] = "b60d58d12632ecf1e8fad7316dc82c6b9738a35625746b47ecdcaf4aed176176" |