From: Martin Matuska Date: Sat, 15 Jun 2019 20:32:35 +0000 (+0200) Subject: RAR reader: extend fix user after free X-Git-Tag: v3.4.1~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cb76165ac5b091545c32d26483b0c0d7a2c47e4f;p=thirdparty%2Flibarchive.git RAR reader: extend fix user after free If read_data_compressed() returns ARCHIVE_FAILED, the caller is allowed to continue with next archive headers. In addition to rar->start_new_table=1 we need to set rar->ppmd_valid=0. Reported by: OSS-Fuzz issue 15120 --- diff --git a/Makefile.am b/Makefile.am index da78b24ac..1ac3218ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -826,6 +826,7 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_format_rar_noeof.rar.uu \ libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \ libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu \ + libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu \ libarchive/test/test_read_format_rar_sfx.exe.uu \ libarchive/test/test_read_format_rar_subblock.rar.uu \ libarchive/test/test_read_format_rar_unicode.rar.uu \ diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c index 49360876c..41e5a3cad 100644 --- a/libarchive/archive_read_support_format_rar.c +++ b/libarchive/archive_read_support_format_rar.c @@ -1027,6 +1027,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff, if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) { __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); rar->start_new_table = 1; + rar->ppmd_valid = 0; } break; diff --git a/libarchive/test/test_read_format_rar.c b/libarchive/test/test_read_format_rar.c index f08b06bc6..57dece389 100644 --- a/libarchive/test/test_read_format_rar.c +++ b/libarchive/test/test_read_format_rar.c @@ -3779,3 +3779,26 @@ DEFINE_TEST(test_read_format_rar_ppmd_use_after_free) assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } + +DEFINE_TEST(test_read_format_rar_ppmd_use_after_free2) +{ + uint8_t buf[16]; + const char* reffile = "test_read_format_rar_ppmd_use_after_free2.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_all(a)); + assertA(0 == archive_read_open_filename(a, reffile, 10240)); + + assertA(ARCHIVE_OK == archive_read_next_header(a, &ae)); + assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); + assertA(ARCHIVE_OK == archive_read_next_header(a, &ae)); + assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} diff --git a/libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu b/libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu new file mode 100644 index 000000000..03c2eadfa --- /dev/null +++ b/libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu @@ -0,0 +1,10 @@ +begin 664 test_read_format_rar_ppmd_use_after_free2.rar +M4F%R(1H'``1G=$Q24`!W````>U!+`P0Q`'#_J7\`+@TU'`#]`0`7__]"0D)" +M+W5N)B8F)F=I9`UD#1T+``!"`````````&%R(1H'``3_________`F@`H2`` +M``"`P\/#2\/#P\/#P\/#P\-3PP"`P\/#PYZ>AYZ>GI[#4\,`@,/#`L,@(""= +M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(/______ +M__\@("`@("`@("`@("`@("`@("`@("`@("`$9W1,4E``=P```'M02P,$,0!P +M_ZE_`"X--1P`_0$`%___0D)"0B]U;B8F)B9G:60-9`T="P``0@````````!A +0