libarchive/test/test_read_format_rar5_win32.rar.uu \
libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \
libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \
+ libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \
libarchive/test/test_read_format_raw.bufr.uu \
libarchive/test/test_read_format_raw.data.gz.uu \
libarchive/test/test_read_format_raw.data.Z.uu \
static int process_base_block(struct archive_read* a,
struct archive_entry* entry)
{
+ const size_t SMALLEST_RAR5_BLOCK_SIZE = 3;
+
struct rar5* rar = get_context(a);
uint32_t hdr_crc, computed_crc;
size_t raw_hdr_size = 0, hdr_size_len, hdr_size;
return ARCHIVE_EOF;
}
+ hdr_size = raw_hdr_size + hdr_size_len;
+
/* Sanity check, maximum header size for RAR5 is 2MB. */
- if(raw_hdr_size > (2 * 1024 * 1024)) {
+ if(hdr_size > (2 * 1024 * 1024)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Base block header is too large");
return ARCHIVE_FATAL;
}
- hdr_size = raw_hdr_size + hdr_size_len;
+ /* Additional sanity checks to weed out invalid files. */
+ if(raw_hdr_size == 0 || hdr_size_len == 0 ||
+ hdr_size < SMALLEST_RAR5_BLOCK_SIZE)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Too small block encountered (%ld bytes)",
+ raw_hdr_size);
+
+ return ARCHIVE_FATAL;
+ }
/* Read the whole header data into memory, maximum memory use here is
* 2MB. */
EPILOGUE();
}
+
+DEFINE_TEST(test_read_format_rar5_block_size_is_too_small)
+{
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_block_size_is_too_small.rar");
+
+ /* This file is damaged, so those functions should return failure.
+ * Additionally, SIGSEGV shouldn't be raised during execution
+ * of those functions. */
+
+ assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK);
+ assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
+
+ EPILOGUE();
+}
--- /dev/null
+begin 644 test_read_format_rar5_block_size_is_too_small.rar
+M4F%R(1H'`0"-[P+2``+'(!P,("`@N`,!`B`@("`@("`@("`@("`@("#_("`@
+M("`@("`@("`@((:Q;2!4-'-^4B`!((WO`M(``O\@$/\@-R`@("`@("`@("`@
+M``X@("`@("`@____("`@("`@(/\@("`@("`@("`@("#_(+6U,2"UM;6UM[CU
+M)B`@*(0G(`!.`#D\3R``(/__(,+_````-0#_($&%*/HE=C+N`"```"```"`D
+J`)$#("#_("#__P`@__\@_R#_("`@("`@("#_("#__R`@(/__("#__R`"
+`
+end