From: Martin Matuška Date: Thu, 14 Aug 2025 21:20:01 +0000 (+0200) Subject: Merge pull request #2713 from antekone/bug/GH-2711/crash-when-rr/1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12c8b3f8952b5103835c6e6ef63005f11262e135;p=thirdparty%2Flibarchive.git Merge pull request #2713 from antekone/bug/GH-2711/crash-when-rr/1 RAR5 reader: fix multiple issues in extra field parsing function (cherry picked from commit 93f9e93d73caa0d0a06e3d32cb7483a11afc41e9) --- diff --git a/Makefile.am b/Makefile.am index 9dd37bb30..9d8873d1d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -921,6 +921,9 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_format_rar4_encrypted_filenames.rar.uu \ libarchive/test/test_read_format_rar4_solid_encrypted.rar.uu \ libarchive/test/test_read_format_rar4_solid_encrypted_filenames.rar.uu \ + libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu \ + libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu \ + libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu \ libarchive/test/test_read_format_rar5_encrypted.rar.uu \ libarchive/test/test_read_format_rar5_encrypted_filenames.rar.uu \ libarchive/test/test_read_format_rar5_solid_encrypted.rar.uu \ diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index 48dde0c2e..f2af82cfa 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -1619,10 +1619,13 @@ static int process_head_file_extra(struct archive_read* a, { uint64_t extra_field_size; uint64_t extra_field_id = 0; - int ret = ARCHIVE_FATAL; uint64_t var_size; while(extra_data_size > 0) { + /* Make sure we won't fail if the file declares only unsupported + attributes. */ + int ret = ARCHIVE_OK; + if(!read_var(a, &extra_field_size, &var_size)) return ARCHIVE_EOF; @@ -1675,12 +1678,26 @@ static int process_head_file_extra(struct archive_read* a, if (ARCHIVE_OK != consume(a, extra_field_size)) { return ARCHIVE_EOF; } + + /* Don't fail on unsupported attribute -- we've handled it + by skipping over it. */ + ret = ARCHIVE_OK; + } + + if (ret != ARCHIVE_OK) { + /* Forward any errors signalled by the attribute parsing + functions. */ + return ret; } } - if(ret != ARCHIVE_OK) { - /* Attribute not implemented. */ - return ret; + if (extra_data_size != 0) { + /* We didn't skip everything, or we skipped too much; either way, + there's an error in this parsing function. */ + + archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, + "unsupported structure of file header extra data"); + return ARCHIVE_FATAL; } return ARCHIVE_OK; diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c index fd233277b..202b66f68 100644 --- a/libarchive/test/test_read_format_rar5.c +++ b/libarchive/test/test_read_format_rar5.c @@ -1428,3 +1428,57 @@ DEFINE_TEST(test_read_format_rar5_data_ready_pointer_leak) EPILOGUE(); } + +DEFINE_TEST(test_read_format_rar5_only_crypt_exfld) +{ + /* GH #2711 */ + + char buf[4096]; + PROLOGUE("test_read_format_rar5_only_crypt_exfld.rar"); + + /* The reader should allow iteration through files, but should fail + during data extraction. */ + + assertA(archive_read_next_header(a, &ae) == ARCHIVE_OK); + assertA(archive_read_data(a, buf, sizeof(buf)) == ARCHIVE_FATAL); + + /* The reader should also provide a valid error message. */ + assertA(archive_error_string(a) != NULL); + + EPILOGUE(); +} + +DEFINE_TEST(test_read_format_rar5_only_unsupported_exfld) +{ + /* GH #2711 */ + + char buf[4096]; + PROLOGUE("test_read_format_rar5_unsupported_exfld.rar"); + + /* The reader should allow iteration through files, and it should + succeed with data extraction. */ + + assertA(archive_read_next_header(a, &ae) == ARCHIVE_OK); + + /* 48 is the expected number of bytes that should be extracted */ + assertA(archive_read_data(a, buf, sizeof(buf)) == 48); + + EPILOGUE(); +} + +DEFINE_TEST(test_read_format_rar5_invalidhash_and_validhtime_exfld) +{ + /* GH #2711 */ + + char buf[4096]; + PROLOGUE("test_read_format_rar5_invalid_hash_valid_htime_exfld.rar"); + + /* The reader should report an error when trying to process this data. + Returning EOF here means that the reader has failed to identify + malformed structure. */ + + assertA(archive_read_next_header(a, &ae) < 0); + assertA(archive_read_data(a, buf, sizeof(buf)) < 0); + + EPILOGUE(); +} diff --git a/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu b/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu new file mode 100644 index 000000000..399acd814 --- /dev/null +++ b/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu @@ -0,0 +1,6 @@ +begin 644 - +M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`#^T/5L)`(###$$,>V#`D840I@``0AF +M:6QE+G1X=`@"OX0]``$"`P(#`&EN=F%L:60@2$%32"!E>'1R82P@86YD(&QA +>=&5R(&$@=F%L:60@2%1)344@97AT)!,``0AF +M:6QE+G1X="0!```&``````````````````````````````````````````!R +M87(U('-T;W)E9"!F:6QE('=I=&@@;VYL>2!A($-265!4(&5X=')A(&9I96QD +'(#W?A@(%!``` +` +end diff --git a/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu b/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu new file mode 100644 index 000000000..16b456bf4 --- /dev/null +++ b/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu @@ -0,0 +1,6 @@ +begin 644 - +M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`#>[JDS)@(##C`$,.V#`BX6Z[0``0AF +M:6QE+G1X=`W_____#WA6-!(`````