summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/libarchive/libarchive/0001-RAR5-reader-reject-files-that-declare-invalid-header.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-extended/libarchive/libarchive/0001-RAR5-reader-reject-files-that-declare-invalid-header.patch')
-rw-r--r--meta/recipes-extended/libarchive/libarchive/0001-RAR5-reader-reject-files-that-declare-invalid-header.patch124
1 files changed, 124 insertions, 0 deletions
diff --git a/meta/recipes-extended/libarchive/libarchive/0001-RAR5-reader-reject-files-that-declare-invalid-header.patch b/meta/recipes-extended/libarchive/libarchive/0001-RAR5-reader-reject-files-that-declare-invalid-header.patch
new file mode 100644
index 0000000000..a84c1f1f76
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/0001-RAR5-reader-reject-files-that-declare-invalid-header.patch
@@ -0,0 +1,124 @@
1From c1fe0a8cc8dde8ba3eae3d17e34060d2d6e4eb96 Mon Sep 17 00:00:00 2001
2From: Grzegorz Antoniak <ga@anadoxin.org>
3Date: Sun, 2 Feb 2020 08:04:41 +0100
4Subject: [PATCH] RAR5 reader: reject files that declare invalid header flags
5
6One of the fields in RAR5's base block structure is the size of the
7header. Some invalid files declare a 0 header size setting, which can
8confuse the unpacker. Minimum header size for RAR5 base blocks is 7
9bytes (4 bytes for CRC, and 3 bytes for the rest), so block size of 0
10bytes should be rejected at header parsing stage.
11
12The fix adds an error condition if header size of 0 bytes is detected.
13In this case, the unpacker will not attempt to unpack the file, as the
14header is corrupted.
15
16The commit also adds OSSFuzz #20459 sample to test further regressions
17in this area.
18
19Upstream-Status: Backport[https://github.com/libarchive/libarchive/commit/94821008d6eea81e315c5881cdf739202961040a]
20CVE: CVE-2020-9308
21
22Signed-off-by: Wenlin Kang <wenlin.kang@windriver.com>
23---
24 Makefile.am | 1 +
25 libarchive/archive_read_support_format_rar5.c | 17 +++++++++++++++--
26 libarchive/test/test_read_format_rar5.c | 15 +++++++++++++++
27 ...d_format_rar5_block_size_is_too_small.rar.uu | 8 ++++++++
28 4 files changed, 39 insertions(+), 2 deletions(-)
29 create mode 100644 libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu
30
31diff --git a/Makefile.am b/Makefile.am
32index da78b24..01abf20 100644
33--- a/Makefile.am
34+++ b/Makefile.am
35@@ -863,6 +863,7 @@ libarchive_test_EXTRA_DIST=\
36 libarchive/test/test_read_format_rar5_symlink.rar.uu \
37 libarchive/test/test_read_format_rar5_truncated_huff.rar.uu \
38 libarchive/test/test_read_format_rar5_win32.rar.uu \
39+ libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \
40 libarchive/test/test_read_format_raw.bufr.uu \
41 libarchive/test/test_read_format_raw.data.gz.uu \
42 libarchive/test/test_read_format_raw.data.Z.uu \
43diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c
44index 7c24627..f73393c 100644
45--- a/libarchive/archive_read_support_format_rar5.c
46+++ b/libarchive/archive_read_support_format_rar5.c
47@@ -2034,6 +2034,8 @@ static int scan_for_signature(struct archive_read* a);
48 static int process_base_block(struct archive_read* a,
49 struct archive_entry* entry)
50 {
51+ const size_t SMALLEST_RAR5_BLOCK_SIZE = 3;
52+
53 struct rar5* rar = get_context(a);
54 uint32_t hdr_crc, computed_crc;
55 size_t raw_hdr_size = 0, hdr_size_len, hdr_size;
56@@ -2057,15 +2059,26 @@ static int process_base_block(struct archive_read* a,
57 return ARCHIVE_EOF;
58 }
59
60+ hdr_size = raw_hdr_size + hdr_size_len;
61+
62 /* Sanity check, maximum header size for RAR5 is 2MB. */
63- if(raw_hdr_size > (2 * 1024 * 1024)) {
64+ if(hdr_size > (2 * 1024 * 1024)) {
65 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
66 "Base block header is too large");
67
68 return ARCHIVE_FATAL;
69 }
70
71- hdr_size = raw_hdr_size + hdr_size_len;
72+ /* Additional sanity checks to weed out invalid files. */
73+ if(raw_hdr_size == 0 || hdr_size_len == 0 ||
74+ hdr_size < SMALLEST_RAR5_BLOCK_SIZE)
75+ {
76+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
77+ "Too small block encountered (%ld bytes)",
78+ raw_hdr_size);
79+
80+ return ARCHIVE_FATAL;
81+ }
82
83 /* Read the whole header data into memory, maximum memory use here is
84 * 2MB. */
85diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c
86index 1408f37..32e7ed8 100644
87--- a/libarchive/test/test_read_format_rar5.c
88+++ b/libarchive/test/test_read_format_rar5.c
89@@ -1194,3 +1194,18 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
90
91 EPILOGUE();
92 }
93+
94+DEFINE_TEST(test_read_format_rar5_block_size_is_too_small)
95+{
96+ char buf[4096];
97+ PROLOGUE("test_read_format_rar5_block_size_is_too_small.rar");
98+
99+ /* This file is damaged, so those functions should return failure.
100+ * Additionally, SIGSEGV shouldn't be raised during execution
101+ * of those functions. */
102+
103+ assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK);
104+ assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
105+
106+ EPILOGUE();
107+}
108diff --git a/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu b/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu
109new file mode 100644
110index 0000000..5cad219
111--- /dev/null
112+++ b/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu
113@@ -0,0 +1,8 @@
114+begin 644 test_read_format_rar5_block_size_is_too_small.rar
115+M4F%R(1H'`0"-[P+2``+'(!P,("`@N`,!`B`@("`@("`@("`@("`@("#_("`@
116+M("`@("`@("`@((:Q;2!4-'-^4B`!((WO`M(``O\@$/\@-R`@("`@("`@("`@
117+M``X@("`@("`@____("`@("`@(/\@("`@("`@("`@("#_(+6U,2"UM;6UM[CU
118+M)B`@*(0G(`!.`#D\3R``(/__(,+_````-0#_($&%*/HE=C+N`"```"```"`D
119+J`)$#("#_("#__P`@__\@_R#_("`@("`@("#_("#__R`@(/__("#__R`"
120+`
121+end
122--
1232.23.0
124