summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch')
-rw-r--r--meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch321
1 files changed, 321 insertions, 0 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