From: Martin Matuska Date: Sat, 20 Apr 2019 10:12:28 +0000 (+0200) Subject: RAR5 reader: use unsigned int for volume number and check for range X-Git-Tag: v3.4.0~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5405343bfd53830b3d018b2d982845de851aba5c;p=thirdparty%2Flibarchive.git RAR5 reader: use unsigned int for volume number and check for range Fix an possible integer overflow. Reported by: OSS-Fuzz issue 13965 --- diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index a43afbfa0..cab50f830 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -33,6 +33,9 @@ #ifdef HAVE_ZLIB_H #include /* crc32 */ #endif +#ifdef HAVE_LIMITS_H +#include +#endif #include "archive.h" #ifndef HAVE_ZLIB_H @@ -281,7 +284,7 @@ struct main_header { uint8_t endarc : 1; uint8_t notused : 5; - int vol_no; + unsigned int vol_no; }; struct generic_header { @@ -293,7 +296,7 @@ struct generic_header { }; struct multivolume { - int expected_vol_no; + unsigned int expected_vol_no; uint8_t* push_buf; }; @@ -1722,8 +1725,12 @@ static int process_head_main(struct archive_read* a, struct rar5* rar, if(!read_var_sized(a, &v, NULL)) { return ARCHIVE_EOF; } - - rar->main.vol_no = (int) v; + if (v > UINT_MAX) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Invalid volume number"); + return ARCHIVE_FATAL; + } + rar->main.vol_no = (unsigned int) v; } else { rar->main.vol_no = 0; } @@ -1941,6 +1948,11 @@ static int process_base_block(struct archive_read* a, if(ret == ARCHIVE_FATAL) { return ARCHIVE_EOF; } else { + if(rar->vol.expected_vol_no == UINT_MAX) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, "Header error"); + return ARCHIVE_FATAL; + } rar->vol.expected_vol_no = rar->main.vol_no + 1; return ARCHIVE_OK; }