mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-28 08:02:54 +00:00
Update vendor/libarchive to libarchive/libarchive@72ce1ff7c
Bugfixes: OSS-Fuzz #44547 (security): fix heap-use-after-free in RAR (v4) filter code PR #1671: Fix 7z PPMD reading beyond boundary Obtained from: libarchive Libarchive commit: 72ce1ff7c6857a7334baa05884e69b9264a2199c
This commit is contained in:
parent
84631082f6
commit
3c540f9694
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -104,7 +104,7 @@ jobs:
|
||||
path: libarchive-dist.tar
|
||||
|
||||
Windows:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
be: [mingw-gcc, msvc]
|
||||
|
@ -21,7 +21,7 @@ endif()
|
||||
# RelWithDebInfo : Release build with Debug Info
|
||||
# MinSizeRel : Release Min Size build
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
|
||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
|
||||
# value type is "UNINITIALIZED".
|
||||
|
@ -51,7 +51,7 @@ IF "%1"=="deplibs" (
|
||||
mingw32-make test || EXIT /b 1
|
||||
mingw32-make install || EXIT /b 1
|
||||
) ELSE IF "%BE%"=="msvc" (
|
||||
cmake -G "Visual Studio 16 2019" . || EXIT /b 1
|
||||
cmake -G "Visual Studio 17 2022" . || EXIT /b 1
|
||||
cmake --build . --target ALL_BUILD --config Release || EXIT /b 1
|
||||
cmake --build . --target RUN_TESTS --config Release || EXIT /b 1
|
||||
cmake --build . --target INSTALL --config Release || EXIT /b 1
|
||||
@ -65,7 +65,7 @@ IF "%1"=="deplibs" (
|
||||
REM mingw32-make test || EXIT /b 1
|
||||
mingw32-make install || EXIT /b 1
|
||||
) ELSE IF "%BE%"=="msvc" (
|
||||
cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE="Release" -D ENABLE_LIB_ONLY=ON -D ENABLE_SHARED_LIB=OFF -D ENABLE_STATIC_LIB=ON . || EXIT /b 1
|
||||
cmake -G "Visual Studio 17 2022" -D CMAKE_BUILD_TYPE="Release" -D ENABLE_LIB_ONLY=ON -D ENABLE_SHARED_LIB=OFF -D ENABLE_STATIC_LIB=ON . || EXIT /b 1
|
||||
cmake --build . --target ALL_BUILD --config Release || EXIT /b 1
|
||||
REM cmake --build . --target RUN_TESTS --config Release || EXIT /b 1
|
||||
cmake --build . --target INSTALL --config Release || EXIT /b 1
|
||||
@ -78,7 +78,7 @@ IF "%1"=="deplibs" (
|
||||
mingw32-make || EXIT /b 1
|
||||
mingw32-make install || EXIT /b 1
|
||||
) ELSE IF "%BE%"=="msvc" (
|
||||
cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE="Release" . || EXIT /b 1
|
||||
cmake -G "Visual Studio 17 2022" -D CMAKE_BUILD_TYPE="Release" . || EXIT /b 1
|
||||
cmake --build . --target ALL_BUILD --config Release || EXIT /b 1
|
||||
cmake --build . --target INSTALL --config Release || EXIT /b 1
|
||||
)
|
||||
@ -91,7 +91,7 @@ IF "%1"=="deplibs" (
|
||||
) ELSE IF "%BE%"=="msvc" (
|
||||
MKDIR build_ci\cmake
|
||||
CD build_ci\cmake
|
||||
cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE="Release" -D ZLIB_LIBRARY="C:/Program Files (x86)/zlib/lib/zlibstatic.lib" -D ZLIB_INCLUDE_DIR="C:/Program Files (x86)/zlib/include" -D BZIP2_LIBRARIES="C:/Program Files (x86)/bzip2/lib/bz2.lib" -D BZIP2_INCLUDE_DIR="C:/Program Files (x86)/bzip2/include" -D LIBLZMA_LIBRARY="C:/Program Files (x86)/xz/lib/liblzma.lib" -D LIBLZMA_INCLUDE_DIR="C:/Program Files (x86)/xz/include" ..\.. || EXIT /b 1
|
||||
cmake -G "Visual Studio 17 2022" -D CMAKE_BUILD_TYPE="Release" -D ZLIB_LIBRARY="C:/Program Files (x86)/zlib/lib/zlibstatic.lib" -D ZLIB_INCLUDE_DIR="C:/Program Files (x86)/zlib/include" -D BZIP2_LIBRARIES="C:/Program Files (x86)/bzip2/lib/bz2.lib" -D BZIP2_INCLUDE_DIR="C:/Program Files (x86)/bzip2/include" -D LIBLZMA_LIBRARY="C:/Program Files (x86)/xz/lib/liblzma.lib" -D LIBLZMA_INCLUDE_DIR="C:/Program Files (x86)/xz/include" ..\.. || EXIT /b 1
|
||||
)
|
||||
) ELSE IF "%1%"=="build" (
|
||||
IF "%BE%"=="mingw-gcc" (
|
||||
|
@ -1 +1 @@
|
||||
3006000
|
||||
3006001dev
|
||||
|
@ -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.6.0])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3006000])
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.6.1dev])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3006001])
|
||||
|
||||
dnl bsdtar and bsdcpio versioning tracks libarchive
|
||||
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
|
||||
|
@ -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 3006000
|
||||
#define ARCHIVE_VERSION_NUMBER 3006001
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* 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.6.0"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.6.1dev"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
|
@ -13,11 +13,12 @@
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "archive_platform.h"
|
||||
#include "archive_blake2.h"
|
||||
#include "archive_blake2_impl.h"
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -21,7 +23,6 @@
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "archive_platform.h"
|
||||
#include "archive_blake2.h"
|
||||
#include "archive_blake2_impl.h"
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3006000
|
||||
#define ARCHIVE_VERSION_NUMBER 3006001
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
@ -287,6 +287,7 @@ struct _7zip {
|
||||
const unsigned char *next_in;
|
||||
int64_t avail_in;
|
||||
int64_t total_in;
|
||||
int64_t stream_in;
|
||||
unsigned char *next_out;
|
||||
int64_t avail_out;
|
||||
int64_t total_out;
|
||||
@ -986,15 +987,30 @@ ppmd_read(void *p)
|
||||
struct _7zip *zip = (struct _7zip *)(a->format->data);
|
||||
Byte b;
|
||||
|
||||
if (zip->ppstream.avail_in == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated RAR file data");
|
||||
zip->ppstream.overconsumed = 1;
|
||||
return (0);
|
||||
if (zip->ppstream.avail_in <= 0) {
|
||||
/*
|
||||
* Ppmd7_DecodeSymbol might require reading multiple bytes
|
||||
* and we are on boundary;
|
||||
* last resort to read using __archive_read_ahead.
|
||||
*/
|
||||
ssize_t bytes_avail = 0;
|
||||
const uint8_t* data = __archive_read_ahead(a,
|
||||
zip->ppstream.stream_in+1, &bytes_avail);
|
||||
if(bytes_avail < zip->ppstream.stream_in+1) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated 7z file data");
|
||||
zip->ppstream.overconsumed = 1;
|
||||
return (0);
|
||||
}
|
||||
zip->ppstream.next_in++;
|
||||
b = data[zip->ppstream.stream_in];
|
||||
} else {
|
||||
b = *zip->ppstream.next_in++;
|
||||
}
|
||||
b = *zip->ppstream.next_in++;
|
||||
zip->ppstream.avail_in--;
|
||||
zip->ppstream.total_in++;
|
||||
zip->ppstream.stream_in++;
|
||||
return (b);
|
||||
}
|
||||
|
||||
@ -1485,6 +1501,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
|
||||
}
|
||||
zip->ppstream.next_in = t_next_in;
|
||||
zip->ppstream.avail_in = t_avail_in;
|
||||
zip->ppstream.stream_in = 0;
|
||||
zip->ppstream.next_out = t_next_out;
|
||||
zip->ppstream.avail_out = t_avail_out;
|
||||
if (zip->ppmd7_stat == 0) {
|
||||
|
@ -430,7 +430,7 @@ static int new_node(struct huffman_code *);
|
||||
static int make_table(struct archive_read *, struct huffman_code *);
|
||||
static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
|
||||
struct huffman_table_entry *, int, int);
|
||||
static int64_t expand(struct archive_read *, int64_t);
|
||||
static int expand(struct archive_read *, int64_t *);
|
||||
static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
|
||||
int64_t, int);
|
||||
static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
|
||||
@ -1988,7 +1988,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
struct rar *rar;
|
||||
int64_t start, end, actualend;
|
||||
int64_t start, end;
|
||||
size_t bs;
|
||||
int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
|
||||
|
||||
@ -2179,11 +2179,12 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
end = rar->filters.filterstart;
|
||||
}
|
||||
|
||||
if ((actualend = expand(a, end)) < 0)
|
||||
return ((int)actualend);
|
||||
ret = expand(a, &end);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
|
||||
rar->bytes_uncopied = actualend - start;
|
||||
rar->filters.lastend = actualend;
|
||||
rar->bytes_uncopied = end - start;
|
||||
rar->filters.lastend = end;
|
||||
if (rar->filters.lastend != rar->filters.filterstart && rar->bytes_uncopied == 0) {
|
||||
/* Broken RAR files cause this case.
|
||||
* NOTE: If this case were possible on a normal RAR file
|
||||
@ -2825,8 +2826,8 @@ make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
expand(struct archive_read *a, int64_t end)
|
||||
static int
|
||||
expand(struct archive_read *a, int64_t *end)
|
||||
{
|
||||
static const unsigned char lengthbases[] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6,
|
||||
@ -2873,16 +2874,19 @@ expand(struct archive_read *a, int64_t end)
|
||||
struct rar *rar = (struct rar *)(a->format->data);
|
||||
struct rar_br *br = &(rar->br);
|
||||
|
||||
if (rar->filters.filterstart < end)
|
||||
end = rar->filters.filterstart;
|
||||
if (rar->filters.filterstart < *end)
|
||||
*end = rar->filters.filterstart;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if(lzss_position(&rar->lzss) >= end)
|
||||
return end;
|
||||
if(lzss_position(&rar->lzss) >= *end) {
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
if(rar->is_ppmd_block)
|
||||
return lzss_position(&rar->lzss);
|
||||
if(rar->is_ppmd_block) {
|
||||
*end = lzss_position(&rar->lzss);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
@ -2906,7 +2910,8 @@ expand(struct archive_read *a, int64_t end)
|
||||
goto truncated_data;
|
||||
rar->start_new_table = rar_br_bits(br, 1);
|
||||
rar_br_consume(br, 1);
|
||||
return lzss_position(&rar->lzss);
|
||||
*end = lzss_position(&rar->lzss);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2917,7 +2922,7 @@ expand(struct archive_read *a, int64_t end)
|
||||
}
|
||||
else if(symbol==257)
|
||||
{
|
||||
if (!read_filter(a, &end))
|
||||
if (!read_filter(a, end))
|
||||
return (ARCHIVE_FATAL);
|
||||
continue;
|
||||
}
|
||||
@ -3325,12 +3330,19 @@ run_filters(struct archive_read *a)
|
||||
struct rar_filter *filter = filters->stack;
|
||||
size_t start = filters->filterstart;
|
||||
size_t end = start + filter->blocklength;
|
||||
int64_t tend;
|
||||
uint32_t lastfilteraddress;
|
||||
uint32_t lastfilterlength;
|
||||
int ret;
|
||||
|
||||
filters->filterstart = INT64_MAX;
|
||||
end = (size_t)expand(a, end);
|
||||
tend = (int64_t)end;
|
||||
ret = expand(a, &tend);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
if (tend < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
end = (size_t)tend;
|
||||
if (end != start + filter->blocklength)
|
||||
return 0;
|
||||
|
||||
|
@ -32,9 +32,9 @@ DEFINE_TEST(test_read_format_rar_filter)
|
||||
struct archive_entry *ae;
|
||||
char *buff[12];
|
||||
const char signature[12] = {
|
||||
0xff, 0xd8, 0xff, 0xe0,
|
||||
0x00, 0x10, 0x4a, 0x46,
|
||||
0x49, 0x46, 0x00, 0x01,
|
||||
0x4d, 0x5a, 0x90, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
extract_reference_file(refname);
|
||||
@ -44,9 +44,9 @@ DEFINE_TEST(test_read_format_rar_filter)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
|
||||
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualString("013.jpg", archive_entry_pathname(ae));
|
||||
assertEqualString("bsdcat.exe", archive_entry_pathname(ae));
|
||||
assertA((int)archive_entry_mtime(ae));
|
||||
assertEqualInt(1215721, archive_entry_size(ae));
|
||||
assertEqualInt(204288, archive_entry_size(ae));
|
||||
assertA(12 == archive_read_data(a, buff, 12));
|
||||
assertEqualMem(buff, signature, 12);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1128,6 +1128,7 @@ DEFINE_TEST(test_read_format_zip_7z_deflate)
|
||||
const char *refname = "test_read_format_zip_7z_deflate.zip";
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
@ -1137,15 +1138,33 @@ DEFINE_TEST(test_read_format_zip_7z_deflate)
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, refname, 10240));
|
||||
//read first symlink
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
r = archive_read_next_header(a, &ae);
|
||||
if (archive_zlib_version() == NULL) {
|
||||
assertEqualInt(ARCHIVE_FAILED, r);
|
||||
assertEqualString(archive_error_string(a),
|
||||
"Unsupported ZIP compression method during decompression "
|
||||
"of link entry (8: deflation)");
|
||||
assert(archive_errno(a) != 0);
|
||||
} else {
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
assertEqualString("libxkbcommon-x11.so.0.0.0",
|
||||
archive_entry_symlink(ae));
|
||||
}
|
||||
assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
|
||||
assertEqualString("libxkbcommon-x11.so.0.0.0",
|
||||
archive_entry_symlink(ae));
|
||||
//read second symlink
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
r = archive_read_next_header(a, &ae);
|
||||
if (archive_zlib_version() == NULL) {
|
||||
assertEqualInt(ARCHIVE_FAILED, r);
|
||||
assertEqualString(archive_error_string(a),
|
||||
"Unsupported ZIP compression method during decompression "
|
||||
"of link entry (8: deflation)");
|
||||
assert(archive_errno(a) != 0);
|
||||
} else {
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
assertEqualString("libxkbcommon-x11.so.0.0.0",
|
||||
archive_entry_symlink(ae));
|
||||
}
|
||||
assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
|
||||
assertEqualString("libxkbcommon-x11.so.0.0.0",
|
||||
archive_entry_symlink(ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ test_winzip_aes(const char *refname, int need_libz)
|
||||
} else {
|
||||
assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
|
||||
assertEqualString(archive_error_string(a),
|
||||
"Unsupported ZIP compression method (deflation)");
|
||||
"Unsupported ZIP compression method (8: deflation)");
|
||||
assert(archive_errno(a) != 0);
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ DEFINE_TEST(test_read_format_zip_winzip_aes256_large)
|
||||
assertEqualInt(ARCHIVE_FAILED,
|
||||
archive_read_data(a, buff, sizeof(buff)));
|
||||
assertEqualString(archive_error_string(a),
|
||||
"Unsupported ZIP compression method (deflation)");
|
||||
"Unsupported ZIP compression method (8: deflation)");
|
||||
assert(archive_errno(a) != 0);
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ DEFINE_TEST(test_read_format_zip_winzip_aes256_large)
|
||||
assertEqualInt(ARCHIVE_FAILED,
|
||||
archive_read_data(a, buff, sizeof(buff)));
|
||||
assertEqualString(archive_error_string(a),
|
||||
"Unsupported ZIP compression method (deflation)");
|
||||
"Unsupported ZIP compression method (8: deflation)");
|
||||
assert(archive_errno(a) != 0);
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ DEFINE_TEST(test_read_format_zip_winzip_aes256_large)
|
||||
assertEqualInt(ARCHIVE_FAILED,
|
||||
archive_read_data(a, buff, sizeof(buff)));
|
||||
assertEqualString(archive_error_string(a),
|
||||
"Unsupported ZIP compression method (deflation)");
|
||||
"Unsupported ZIP compression method (8: deflation)");
|
||||
assert(archive_errno(a) != 0);
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ DEFINE_TEST(test_read_format_zip_winzip_aes256_large)
|
||||
assertEqualInt(ARCHIVE_FAILED,
|
||||
archive_read_data(a, buff, sizeof(buff)));
|
||||
assertEqualString(archive_error_string(a),
|
||||
"Unsupported ZIP compression method (deflation)");
|
||||
"Unsupported ZIP compression method (8: deflation)");
|
||||
assert(archive_errno(a) != 0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user