From: Grzegorz Antoniak Date: Sat, 4 May 2019 04:54:07 +0000 (+0200) Subject: RAR5 reader: fix integer overflow X-Git-Tag: v3.4.0~53^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F1187%2Fhead;p=thirdparty%2Flibarchive.git RAR5 reader: fix integer overflow This commit fixes an integer overflow triggering on invalid files during decompression. Also added a unit test. Should fix OSSFuzz issue #14555. --- diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index a2e5b68e7..370c663d5 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -2811,6 +2811,14 @@ static int do_uncompress_block(struct archive_read* a, const uint8_t* p) { return ARCHIVE_FATAL; } + if(dist >= INT_MAX - low_dist - 1) { + /* This only happens in invalid archives. */ + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Distance pointer overflow"); + return ARCHIVE_FATAL; + } + dist += low_dist; } else { /* dbits is one of [0,1,2,3] */ diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c index 5248172b0..a0f278133 100644 --- a/libarchive/test/test_read_format_rar5.c +++ b/libarchive/test/test_read_format_rar5.c @@ -1036,4 +1036,19 @@ DEFINE_TEST(test_read_format_rar5_invalid_dict_reference) assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); EPILOGUE(); -} \ No newline at end of file +} + +DEFINE_TEST(test_read_format_rar5_distance_overflow) +{ + uint8_t buf[16]; + + PROLOGUE("test_read_format_rar5_distance_overflow.rar"); + + assertA(0 == archive_read_next_header(a, &ae)); + /* This archive is invalid. However, processing it shouldn't cause any + * errors related to variable overflows when using -fsanitize. */ + assertA(ARCHIVE_FATAL == 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_distance_overflow.rar.uu b/libarchive/test/test_read_format_rar5_distance_overflow.rar.uu new file mode 100644 index 000000000..8fefa282e --- /dev/null +++ b/libarchive/test/test_read_format_rar5_distance_overflow.rar.uu @@ -0,0 +1,9 @@ +begin 644 test_read_format_rar5_distance_overflow.rar +M4F%R(1H'`0"-[P+2``(''/\@("`@_R4``B`@("`@("`@("`@(/__("`@("`@ +M(/\@("`@("`@((9ML63,PX"&AK%:S+?_(/\@_R#_(/\@_R#_(/\@`"``!R`@ +MR