summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVirendra Thakur <virendra.thakur@kpit.com>2022-02-24 20:41:59 +0530
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-03-09 17:30:48 +0000
commit6bba192936c25702316589ca59403daa1bf574da (patch)
tree764f551fcb2b865b1a8843008125639a7aebfdf6
parent9426c3c83d2a06ae3941d833b76d58ad04e2a294 (diff)
downloadpoky-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>
-rw-r--r--meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch321
-rw-r--r--meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch121
-rw-r--r--meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch93
-rw-r--r--meta/recipes-extended/libarchive/libarchive_3.4.2.bb6
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 @@
1From 05ebb55896d10a9737dad9ae0303f7f45489ba6f Mon Sep 17 00:00:00 2001
2From: Grzegorz Antoniak <ga@anadoxin.org>
3Date: Sat, 13 Feb 2021 09:08:13 +0100
4Subject: [PATCH] RAR5 reader: fixed out of bounds read in some files
5
6Added 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
8memory reads.
9
10This commit contains a test with OSSFuzz sample #30448.
11
12Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-1.patch?h=applied/3.4.3-2ubuntu0.1]
13CVE: CVE-2021-36976
14Signed-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 @@
1From 17f4e83c0f0fc3bacf4b2bbacb01f987bb5aff5f Mon Sep 17 00:00:00 2001
2From: Grzegorz Antoniak <ga@anadoxin.org>
3Date: Fri, 12 Feb 2021 20:18:31 +0100
4Subject: [PATCH] RAR5 reader: fix invalid memory access in some files
5
6RAR5 reader uses several variables to manage the window buffer during
7extraction: the buffer itself (`window_buf`), the current size of the
8window buffer (`window_size`), and a helper variable (`window_mask`)
9that is used to constrain read and write offsets to the window buffer.
10
11Some specially crafted files can force the unpacker to update the
12`window_mask` variable to a value that is out of sync with current
13buffer size. If the `window_mask` will be bigger than the actual buffer
14size, then an invalid access operation can happen (SIGSEGV).
15
16This commit ensures that if the `window_size` and `window_mask` will be
17changed, the window buffer will be reallocated to the proper size, so no
18invalid memory operation should be possible.
19
20This commit contains a test file from OSSFuzz #30442.
21
22Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-2.patch?h=applied/3.4.3-2ubuntu0.1]
23CVE: CVE-2021-36976
24Signed-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 @@
1From 313bcd7ac547f7cc25945831f63507420c0874d7 Mon Sep 17 00:00:00 2001
2From: Grzegorz Antoniak <ga@anadoxin.org>
3Date: Sat, 13 Feb 2021 10:13:22 +0100
4Subject: [PATCH] RAR5 reader: add more checks for invalid extraction
5 parameters
6
7Some specially crafted files declare invalid extraction parameters that
8can confuse the RAR5 reader.
9
10One of the arguments is the declared window size parameter that the
11archive file can declare for each file stored in the archive. Some
12crafted files declare window size equal to 0, which is clearly wrong.
13
14This commit adds additional safety checks decreasing the tolerance of
15the RAR5 format.
16
17This 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
26Upstream-Status: Backport [https://github.com/libarchive/libarchive/pull/1493/commits/313bcd7ac547f7cc25945831f63507420c0874d7]
27CVE: CVE-2021-36976
28Signed-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
33EXTRA_OECONF += "--enable-largefile" 33EXTRA_OECONF += "--enable-largefile"
34 34
35SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz" 35SRC_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
37SRC_URI[md5sum] = "d953ed6b47694dadf0e6042f8f9ff451" 41SRC_URI[md5sum] = "d953ed6b47694dadf0e6042f8f9ff451"
38SRC_URI[sha256sum] = "b60d58d12632ecf1e8fad7316dc82c6b9738a35625746b47ecdcaf4aed176176" 42SRC_URI[sha256sum] = "b60d58d12632ecf1e8fad7316dc82c6b9738a35625746b47ecdcaf4aed176176"