diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c967c17 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libarchive-3.3.2.tar.gz diff --git a/.libarchive.metadata b/.libarchive.metadata new file mode 100644 index 0000000..f60f161 --- /dev/null +++ b/.libarchive.metadata @@ -0,0 +1 @@ +580064227105e30322caa6c67b59e8c8e6060027 SOURCES/libarchive-3.3.2.tar.gz diff --git a/SOURCES/fix-few-obvious-resource-leaks-covscan.patch b/SOURCES/fix-few-obvious-resource-leaks-covscan.patch new file mode 100644 index 0000000..a503633 --- /dev/null +++ b/SOURCES/fix-few-obvious-resource-leaks-covscan.patch @@ -0,0 +1,146 @@ +From 9d178fe573818764a2d15e0a39691f5eb4e300f6 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Mon, 27 May 2019 10:52:51 +0200 +Subject: [PATCH] Fix a few obvious resource leaks and strcpy() misuses + +Per Coverity report. +--- + cpio/cpio.c | 4 +++- + libarchive/archive_acl.c | 8 ++++++-- + libarchive/archive_write_set_format_iso9660.c | 4 ++-- + libarchive/archive_write_set_format_mtree.c | 4 ++-- + libarchive/archive_write_set_format_pax.c | 6 ++++-- + libarchive/archive_write_set_format_xar.c | 10 ++++++---- + 6 files changed, 23 insertions(+), 13 deletions(-) + +diff --git a/cpio/cpio.c b/cpio/cpio.c +index 5beedd0..6696bb5 100644 +--- a/cpio/cpio.c ++++ b/cpio/cpio.c +@@ -744,8 +744,10 @@ file_to_archive(struct cpio *cpio, const char *srcpath) + } + if (cpio->option_rename) + destpath = cpio_rename(destpath); +- if (destpath == NULL) ++ if (destpath == NULL) { ++ archive_entry_free(entry); + return (0); ++ } + archive_entry_copy_pathname(entry, destpath); + + /* +diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c +index b8b6b63..503f379 100644 +--- a/libarchive/archive_acl.c ++++ b/libarchive/archive_acl.c +@@ -753,8 +753,10 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags, + append_entry_w(&wp, prefix, ap->type, ap->tag, flags, + wname, ap->permset, id); + count++; +- } else if (r < 0 && errno == ENOMEM) ++ } else if (r < 0 && errno == ENOMEM) { ++ free(ws); + return (NULL); ++ } + } + + /* Add terminating character */ +@@ -975,8 +977,10 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags, + prefix = NULL; + r = archive_mstring_get_mbs_l( + &ap->name, &name, &len, sc); +- if (r != 0) ++ if (r != 0) { ++ free(s); + return (NULL); ++ } + if (count > 0) + *p++ = separator; + if (name == NULL || +diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c +index c0ca435..badc88b 100644 +--- a/libarchive/archive_write_set_format_iso9660.c ++++ b/libarchive/archive_write_set_format_iso9660.c +@@ -4899,10 +4899,10 @@ isofile_gen_utility_names(struct archive_write *a, struct isofile *file) + if (p[0] == '/') { + if (p[1] == '/') + /* Convert '//' --> '/' */ +- strcpy(p, p+1); ++ memmove(p, p+1, strlen(p+1) + 1); + else if (p[1] == '.' && p[2] == '/') + /* Convert '/./' --> '/' */ +- strcpy(p, p+2); ++ memmove(p, p+2, strlen(p+2) + 1); + else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { + /* Convert 'dir/dir1/../dir2/' + * --> 'dir/dir2/' +diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c +index 493d473..0f2431e 100644 +--- a/libarchive/archive_write_set_format_mtree.c ++++ b/libarchive/archive_write_set_format_mtree.c +@@ -1810,10 +1810,10 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file, + if (p[0] == '/') { + if (p[1] == '/') + /* Convert '//' --> '/' */ +- strcpy(p, p+1); ++ memmove(p, p+1, strlen(p+1) + 1); + else if (p[1] == '.' && p[2] == '/') + /* Convert '/./' --> '/' */ +- strcpy(p, p+2); ++ memmove(p, p+2, strlen(p+2) + 1); + else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { + /* Convert 'dir/dir1/../dir2/' + * --> 'dir/dir2/' +diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c +index 0eaf733..4863e46 100644 +--- a/libarchive/archive_write_set_format_pax.c ++++ b/libarchive/archive_write_set_format_pax.c +@@ -522,11 +522,13 @@ add_pax_acl(struct archive_write *a, + ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s", + "Can't translate ", attr, " to UTF-8"); + return(ARCHIVE_WARN); +- } else if (*p != '\0') { ++ } ++ ++ if (*p != '\0') { + add_pax_attr(&(pax->pax_header), + attr, p); +- free(p); + } ++ free(p); + return(ARCHIVE_OK); + } + +diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c +index 495f0d4..56cd33c 100644 +--- a/libarchive/archive_write_set_format_xar.c ++++ b/libarchive/archive_write_set_format_xar.c +@@ -2120,10 +2120,10 @@ file_gen_utility_names(struct archive_write *a, struct file *file) + if (p[0] == '/') { + if (p[1] == '/') + /* Convert '//' --> '/' */ +- strcpy(p, p+1); ++ memmove(p, p+1, strlen(p+1) + 1); + else if (p[1] == '.' && p[2] == '/') + /* Convert '/./' --> '/' */ +- strcpy(p, p+2); ++ memmove(p, p+2, strlen(p+2) + 1); + else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { + /* Convert 'dir/dir1/../dir2/' + * --> 'dir/dir2/' +@@ -3169,8 +3169,10 @@ save_xattrs(struct archive_write *a, struct file *file) + checksum_update(&(xar->a_sumwrk), + xar->wbuff, size); + if (write_to_temp(a, xar->wbuff, size) +- != ARCHIVE_OK) +- return (ARCHIVE_FATAL); ++ != ARCHIVE_OK) { ++ free(heap); ++ return (ARCHIVE_FATAL); ++ } + if (r == ARCHIVE_OK) { + xar->stream.next_out = xar->wbuff; + xar->stream.avail_out = sizeof(xar->wbuff); +-- +2.17.1 + diff --git a/SOURCES/fix-use-after-free-in-delayed-newc.patch b/SOURCES/fix-use-after-free-in-delayed-newc.patch new file mode 100644 index 0000000..2534d32 --- /dev/null +++ b/SOURCES/fix-use-after-free-in-delayed-newc.patch @@ -0,0 +1,78 @@ +From 6a71cce7ed735f83f9a6a6bad8beaa47f8d14734 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Mon, 27 May 2019 10:06:14 +0200 +Subject: [PATCH 1/2] Fix use-after-free in delayed link processing (newc + format) + +During archiving, if some of the "delayed" hard link entries +happened to disappear on filesystem (or become unreadable) for +some reason (most probably race), the old code free()d the 'entry' +and continued with the loop; the next loop though dereferenced +'entry' and crashed the archiver. + +Per report from Coverity. +--- + tar/write.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/tar/write.c b/tar/write.c +index 9c24566..3970de2 100644 +--- a/tar/write.c ++++ b/tar/write.c +@@ -540,8 +540,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) + lafe_warnc(archive_errno(disk), + "%s", archive_error_string(disk)); + bsdtar->return_value = 1; +- archive_entry_free(entry); +- continue; ++ goto next_entry; + } + + /* +@@ -559,13 +558,13 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) + bsdtar->return_value = 1; + else + archive_read_close(disk); +- archive_entry_free(entry); +- continue; ++ goto next_entry; + } + + write_file(bsdtar, a, entry); +- archive_entry_free(entry); + archive_read_close(disk); ++next_entry: ++ archive_entry_free(entry); + entry = NULL; + archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); + } +-- +2.17.1 + + +From a999ca882aeb8fce4f4f2ee1317f528984b47e8e Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Mon, 27 May 2019 10:34:48 +0200 +Subject: [PATCH 2/2] call missing archive_read_close() in write_archive() + +--- + tar/write.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tar/write.c b/tar/write.c +index 3970de2..63c619c 100644 +--- a/tar/write.c ++++ b/tar/write.c +@@ -556,8 +556,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) + "%s", archive_error_string(disk)); + if (r == ARCHIVE_FATAL) + bsdtar->return_value = 1; +- else +- archive_read_close(disk); ++ archive_read_close(disk); + goto next_entry; + } + +-- +2.17.1 + diff --git a/SOURCES/libarchive-3.1.2-CVE-2017-14503.patch b/SOURCES/libarchive-3.1.2-CVE-2017-14503.patch new file mode 100644 index 0000000..deebbed --- /dev/null +++ b/SOURCES/libarchive-3.1.2-CVE-2017-14503.patch @@ -0,0 +1,29 @@ +From 2c8c83b9731ff822fad6cc8c670ea5519c366a14 Mon Sep 17 00:00:00 2001 +From: Joerg Sonnenberger +Date: Thu, 19 Jul 2018 21:14:53 +0200 +Subject: [PATCH] Reject LHA archive entries with negative size. + +--- + libarchive/archive_read_support_format_lha.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c +index b8ef4ae1..95c99bb1 100644 +--- a/libarchive/archive_read_support_format_lha.c ++++ b/libarchive/archive_read_support_format_lha.c +@@ -701,6 +701,12 @@ archive_read_format_lha_read_header(struct archive_read *a, + * Prepare variables used to read a file content. + */ + lha->entry_bytes_remaining = lha->compsize; ++ if (lha->entry_bytes_remaining < 0) { ++ archive_set_error(&a->archive, ++ ARCHIVE_ERRNO_FILE_FORMAT, ++ "Invalid LHa entry size"); ++ return (ARCHIVE_FATAL); ++ } + lha->entry_offset = 0; + lha->entry_crc_calculated = 0; + +-- +2.20.1 + diff --git a/SOURCES/libarchive-3.1.2-CVE-2019-1000019.patch b/SOURCES/libarchive-3.1.2-CVE-2019-1000019.patch new file mode 100644 index 0000000..f05595e --- /dev/null +++ b/SOURCES/libarchive-3.1.2-CVE-2019-1000019.patch @@ -0,0 +1,58 @@ +From 65a23f5dbee4497064e9bb467f81138a62b0dae1 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 1 Jan 2019 16:01:40 +1100 +Subject: [PATCH 2/2] 7zip: fix crash when parsing certain archives + +Fuzzing with CRCs disabled revealed that a call to get_uncompressed_data() +would sometimes fail to return at least 'minimum' bytes. This can cause +the crc32() invocation in header_bytes to read off into invalid memory. + +A specially crafted archive can use this to cause a crash. + +An ASAN trace is below, but ASAN is not required - an uninstrumented +binary will also crash. + +==7719==ERROR: AddressSanitizer: SEGV on unknown address 0x631000040000 (pc 0x7fbdb3b3ec1d bp 0x7ffe77a51310 sp 0x7ffe77a51150 T0) +==7719==The signal is caused by a READ memory access. + #0 0x7fbdb3b3ec1c in crc32_z (/lib/x86_64-linux-gnu/libz.so.1+0x2c1c) + #1 0x84f5eb in header_bytes (/tmp/libarchive/bsdtar+0x84f5eb) + #2 0x856156 in read_Header (/tmp/libarchive/bsdtar+0x856156) + #3 0x84e134 in slurp_central_directory (/tmp/libarchive/bsdtar+0x84e134) + #4 0x849690 in archive_read_format_7zip_read_header (/tmp/libarchive/bsdtar+0x849690) + #5 0x5713b7 in _archive_read_next_header2 (/tmp/libarchive/bsdtar+0x5713b7) + #6 0x570e63 in _archive_read_next_header (/tmp/libarchive/bsdtar+0x570e63) + #7 0x6f08bd in archive_read_next_header (/tmp/libarchive/bsdtar+0x6f08bd) + #8 0x52373f in read_archive (/tmp/libarchive/bsdtar+0x52373f) + #9 0x5257be in tar_mode_x (/tmp/libarchive/bsdtar+0x5257be) + #10 0x51daeb in main (/tmp/libarchive/bsdtar+0x51daeb) + #11 0x7fbdb27cab96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310 + #12 0x41dd09 in _start (/tmp/libarchive/bsdtar+0x41dd09) + +This was primarly done with afl and FairFuzz. Some early corpus entries +may have been generated by qsym. +--- + libarchive/archive_read_support_format_7zip.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c +index bccbf896..b6d1505d 100644 +--- a/libarchive/archive_read_support_format_7zip.c ++++ b/libarchive/archive_read_support_format_7zip.c +@@ -2964,13 +2964,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size, + if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) { + /* Copy mode. */ + +- /* +- * Note: '1' here is a performance optimization. +- * Recall that the decompression layer returns a count of +- * available bytes; asking for more than that forces the +- * decompressor to combine reads by copying data. +- */ +- *buff = __archive_read_ahead(a, 1, &bytes_avail); ++ *buff = __archive_read_ahead(a, minimum, &bytes_avail); + if (bytes_avail <= 0) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, +-- +2.20.1 + diff --git a/SOURCES/libarchive-3.1.2-CVE-2019-1000020.patch b/SOURCES/libarchive-3.1.2-CVE-2019-1000020.patch new file mode 100644 index 0000000..b314520 --- /dev/null +++ b/SOURCES/libarchive-3.1.2-CVE-2019-1000020.patch @@ -0,0 +1,59 @@ +From 8312eaa576014cd9b965012af51bc1f967b12423 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 1 Jan 2019 17:10:49 +1100 +Subject: [PATCH 1/2] iso9660: Fail when expected Rockridge extensions is + missing + +A corrupted or malicious ISO9660 image can cause read_CE() to loop +forever. + +read_CE() calls parse_rockridge(), expecting a Rockridge extension +to be read. However, parse_rockridge() is structured as a while +loop starting with a sanity check, and if the sanity check fails +before the loop has run, the function returns ARCHIVE_OK without +advancing the position in the file. This causes read_CE() to retry +indefinitely. + +Make parse_rockridge() return ARCHIVE_WARN if it didn't read an +extension. As someone with no real knowledge of the format, this +seems more apt than ARCHIVE_FATAL, but both the call-sites escalate +it to a fatal error immediately anyway. + +Found with a combination of AFL, afl-rb (FairFuzz) and qsym. +--- + libarchive/archive_read_support_format_iso9660.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c +index 28acfefb..bad8f1df 100644 +--- a/libarchive/archive_read_support_format_iso9660.c ++++ b/libarchive/archive_read_support_format_iso9660.c +@@ -2102,6 +2102,7 @@ parse_rockridge(struct archive_read *a, struct file_info *file, + const unsigned char *p, const unsigned char *end) + { + struct iso9660 *iso9660; ++ int entry_seen = 0; + + iso9660 = (struct iso9660 *)(a->format->data); + +@@ -2257,8 +2258,16 @@ parse_rockridge(struct archive_read *a, struct file_info *file, + } + + p += p[2]; ++ entry_seen = 1; ++ } ++ ++ if (entry_seen) ++ return (ARCHIVE_OK); ++ else { ++ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, ++ "Tried to parse Rockridge extensions, but none found"); ++ return (ARCHIVE_WARN); + } +- return (ARCHIVE_OK); + } + + static int +-- +2.20.1 + diff --git a/SOURCES/libarchive-3.3.2-CVE-2018-1000877.patch b/SOURCES/libarchive-3.3.2-CVE-2018-1000877.patch new file mode 100644 index 0000000..e980aa6 --- /dev/null +++ b/SOURCES/libarchive-3.3.2-CVE-2018-1000877.patch @@ -0,0 +1,34 @@ +From 88311f46cdfc719d26bb99d3b47944eb92ceae02 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Tue, 30 Apr 2019 11:50:33 +0200 +Subject: [PATCH] Avoid a double-free when a window size of 0 is specified + +new_size can be 0 with a malicious or corrupted RAR archive. + +realloc(area, 0) is equivalent to free(area), so the region would +be free()d here and the free()d again in the cleanup function. + +Found with a setup running AFL, afl-rb, and qsym. +--- + libarchive/archive_read_support_format_rar.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c +index c4a8278..3f88eef 100644 +--- a/libarchive/archive_read_support_format_rar.c ++++ b/libarchive/archive_read_support_format_rar.c +@@ -2317,6 +2317,11 @@ parse_codes(struct archive_read *a) + new_size = DICTIONARY_MAX_SIZE; + else + new_size = rar_fls((unsigned int)rar->unp_size) << 1; ++ if (new_size == 0) { ++ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, ++ "Zero window size is invalid."); ++ return (ARCHIVE_FATAL); ++ } + new_window = realloc(rar->lzss.window, new_size); + if (new_window == NULL) { + archive_set_error(&a->archive, ENOMEM, +-- +2.17.1 + diff --git a/SOURCES/libarchive-3.3.2-CVE-2018-1000878.patch b/SOURCES/libarchive-3.3.2-CVE-2018-1000878.patch new file mode 100644 index 0000000..2736827 --- /dev/null +++ b/SOURCES/libarchive-3.3.2-CVE-2018-1000878.patch @@ -0,0 +1,75 @@ +From d00ccaf8c20efbd009964e3e2697d26907d14163 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Tue, 30 Apr 2019 11:36:08 +0200 +Subject: [PATCH] rar: file split across multi-part archives must match + +Fuzzing uncovered some UAF and memory overrun bugs where a file in a +single file archive reported that it was split across multiple +volumes. This was caused by ppmd7 operations calling +rar_br_fillup. This would invoke rar_read_ahead, which would in some +situations invoke archive_read_format_rar_read_header. That would +check the new file name against the old file name, and if they didn't +match up it would free the ppmd7 buffer and allocate a new +one. However, because the ppmd7 decoder wasn't actually done with the +buffer, it would continue to used the freed buffer. Both reads and +writes to the freed region can be observed. + +This is quite tricky to solve: once the buffer has been freed it is +too late, as the ppmd7 decoder functions almost universally assume +success - there's no way for ppmd_read to signal error, nor are there +good ways for functions like Range_Normalise to propagate them. So we +can't detect after the fact that we're in an invalid state - e.g. by +checking rar->cursor, we have to prevent ourselves from ever ending up +there. So, when we are in the dangerous part or rar_read_ahead that +assumes a valid split, we set a flag force read_header to either go +down the path for split files or bail. This means that the ppmd7 +decoder keeps a valid buffer and just runs out of data. + +Found with a combination of AFL, afl-rb and qsym. +--- + libarchive/archive_read_support_format_rar.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c +index cbb14c3..c4a8278 100644 +--- a/libarchive/archive_read_support_format_rar.c ++++ b/libarchive/archive_read_support_format_rar.c +@@ -258,6 +258,7 @@ struct rar + struct data_block_offsets *dbo; + unsigned int cursor; + unsigned int nodes; ++ char filename_must_match; + + /* LZSS members */ + struct huffman_code maincode; +@@ -1570,6 +1571,12 @@ read_header(struct archive_read *a, struct archive_entry *entry, + } + return ret; + } ++ else if (rar->filename_must_match) ++ { ++ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, ++ "Mismatch of file parts split across multi-volume archive"); ++ return (ARCHIVE_FATAL); ++ } + + rar->filename_save = (char*)realloc(rar->filename_save, + filename_size + 1); +@@ -2938,12 +2945,14 @@ rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) + else if (*avail == 0 && rar->main_flags & MHD_VOLUME && + rar->file_flags & FHD_SPLIT_AFTER) + { ++ rar->filename_must_match = 1; + ret = archive_read_format_rar_read_header(a, a->entry); + if (ret == (ARCHIVE_EOF)) + { + rar->has_endarc_header = 1; + ret = archive_read_format_rar_read_header(a, a->entry); + } ++ rar->filename_must_match = 0; + if (ret != (ARCHIVE_OK)) + return NULL; + return rar_read_ahead(a, min, avail); +-- +2.17.1 + diff --git a/SOURCES/libarchive-3.3.2-CVE-2019-18408.patch b/SOURCES/libarchive-3.3.2-CVE-2019-18408.patch new file mode 100644 index 0000000..1811e77 --- /dev/null +++ b/SOURCES/libarchive-3.3.2-CVE-2019-18408.patch @@ -0,0 +1,31 @@ +From 1abcbf1af5209631ccf4fca4ddcab3c863294c85 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Patrik=20Novotn=C3=BD?= +Date: Wed, 15 Jan 2020 16:10:04 +0100 +Subject: [PATCH] RAR reader: fix use after free + +If read_data_compressed() returns ARCHIVE_FAILED, the caller is allowed +to continue with next archive headers. We need to set rar->start_new_table +after the ppmd7_context got freed, otherwise it won't be allocated again. +--- + libarchive/archive_read_support_format_rar.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c +index cbb14c32..9c26ef97 100644 +--- a/libarchive/archive_read_support_format_rar.c ++++ b/libarchive/archive_read_support_format_rar.c +@@ -1037,8 +1037,10 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff, + case COMPRESS_METHOD_GOOD: + case COMPRESS_METHOD_BEST: + ret = read_data_compressed(a, buff, size, offset); +- if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) ++ if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) { + __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); ++ rar->start_new_table = 1; ++ } + break; + + default: +-- +2.24.1 + diff --git a/SOURCES/libarchive-3.3.2-CVE-2019-19221.patch b/SOURCES/libarchive-3.3.2-CVE-2019-19221.patch new file mode 100644 index 0000000..86279ad --- /dev/null +++ b/SOURCES/libarchive-3.3.2-CVE-2019-19221.patch @@ -0,0 +1,98 @@ +From 72085b30bf30867360c4aa77bd43de5e1788d875 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Tue, 24 Mar 2020 09:22:47 +0100 +Subject: [PATCH] Bugfix and optimize archive_wstring_append_from_mbs() + +The cal to mbrtowc() or mbtowc() should read up to mbs_length +bytes and not wcs_length. This avoids out-of-bounds reads. + +mbrtowc() and mbtowc() return (size_t)-1 wit errno EILSEQ when +they encounter an invalid multibyte character and (size_t)-2 when +they they encounter an incomplete multibyte character. As we return +failure and all our callers error out it makes no sense to continue +parsing mbs. + +As we allocate `len` wchars at the beginning and each wchar has +at least one byte, there will never be need to grow the buffer, +so the code can be left out. On the other hand, we are always +allocatng more memory than we need. + +As long as wcs_length == mbs_length == len we can omit wcs_length. +We keep the old code commented if we decide to save memory and +use autoexpanding wcs_length in the future. +--- + libarchive/archive_string.c | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c +index 5ae09b6..d7541dc 100644 +--- a/libarchive/archive_string.c ++++ b/libarchive/archive_string.c +@@ -590,7 +590,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, + * No single byte will be more than one wide character, + * so this length estimate will always be big enough. + */ +- size_t wcs_length = len; ++ //size_t wcs_length = len; + size_t mbs_length = len; + const char *mbs = p; + wchar_t *wcs; +@@ -599,7 +599,11 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, + + memset(&shift_state, 0, sizeof(shift_state)); + #endif +- if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1)) ++ /* ++ * As we decided to have wcs_length == mbs_length == len ++ * we can use len here instead of wcs_length ++ */ ++ if (NULL == archive_wstring_ensure(dest, dest->length + len + 1)) + return (-1); + wcs = dest->s + dest->length; + /* +@@ -608,6 +612,12 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, + * multi bytes. + */ + while (*mbs && mbs_length > 0) { ++ /* ++ * The buffer we allocated is always big enough. ++ * Keep this code path in a comment if we decide to choose ++ * smaller wcs_length in the future ++ */ ++/* + if (wcs_length == 0) { + dest->length = wcs - dest->s; + dest->s[dest->length] = L'\0'; +@@ -617,24 +627,20 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, + return (-1); + wcs = dest->s + dest->length; + } ++*/ + #if HAVE_MBRTOWC +- r = mbrtowc(wcs, mbs, wcs_length, &shift_state); ++ r = mbrtowc(wcs, mbs, mbs_length, &shift_state); + #else +- r = mbtowc(wcs, mbs, wcs_length); ++ r = mbtowc(wcs, mbs, mbs_length); + #endif + if (r == (size_t)-1 || r == (size_t)-2) { + ret_val = -1; +- if (errno == EILSEQ) { +- ++mbs; +- --mbs_length; +- continue; +- } else +- break; ++ break; + } + if (r == 0 || r > mbs_length) + break; + wcs++; +- wcs_length--; ++ //wcs_length--; + mbs += r; + mbs_length -= r; + } +-- +2.24.1 + diff --git a/SPECS/libarchive.spec b/SPECS/libarchive.spec new file mode 100644 index 0000000..8f58511 --- /dev/null +++ b/SPECS/libarchive.spec @@ -0,0 +1,469 @@ +%bcond_without check + +Name: libarchive +Version: 3.3.2 +Release: 9%{?dist} +Summary: A library for handling streaming archive formats + +License: BSD +URL: http://www.libarchive.org/ +Source0: http://www.libarchive.org/downloads/%{name}-%{version}.tar.gz + +Patch0: libarchive-3.1.2-CVE-2017-14503.patch +Patch1: libarchive-3.1.2-CVE-2019-1000019.patch +Patch2: libarchive-3.1.2-CVE-2019-1000020.patch +Patch3: libarchive-3.3.2-CVE-2018-1000878.patch +Patch4: libarchive-3.3.2-CVE-2018-1000877.patch +Patch5: fix-use-after-free-in-delayed-newc.patch +Patch6: fix-few-obvious-resource-leaks-covscan.patch +Patch7: libarchive-3.3.2-CVE-2019-18408.patch +Patch8: libarchive-3.3.2-CVE-2019-19221.patch + +BuildRequires: gcc +BuildRequires: bison +BuildRequires: sharutils +BuildRequires: zlib-devel +BuildRequires: bzip2-devel +BuildRequires: xz-devel +BuildRequires: lzo-devel +BuildRequires: e2fsprogs-devel +BuildRequires: libacl-devel +BuildRequires: libattr-devel +BuildRequires: openssl-devel +BuildRequires: libxml2-devel +BuildRequires: lz4-devel +BuildRequires: automake + + +%description +Libarchive is a programming library that can create and read several different +streaming archive formats, including most popular tar variants, several cpio +formats, and both BSD and GNU ar variants. It can also write shar archives and +read ISO9660 CDROM images and ZIP archives. + + +%package devel +Summary: Development files for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + + +%package -n bsdtar +Summary: Manipulate tape archives +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description -n bsdtar +The bsdtar package contains standalone bsdtar utility split off regular +libarchive packages. + + +%package -n bsdcpio +Summary: Copy files to and from archives +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description -n bsdcpio +The bsdcpio package contains standalone bsdcpio utility split off regular +libarchive packages. + + +%package -n bsdcat +Summary: Expand files to standard output +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description -n bsdcat +The bsdcat program typically takes a filename as an argument or reads standard +input when used in a pipe. In both cases decompressed data it written to +standard output. + + +%prep +%autosetup -p1 + + +%build +%configure --disable-static --disable-rpath +# remove rpaths +sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool +sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool + +make %{?_smp_mflags} + + +%install +make install DESTDIR=$RPM_BUILD_ROOT +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' + +# rhbz#1294252 +replace () +{ + filename=$1 + file=`basename "$filename"` + binary=${file%%.*} + pattern=${binary##bsd} + + awk " + # replace the topic + /^.Dt ${pattern^^} 1/ { + print \".Dt ${binary^^} 1\"; + next; + } + # replace the first occurence of \"$pattern\" by \"$binary\" + !stop && /^.Nm $pattern/ { + print \".Nm $binary\" ; + stop = 1 ; + next; + } + # print remaining lines + 1; + " "$filename" > "$filename.new" + mv "$filename".new "$filename" +} + +for manpage in bsdtar.1 bsdcpio.1 +do + installed_manpage=`find "$RPM_BUILD_ROOT" -name "$manpage"` + replace "$installed_manpage" +done + + +%check +%if %{with check} +logfiles () +{ + find -name '*_test.log' -or -name test-suite.log +} + +tempdirs () +{ + cat `logfiles` \ + | awk "match(\$0, /[^[:space:]]*`date -I`[^[:space:]]*/) { print substr(\$0, RSTART, RLENGTH); }" \ + | sort | uniq +} + +cat_logs () +{ + for i in `logfiles` + do + echo "=== $i ===" + cat "$i" + done +} + +run_testsuite () +{ + rc=0 + LD_LIBRARY_PATH=`pwd`/.libs make %{?_smp_mflags} check -j1 || { + # error happened - try to extract in koji as much info as possible + cat_logs + + for i in `tempdirs`; do + if test -d "$i" ; then + find $i -printf "%p\n ~> a: %a\n ~> c: %c\n ~> t: %t\n ~> %s B\n" + cat $i/*.log + fi + done + return 1 + } + cat_logs +} + +# On a ppc/ppc64 is some race condition causing 'make check' fail on ppc +# when both 32 and 64 builds are done in parallel on the same machine in +# koji. Try to run once again if failed. +%ifarch ppc +run_testsuite || run_testsuite +%else +run_testsuite +%endif +%endif + + +%files +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc NEWS README.md +%{_libdir}/libarchive.so.13* +%{_mandir}/*/cpio.* +%{_mandir}/*/mtree.* +%{_mandir}/*/tar.* + +%files devel +%{_includedir}/*.h +%{_mandir}/*/archive* +%{_mandir}/*/libarchive* +%{_libdir}/libarchive.so +%{_libdir}/pkgconfig/libarchive.pc + +%files -n bsdtar +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc NEWS README.md +%{_bindir}/bsdtar +%{_mandir}/*/bsdtar* + +%files -n bsdcpio +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc NEWS README.md +%{_bindir}/bsdcpio +%{_mandir}/*/bsdcpio* + +%files -n bsdcat +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc NEWS README.md +%{_bindir}/bsdcat +%{_mandir}/*/bsdcat* + + + +%changelog +* Tue Mar 24 2020 Ondrej Dubaj - 3.3.2-9 +- Fix out-of-bounds read (CVE-2019-19221) (#1803967) + +* Wed Jan 15 2020 Patrik Novotný - 3.3.2-8 +- Fix CVE-2019-18408: RAR use-after-free + +* Mon May 27 2019 Ondrej Dubaj - 3.3.2-7 +- fix use-after-free in delayed newc link processing (#1602575) +- fix a few obvious resource leaks and strcpy() misuses (#1602575) + +* Tue Apr 30 2019 Ondrej Dubaj - 3.3.2-6 +- fixed use after free in RAR decoder (#1700752) +- fixed double free in RAR decoder (#1700753) + +* Tue Apr 02 2019 Ondrej Dubaj - 3.3.2-5 +- release bump due to gating (#1680768) + +* Fri Feb 22 2019 Pavel Raiskup - 3.3.2-4 +- fix out-of-bounds read within lha_read_data_none() (CVE-2017-14503) +- fix crash on crafted 7zip archives (CVE-2019-1000019) +- fix infinite loop in ISO9660 (CVE-2019-1000020) + +* Wed Jul 18 2018 Pavel Raiskup - 3.3.2-3 +- drop use of %%ldconfig_scriptlets + +* Fri Jul 13 2018 Fedora Release Engineering - 3.3.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Feb 08 2018 Pavel Raiskup - 3.3.2-1 +- rebase to latest upstream release + +* Wed Feb 07 2018 Fedora Release Engineering - 3.3.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Feb 03 2018 Igor Gnatenko - 3.3.1-4 +- Switch to %%ldconfig_scriptlets + +* Thu Aug 03 2017 Fedora Release Engineering - 3.3.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 3.3.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Apr 18 2017 Pavel Raiskup - 3.3.1-1 +- the latest release, per release notes: + https://groups.google.com/forum/#!topic/libarchive-discuss/jfc7lBfrvVg + +* Mon Feb 20 2017 Pavel Raiskup - 3.2.2-3 +- temporary work-around for FTBFS (rhbz#1423839) + +* Fri Feb 10 2017 Fedora Release Engineering - 3.2.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Nov 11 2016 Pavel Raiskup - 3.2.2-2 +- enable lz4 support, rhbz#1394038 + +* Tue Oct 25 2016 Pavel Raiskup - 3.2.2-1 +- minor rebase to 3.2.2 + +* Tue Oct 11 2016 Tomáš Mráz - 3.2.1-5 +- rebuild with OpenSSL 1.1.0 + +* Mon Sep 26 2016 Tomas Repik - 3.2.1-4 +- fix some stack and heap overflows +- resolves (rhbz#1378669, rhbz#1378668, rhbz#1378666) + +* Mon Aug 08 2016 Tomas Repik - 3.2.1-3 +- bump release for upgradepath + +* Mon Jul 18 2016 Pavel Raiskup - 3.2.1-2 +- print more detailed logs for testsuite, even if testsuite succeeded + +* Mon Jun 20 2016 Pavel Raiskup - 3.2.1-1 +- rebase, several security issues fixed (rhbz#1348194) + +* Mon May 16 2016 Pavel Raiskup - 3.2.0-3 +- fix the manual pages for remaining issue (rhbz#1294252) + +* Thu May 12 2016 Pavel Raiskup - 3.2.0-2 +- fix manual pages to mention correctly spelled binary names (rhbz#1294252) + +* Tue May 03 2016 Pavel Raiskup - 3.2.0-1 +- new upstream release 3.2.0 (rhbz#1330345), per release notes: + https://groups.google.com/d/msg/libarchive-discuss/qIzW7doKzxA/MVbUkjlNAAAJ + +* Mon Mar 07 2016 Björn Esser - 3.1.2-16 +- removed %%defattr, BuildRoot and other ancient bits +- added arch'ed bits to all Requires + +* Thu Feb 04 2016 Fedora Release Engineering - 3.1.2-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Dec 21 2015 Pavel Raiskup - 3.1.2-14 +- fix 'Out of memory when creating mtree files' error (rhbz#1284162) +- use %%autosetup macro + +* Wed Jun 17 2015 Fedora Release Engineering - 3.1.2-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Apr 29 2015 Pavel Raiskup - 3.1.2-12 +- fix libarchive segfault for intentionally broken cpio archives (rhbz#1216892) + +* Sat Feb 21 2015 Till Maas - 3.1.2-11 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Sun Aug 17 2014 Fedora Release Engineering - 3.1.2-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 17 2014 Tom Callaway - 3.1.2-9 +- fix license handling + +* Sat Jun 07 2014 Fedora Release Engineering - 3.1.2-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu Aug 08 2013 Jaromir Koncicky - 3.1.2-7 +- Fixed Bug 993048 - added #ifdef ACL_TYPE_NFS4 to code which requires + NFS4 ACL support + +* Sat Aug 03 2013 Fedora Release Engineering - 3.1.2-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Jul 22 2013 Pavel Raiskup - 3.1.2-5 +- try to workaround racy testsuite fail + +* Sun Jun 30 2013 Pavel Raiskup - 3.1.2-4 +- enable testsuite in the %%check phase + +* Mon Jun 24 2013 Pavel Raiskup - 3.1.2-3 +- bsdtar/bsdcpio should require versioned libarchive + +* Wed Apr 3 2013 Tomas Bzatek - 3.1.2-2 +- Remove libunistring-devel build require + +* Thu Mar 28 2013 Tomas Bzatek - 3.1.2-1 +- Update to 3.1.2 +- Fix CVE-2013-0211: read buffer overflow on 64-bit systems (#927105) + +* Thu Feb 14 2013 Fedora Release Engineering - 3.1.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Jan 14 2013 Tomas Bzatek - 3.1.1-1 +- Update to 3.1.1 +- NEWS seems to be valid UTF-8 nowadays + +* Wed Oct 03 2012 Pavel Raiskup - 3.0.4-3 +- better install manual pages for libarchive/bsdtar/bsdcpio (# ... ) +- several fedora-review fixes ...: +- Source0 has moved to github.com +- remove trailing white spaces +- repair summary to better describe bsdtar/cpiotar utilities + +* Thu Jul 19 2012 Fedora Release Engineering - 3.0.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon May 7 2012 Tomas Bzatek - 3.0.4-1 +- Update to 3.0.4 + +* Wed Feb 1 2012 Tomas Bzatek - 3.0.3-2 +- Enable bsdtar and bsdcpio in separate subpackages (#786400) + +* Fri Jan 13 2012 Tomas Bzatek - 3.0.3-1 +- Update to 3.0.3 + +* Fri Jan 13 2012 Fedora Release Engineering - 3.0.0-0.3.a +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Nov 15 2011 Rex Dieter 3.0.0-0.2.a +- track files/sonames closer, so abi bumps aren't a surprise +- tighten subpkg deps via %%_isa + +* Mon Nov 14 2011 Tomas Bzatek - 3.0.0-0.1.a +- Update to 3.0.0a (alpha release) + +* Mon Sep 5 2011 Tomas Bzatek - 2.8.5-1 +- Update to 2.8.5 + +* Mon Feb 07 2011 Fedora Release Engineering - 2.8.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Jan 13 2011 Tomas Bzatek - 2.8.4-2 +- Rebuild for new xz-libs + +* Wed Jun 30 2010 Tomas Bzatek - 2.8.4-1 +- Update to 2.8.4 + +* Fri Jun 25 2010 Tomas Bzatek - 2.8.3-2 +- Fix ISO9660 reader data type mismatches (#597243) + +* Tue Mar 16 2010 Tomas Bzatek - 2.8.3-1 +- Update to 2.8.3 + +* Mon Mar 8 2010 Tomas Bzatek - 2.8.1-1 +- Update to 2.8.1 + +* Fri Feb 5 2010 Tomas Bzatek - 2.8.0-1 +- Update to 2.8.0 + +* Wed Jan 6 2010 Tomas Bzatek - 2.7.902a-1 +- Update to 2.7.902a + +* Fri Aug 21 2009 Tomas Mraz - 2.7.1-2 +- rebuilt with new openssl + +* Fri Aug 7 2009 Tomas Bzatek 2.7.1-1 +- Update to 2.7.1 +- Drop deprecated lzma dependency, libxz handles both formats + +* Mon Jul 27 2009 Tomas Bzatek 2.7.0-3 +- Enable XZ compression format + +* Fri Jul 24 2009 Fedora Release Engineering - 2.7.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue May 12 2009 Tomas Bzatek 2.7.0-1 +- Update to 2.7.0 + +* Fri Mar 6 2009 Tomas Bzatek 2.6.2-1 +- Update to 2.6.2 + +* Wed Feb 25 2009 Fedora Release Engineering - 2.6.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Mon Feb 16 2009 Tomas Bzatek 2.6.1-1 +- Update to 2.6.1 + +* Thu Jan 8 2009 Tomas Bzatek 2.6.0-1 +- Update to 2.6.0 + +* Mon Dec 15 2008 Tomas Bzatek 2.5.904a-1 +- Update to 2.5.904a + +* Tue Dec 9 2008 Tomas Bzatek 2.5.903a-2 +- Add LZMA support + +* Mon Dec 8 2008 Tomas Bzatek 2.5.903a-1 +- Update to 2.5.903a + +* Tue Jul 22 2008 Tomas Bzatek 2.5.5-1 +- Update to 2.5.5 + +* Wed Apr 2 2008 Tomas Bzatek 2.4.17-1 +- Update to 2.4.17 + +* Wed Mar 19 2008 Tomas Bzatek 2.4.14-1 +- Initial packaging