diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | libarchive/archive_read_support_format_rar5.c | 10 | ||||
-rw-r--r-- | libarchive/test/test_read_format_rar5.c | 19 | ||||
-rw-r--r-- | libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu | 7 |
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 |