summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--libarchive/archive_read_support_format_rar5.c10
-rw-r--r--libarchive/test/test_read_format_rar5.c19
-rw-r--r--libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu7
4 files changed, 37 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 1523c539..743aaa0d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -895,6 +895,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \
libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \
libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \
+ libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.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 \
diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c
index 880ba661..a3cfa72e 100644
--- a/libarchive/archive_read_support_format_rar5.c
+++ b/libarchive/archive_read_support_format_rar5.c
@@ -3731,6 +3731,16 @@ static int do_uncompress_file(struct archive_read* a) {
rar->cstate.initialized = 1;
}
+ /* Don't allow extraction if window_size is invalid. */
+ if(rar->cstate.window_size == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid window size declaration in this file");
+
+ /* This should never happen in valid files. */
+ return ARCHIVE_FATAL;
+ }
+
if(rar->cstate.all_filters_applied == 1) {
/* We use while(1) here, but standard case allows for just 1
* iteration. The loop will iterate if process_block() didn't
diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c
index 414401a1..acc90510 100644
--- a/libarchive/test/test_read_format_rar5.c
+++ b/libarchive/test/test_read_format_rar5.c
@@ -1328,3 +1328,22 @@ DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read)
EPILOGUE();
}
+
+DEFINE_TEST(test_read_format_rar5_bad_window_size_in_multiarchive_file)
+{
+ /* oss fuzz 30459 */
+
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_bad_window_sz_in_mltarc_file.rar");
+
+ /* This file is damaged, so those functions should return failure.
+ * Additionally, SIGSEGV shouldn't be raised during execution
+ * of those functions. */
+
+ (void) archive_read_next_header(a, &ae);
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
+ (void) archive_read_next_header(a, &ae);
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
+
+ EPILOGUE();
+} \ No newline at end of file
diff --git a/libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu b/libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu
new file mode 100644
index 00000000..7684bc19
--- /dev/null
+++ b/libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu
@@ -0,0 +1,7 @@
+begin 644 test_read_format_rar5_bad_window_size_in_multiarchive_file.rar
+M4F%R(1H'`0`]/-[E`@$`_R`@1#[Z5P("`PL`("`@@"(`"?\@("#___\@("`@
+M("`@("`@("`@4X`J]`,"YR(#$($@("`@``$@("`@@<L0("`@("`@("`@("`@
+M("`@(""LCTJA`P$%`B`@`2!3@"KT`P+G(@,@("`@_P,!!B`@(/___R`@(('+
+5$"`OX2`@[.SL[.S_("`@("`@("`@
+`
+end