]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
RAR5 reader: fix buffer overflow when parsing huffman tables.
authorGrzegorz Antoniak <ga@anadoxin.org>
Wed, 1 May 2019 04:21:58 +0000 (06:21 +0200)
committerGrzegorz Antoniak <ga@anadoxin.org>
Wed, 1 May 2019 04:21:58 +0000 (06:21 +0200)
RAR5 compresses its Huffman tables by using an algorithm similar to Run
Length Encoding. During uncompression of those tables, RAR5 reader
didn't perform enough checks to prevent from buffer overflow in some
cases.

This commit adds additional check that prevents from encountering a
buffer overflow error in some files.

The commit also adds a unit test to guard against regression of this
issue.

Fixes OSSFuzz case #12466.

libarchive/archive_read_support_format_rar5.c
libarchive/test/test_read_format_rar5.c
libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu [new file with mode: 0644]

index 84d05c431e8bca0b07c386c9935eff86cf085231..cf897657caf36d81657b1c8482f8e4d438a90f87 100644 (file)
@@ -2323,7 +2323,7 @@ static int parse_tables(struct archive_read* a, struct rar5* rar,
                 int k;
 
                 /* Fill zeroes. */
-                for(k = 0; k < value + 2; k++) {
+                for(k = 0; (k < value + 2) && (w < HUFF_BC); k++) {
                     bit_length[w++] = 0;
                 }
             }
index 9b684a73a9e3306d57730a9e445ef919de60da63..d52b6002c54d45df905bfa75dcbb39304839c700 100644 (file)
@@ -950,3 +950,18 @@ DEFINE_TEST(test_read_format_rar5_extra_field_version)
 
     EPILOGUE();
 }
+
+DEFINE_TEST(test_read_format_rar5_readtables_overflow)
+{
+    uint8_t buf[16];
+
+    PROLOGUE("test_read_format_rar5_readtables_overflow.rar");
+
+    assertA(0 == archive_read_next_header(a, &ae));
+    /* This archive is invalid. However, processing it shouldn't cause any
+     * buffer overflow errors during reading rar5 tables. */
+    assertA(0 == archive_read_data(a, buf, sizeof(buf)));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+
+    EPILOGUE();
+}
diff --git a/libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu b/libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu
new file mode 100644 (file)
index 0000000..611c2af
--- /dev/null
@@ -0,0 +1,15 @@
+begin 644 test_read_format_rar5_readtables_overflow.rar
+M4F%R(1H'`0"-[P+2`)3+'_4`C>\"T@`"T@"4RQ_5]0#O0````,L?Q_T``(`"
+MT@"4RQ_=V-C8`)3+']W=]0"-\`+2`)3+']WU`(WO`M(``M(`E,L?U?4`[P+2
+M`)3+'\?]``"``M(`E,L?W=C8V`"4RQ_=]0#V`(WO`M'UV,?8V-C8$=C8V-C8
+MV(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V-C8!]C8V-C8V-C8V-C8V-C8V-C8
+MV-C8V-C8V-C(V-C8V-C2`)3+']W8V-C8V-C8V-C8V-C8V-C8@-C8V-C8V-C8
+MV/+8V-C8V-C8V-C8`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8!-C8
+MV-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8`(`"V`7V`(WO`M'U`]L?
+MW?4`C>\"T@`"T@"4'__U`(WO`N``E,L?W84`C0`0T@"4RQ_=V-C8V-C8V`"4
+MR_\R]0#V`(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8
+MV-C8V-C8V-C8V-C8R-C8V-C8T@"4RQ_=V-C8V-C8V-C8V-C8V-C8V(#8V-C8
+MV-C8````9-C8V-C8V!'8V-C8V-C8]]C8V-C8V-C8V-C8V/+8V-C8V-C8V-C8
+=`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-@`
+`
+end