Merge pull request #3047 from legnaleurc/fix/rar-recovery-record
rar: skip NEWSUB payloads without size cap
(cherry picked from commit 82404ac239)
This commit is contained in:
1 parent
b9cf20973f
commit
7cbf4a8817
4 files changed
+23336
-7
No files matched your search
@@ -976,6 +976,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu \
|
||||
libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu \
|
||||
libarchive/test/test_read_format_rar_newsub_huge.rar.uu \
|
||||
libarchive/test/test_read_format_rar_newsub_rr_over_1m.rar.uu \
|
||||
libarchive/test/test_read_format_rar_noeof.rar.uu \
|
||||
libarchive/test/test_read_format_rar_overflow.rar.uu \
|
||||
libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \
|
||||
|
||||
@@ -124,7 +124,6 @@
|
||||
#define NS_UNIT 10000000
|
||||
|
||||
#define DICTIONARY_MAX_SIZE 0x400000
|
||||
#define RAR_MAX_NEWSUB_SIZE (1024 * 1024)
|
||||
|
||||
#define MAINCODE_SIZE 299
|
||||
#define OFFSETCODE_SIZE 60
|
||||
@@ -1514,8 +1513,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
* consumed at the end.
|
||||
*/
|
||||
if (head_type == NEWSUB_HEAD) {
|
||||
if (rar->packed_size > RAR_MAX_NEWSUB_SIZE ||
|
||||
rar->packed_size > INT64_MAX - header_size) {
|
||||
if (rar->packed_size > INT64_MAX - header_size) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Invalid RAR file: Overlarge extended header");
|
||||
return (ARCHIVE_FATAL);
|
||||
@@ -1526,7 +1524,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* NEWSUB blocks are metadata-only here; skip them without creating an entry. */
|
||||
/*
|
||||
* NEWSUB records are metadata-only in this reader. The block header
|
||||
* has already been validated, so it is safe to skip exactly the
|
||||
* remaining header bytes and the associated data payload.
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3906,6 +3906,25 @@ DEFINE_TEST(test_read_format_rar_newsub_huge)
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_rar_newsub_rr_over_1m)
|
||||
{
|
||||
const char* reffile = "test_read_format_rar_newsub_rr_over_1m.rar";
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
assertA(0 == archive_read_support_format_rar(a));
|
||||
assertA(0 == archive_read_open_filename(a, reffile, 10240));
|
||||
|
||||
failure("RAR NEWSUB RR records larger than 1 MiB should be skipped");
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_rar_newsub_huge64)
|
||||
{
|
||||
static const unsigned char archive[] = {
|
||||
@@ -3925,10 +3944,10 @@ DEFINE_TEST(test_read_format_rar_newsub_huge64)
|
||||
assertA(0 == archive_read_support_format_rar(a));
|
||||
assertA(0 == archive_read_open_memory(a, archive, sizeof(archive)));
|
||||
|
||||
failure("Malformed RAR NEWSUB header should be rejected before "
|
||||
"extended data read-ahead");
|
||||
failure("Malformed RAR NEWSUB header should be rejected if its "
|
||||
"extended data is missing");
|
||||
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
|
||||
assertEqualString("Invalid RAR file: Overlarge extended header",
|
||||
assertEqualString("Invalid RAR file: Cannot read extended header data",
|
||||
archive_error_string(a));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user