diff --git a/Makefile.am b/Makefile.am index 3e2dc629807d..d26eac1bbb83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -454,6 +454,7 @@ libarchive_test_SOURCES= \ libarchive/test/test_read_format_rar_encryption_data.c \ libarchive/test/test_read_format_rar_encryption_partially.c \ libarchive/test/test_read_format_rar_encryption_header.c \ + libarchive/test/test_read_format_rar_invalid1.c \ libarchive/test/test_read_format_raw.c \ libarchive/test/test_read_format_tar.c \ libarchive/test/test_read_format_tar_concatenated.c \ @@ -747,6 +748,7 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_format_rar_encryption_data.rar.uu \ libarchive/test/test_read_format_rar_encryption_header.rar.uu \ libarchive/test/test_read_format_rar_encryption_partially.rar.uu \ + libarchive/test/test_read_format_rar_invalid1.rar.uu \ libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu \ libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu \ libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu \ diff --git a/NEWS b/NEWS index 5bf877606244..f672d3dfe3cb 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Jun 20, 2016: libarchive 3.2.1 released + This fixes a handful of security and other critical issues with 3.2.0 + +May 01, 2016: libarchive 3.2.0 released + Apr 09, 2016: libarchive 3.1.901a released Another test release in preparation for 3.2.0 diff --git a/build/version b/build/version index 595378f1050c..f293156370c5 100644 --- a/build/version +++ b/build/version @@ -1 +1 @@ -3002000 +3002001 diff --git a/configure.ac b/configure.ac index 06381824d4ae..e15ceee1e5ff 100644 --- a/configure.ac +++ b/configure.ac @@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front. dnl In particular, this allows the version macro to be used in AC_INIT dnl These first two version numbers are updated automatically on each release. -m4_define([LIBARCHIVE_VERSION_S],[3.2.0]) -m4_define([LIBARCHIVE_VERSION_N],[3002000]) +m4_define([LIBARCHIVE_VERSION_S],[3.2.1]) +m4_define([LIBARCHIVE_VERSION_N],[3002001]) dnl bsdtar and bsdcpio versioning tracks libarchive m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) diff --git a/libarchive/archive.h b/libarchive/archive.h index 59e9ef15eb60..1794dd34fc56 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -36,7 +36,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */ -#define ARCHIVE_VERSION_NUMBER 3002000 +#define ARCHIVE_VERSION_NUMBER 3002001 #include #include /* for wchar_t */ @@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_ONLY_STRING "3.2.0" +#define ARCHIVE_VERSION_ONLY_STRING "3.2.1" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h index 423c8d3ff7b1..dab2c9d82878 100644 --- a/libarchive/archive_entry.h +++ b/libarchive/archive_entry.h @@ -29,7 +29,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */ -#define ARCHIVE_VERSION_NUMBER 3002000 +#define ARCHIVE_VERSION_NUMBER 3002001 /* * Note: archive_entry.h is for use outside of libarchive; the diff --git a/libarchive/archive_ppmd7.c b/libarchive/archive_ppmd7.c index fe0b0318cc05..1aed922db656 100644 --- a/libarchive/archive_ppmd7.c +++ b/libarchive/archive_ppmd7.c @@ -126,6 +126,11 @@ static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) { if (p->Base == 0 || p->Size != size) { + /* RestartModel() below assumes that p->Size >= UNIT_SIZE + (see the calculation of m->MinContext). */ + if (size < UNIT_SIZE) { + return False; + } Ppmd7_Free(p, alloc); p->AlignOffset = #ifdef PPMD_32BIT diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c index 90901acb710f..1dfe52b8539a 100644 --- a/libarchive/archive_read_support_format_7zip.c +++ b/libarchive/archive_read_support_format_7zip.c @@ -2153,6 +2153,9 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss, return (-1); if (UMAX_ENTRY < f[i].numUnpackStreams) return (-1); + if (unpack_streams > SIZE_MAX - UMAX_ENTRY) { + return (-1); + } unpack_streams += (size_t)f[i].numUnpackStreams; } if ((p = header_bytes(a, 1)) == NULL) diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c index 6934ceefe9db..f41ba3865623 100644 --- a/libarchive/archive_read_support_format_iso9660.c +++ b/libarchive/archive_read_support_format_iso9660.c @@ -1091,7 +1091,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660) /* This condition is unlikely; by way of caution. */ vd = &(iso9660->joliet); - skipsize = LOGICAL_BLOCK_SIZE * vd->location; + skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location; skipsize = __archive_read_consume(a, skipsize); if (skipsize < 0) return ((int)skipsize); @@ -1129,7 +1129,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660) && iso9660->seenJoliet) { /* Switch reading data from primary to joliet. */ vd = &(iso9660->joliet); - skipsize = LOGICAL_BLOCK_SIZE * vd->location; + skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location; skipsize -= iso9660->current_position; skipsize = __archive_read_consume(a, skipsize); if (skipsize < 0) diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c index 6450aac82785..f729f173645d 100644 --- a/libarchive/archive_read_support_format_rar.c +++ b/libarchive/archive_read_support_format_rar.c @@ -2127,6 +2127,12 @@ parse_codes(struct archive_read *a) rar->range_dec.Stream = &rar->bytein; __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); + if (rar->dictionary_size == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Invalid zero dictionary size"); + return (ARCHIVE_FATAL); + } + if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, rar->dictionary_size, &g_szalloc)) { @@ -2884,11 +2890,10 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer, } windowoffs = lzss_offset_for_position(&rar->lzss, startpos); - if(windowoffs + length <= lzss_size(&rar->lzss)) + if(windowoffs + length <= lzss_size(&rar->lzss)) { memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], length); - else - { + } else if (length <= lzss_size(&rar->lzss)) { firstpart = lzss_size(&rar->lzss) - windowoffs; if (firstpart < 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, @@ -2900,9 +2905,14 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer, &rar->lzss.window[windowoffs], firstpart); memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], &rar->lzss.window[0], length - firstpart); - } else + } else { memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], length); + } + } else { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Bad RAR file data"); + return (ARCHIVE_FATAL); } rar->unp_offset += length; if (rar->unp_offset >= rar->unp_buffer_size) diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt index b70be7422166..124aa3a8b1ba 100644 --- a/libarchive/test/CMakeLists.txt +++ b/libarchive/test/CMakeLists.txt @@ -143,6 +143,7 @@ IF(ENABLE_TEST) test_read_format_rar_encryption_data.c test_read_format_rar_encryption_header.c test_read_format_rar_encryption_partially.c + test_read_format_rar_invalid1.c test_read_format_raw.c test_read_format_tar.c test_read_format_tar_concatenated.c diff --git a/libarchive/test/test_write_format_gnutar_filenames.c b/libarchive/test/test_write_format_gnutar_filenames.c index 32f5ce4f32bb..38b4ca9d7fd7 100644 --- a/libarchive/test/test_write_format_gnutar_filenames.c +++ b/libarchive/test/test_write_format_gnutar_filenames.c @@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$"); * reads back to verify it. */ -static char filename[1024]; +static char filename[2048]; DEFINE_TEST(test_write_format_gnutar_filenames) {