aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2018-11-24 01:15:08 +0000
committerMartin Matuska <mm@FreeBSD.org>2018-11-24 01:15:08 +0000
commitfd2a102f7ba73f37fbac1c994086b23f438cbf13 (patch)
tree839a0814bd5fe79181ad1d0544f840fee2b9968b
parenta26007e8d35293595dadaee72d00911741d111ed (diff)
downloadsrc-fd2a102f7ba73f37fbac1c994086b23f438cbf13.tar.gz
src-fd2a102f7ba73f37fbac1c994086b23f438cbf13.zip
Update vendor/libarchive/dist to git 0e416f2fe757ad6841dbb3386a17d88b5c9f5533
Relevant vendor changes: PR #1080: Spelling fixes PR #1084: RAR5 reader bugfixes PR #1091: fix use-after-free in delayed newc link processing PR #1092: Fix a few obvious resource leaks and strcpy() misuses
Notes
Notes: svn path=/vendor/libarchive/dist/; revision=340865
-rw-r--r--build/cmake/config.h.in6
-rw-r--r--cpio/cpio.c4
-rw-r--r--libarchive/archive_acl.c8
-rw-r--r--libarchive/archive_read_support_format_rar5.c52
-rw-r--r--libarchive/archive_windows.c3
-rw-r--r--libarchive/archive_write_set_format_iso9660.c4
-rw-r--r--libarchive/archive_write_set_format_mtree.c4
-rw-r--r--libarchive/archive_write_set_format_pax.c6
-rw-r--r--libarchive/archive_write_set_format_xar.c8
-rw-r--r--libarchive/test/test_fuzz.c2
-rw-r--r--libarchive/test/test_read_format_rar5.c41
-rw-r--r--libarchive/test/test_write_disk_perms.c2
-rw-r--r--tar/write.c12
13 files changed, 112 insertions, 40 deletions
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index 04f938d3f7f3..aed77f9a81c9 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -680,6 +680,12 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `bz2' library (-lbz2). */
#cmakedefine HAVE_LIBBZ2 1
+/* Define to 1 if you have the `b2' library (-lb2). */
+#cmakedefine HAVE_LIBB2 1
+
+/* Define to 1 if you have the <blake2.h> header file. */
+#cmakedefine HAVE_BLAKE2_H 1
+
/* Define to 1 if you have the `charset' library (-lcharset). */
#cmakedefine HAVE_LIBCHARSET 1
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 9dddf417a5a5..4fd394dea5f1 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -755,8 +755,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 9941d2f6fdb2..6ce7ab66093a 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_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c
index a4479f5a4a7b..7681c9486147 100644
--- a/libarchive/archive_read_support_format_rar5.c
+++ b/libarchive/archive_read_support_format_rar5.c
@@ -88,6 +88,7 @@ struct file_header {
uint8_t solid : 1; /* Is this a solid stream? */
uint8_t service : 1; /* Is this file a service data? */
+ uint8_t eof : 1; /* Did we finish unpacking the file? */
/* Optional time fields. */
uint64_t e_mtime;
@@ -176,7 +177,7 @@ struct comp_state {
decompression. */
uint8_t* filtered_buf; /* Buffer used when applying filters. */
const uint8_t* block_buf; /* Buffer used when merging blocks. */
- size_t window_mask; /* Convinience field; window_size - 1. */
+ size_t window_mask; /* Convenience field; window_size - 1. */
int64_t write_ptr; /* This amount of data has been unpacked in
the window buffer. */
int64_t last_write_ptr; /* This amount of data has been stored in
@@ -279,7 +280,7 @@ struct rar5 {
int skip_mode;
/* An offset to QuickOpen list. This is not supported by this unpacker,
- * becuase we're focusing on streaming interface. QuickOpen is designed
+ * because we're focusing on streaming interface. QuickOpen is designed
* to make things quicker for non-stream interfaces, so it's not our
* use case. */
uint64_t qlist_offset;
@@ -387,7 +388,7 @@ static void cdeque_pop_front_fast(struct cdeque* d, void** value) {
d->size--;
}
-/* Pops a front element of this cicrular deque object and returns its value.
+/* Pops a front element of this circular deque object and returns its value.
* This function performs bounds checking. */
static int cdeque_pop_front(struct cdeque* d, void** value) {
if(!d || !value)
@@ -400,17 +401,17 @@ static int cdeque_pop_front(struct cdeque* d, void** value) {
return CDE_OK;
}
-/* Convinience function to cast filter_info** to void **. */
+/* Convenience function to cast filter_info** to void **. */
static void** cdeque_filter_p(struct filter_info** f) {
return (void**) (size_t) f;
}
-/* Convinience function to cast filter_info* to void *. */
+/* Convenience function to cast filter_info* to void *. */
static void* cdeque_filter(struct filter_info* f) {
return (void**) (size_t) f;
}
-/* Destroys this circular deque object. Dellocates the memory of the collection
+/* Destroys this circular deque object. Deallocates the memory of the collection
* buffer, but doesn't deallocate the memory of any pointer passed to this
* deque as a value. */
static void cdeque_free(struct cdeque* d) {
@@ -434,7 +435,7 @@ static inline struct rar5* get_context(struct archive_read* a) {
// TODO: make sure these functions return a little endian number
-/* Convinience functions used by filter implementations. */
+/* Convenience functions used by filter implementations. */
static uint32_t read_filter_data(struct rar5* rar, uint32_t offset) {
uint32_t* dptr = (uint32_t*) &rar->cstate.window_buf[offset];
@@ -672,7 +673,7 @@ static void push_data(struct archive_read* a, struct rar5* rar,
}
}
-/* Convinience function that submits the data to the user. It uses the
+/* Convenience function that submits the data to the user. It uses the
* unpack window buffer as a source location. */
static void push_window_data(struct archive_read* a, struct rar5* rar,
int64_t idx_begin, int64_t idx_end)
@@ -753,7 +754,7 @@ static void free_filters(struct rar5* rar) {
/* Free any remaining filters. All filters should be naturally consumed by
* the unpacking function, so remaining filters after unpacking normally
- * mean that unpacking wasn't successfull. But still of course we shouldn't
+ * mean that unpacking wasn't successful. But still of course we shouldn't
* leak memory in such case. */
/* cdeque_size() is a fast operation, so we can use it as a loop
@@ -885,7 +886,7 @@ static int read_var(struct archive_read* a, uint64_t* pvalue,
* it will not have the possibility to advance the file
* pointer, because it will not know how many bytes it needs
* to consume. This is why we handle such situation here
- * autmatically. */
+ * automatically. */
if(ARCHIVE_OK != consume(a, 1 + i)) {
return 0;
}
@@ -918,7 +919,7 @@ static int read_var_sized(struct archive_read* a, size_t* pvalue,
size_t* pvalue_len)
{
uint64_t v;
- uint64_t v_size;
+ uint64_t v_size = 0;
const int ret = pvalue_len
? read_var(a, &v, &v_size)
@@ -1218,7 +1219,7 @@ static int process_head_file_extra(struct archive_read* a,
ssize_t extra_data_size)
{
size_t extra_field_size;
- size_t extra_field_id;
+ size_t extra_field_id = 0;
int ret = ARCHIVE_FATAL;
size_t var_size;
@@ -1288,7 +1289,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
size_t host_os = 0;
size_t name_size = 0;
uint64_t unpacked_size;
- uint32_t mtime = 0, crc;
+ uint32_t mtime = 0, crc = 0;
int c_method = 0, c_version = 0, is_dir;
char name_utf8_buf[2048 * 4];
const uint8_t* p;
@@ -1522,7 +1523,7 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
enum MAIN_FLAGS {
VOLUME = 0x0001, /* multi-volume archive */
- VOLUME_NUMBER = 0x0002, /* volume number, first vol doesnt have it */
+ VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't have it */
SOLID = 0x0004, /* solid archive */
PROTECT = 0x0008, /* contains Recovery info */
LOCK = 0x0010, /* readonly flag, not used */
@@ -1647,7 +1648,7 @@ static int process_base_block(struct archive_read* a,
{
struct rar5* rar = get_context(a);
uint32_t hdr_crc, computed_crc;
- size_t raw_hdr_size, hdr_size_len, hdr_size;
+ size_t raw_hdr_size = 0, hdr_size_len, hdr_size;
size_t header_id = 0;
size_t header_flags = 0;
const uint8_t* p;
@@ -2211,7 +2212,7 @@ static int parse_block_header(struct archive_read* a, const uint8_t* p,
return ARCHIVE_OK;
}
-/* Convinience function used during filter processing. */
+/* Convenience function used during filter processing. */
static int parse_filter_data(struct rar5* rar, const uint8_t* p,
uint32_t* filter_data)
{
@@ -2685,6 +2686,12 @@ static int merge_block(struct archive_read* a, ssize_t block_size,
cur_block_size =
rar5_min(rar->file.bytes_remaining, block_size - partial_offset);
+ if(cur_block_size == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Encountered block size == 0 during block merge");
+ return ARCHIVE_FATAL;
+ }
+
if(!read_ahead(a, cur_block_size, &lp))
return ARCHIVE_EOF;
@@ -3116,6 +3123,9 @@ static int do_unstore_file(struct archive_read* a,
}
size_t to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024);
+ if(to_read == 0) {
+ return ARCHIVE_EOF;
+ }
if(!read_ahead(a, to_read, &p)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "I/O error "
@@ -3186,7 +3196,7 @@ static int verify_checksums(struct archive_read* a) {
* data and discarding the result). */
if(!rar->skip_mode) {
- /* Always check checkums if we're not in skip mode */
+ /* Always check checksums if we're not in skip mode */
verify_crc = 1;
} else {
/* We can override the logic above with a compile-time option
@@ -3283,8 +3293,13 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
}
ret = use_data(rar, buff, size, offset);
- if(ret == ARCHIVE_OK)
+ if(ret == ARCHIVE_OK) {
return ret;
+ }
+
+ if(rar->file.eof == 1) {
+ return ARCHIVE_EOF;
+ }
ret = do_unpack(a, rar, buff, size, offset);
if(ret != ARCHIVE_OK) {
@@ -3301,6 +3316,7 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
* value in the last `archive_read_data` call to signal an error
* to the user. */
+ rar->file.eof = 1;
return verify_global_checksums(a);
}
diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c
index 6ff8749ae74f..624e270095d6 100644
--- a/libarchive/archive_windows.c
+++ b/libarchive/archive_windows.c
@@ -445,7 +445,8 @@ fileTimeToUTC(const FILETIME *filetime, time_t *t, long *ns)
* Windows' stat() does not accept the path added "\\?\" especially "?"
* character.
* It means we cannot access the long name path longer than MAX_PATH.
- * So I've implemented simular Windows' stat() to access the long name path.
+ * So I've implemented a function similar to Windows' stat() to access the
+ * long name path.
* And I've added some feature.
* 1. set st_ino by nFileIndexHigh and nFileIndexLow of
* BY_HANDLE_FILE_INFORMATION.
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
index c0ca435d15c7..badc88bad0c9 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 493d4735661f..0f2431e6abe0 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 6f78c48bd651..5a4c45a11e02 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 495f0d441e5c..36d4a615e2ae 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)
+ != ARCHIVE_OK) {
+ free(heap);
return (ARCHIVE_FATAL);
+ }
if (r == ARCHIVE_OK) {
xar->stream.next_out = xar->wbuff;
xar->stream.avail_out = sizeof(xar->wbuff);
diff --git a/libarchive/test/test_fuzz.c b/libarchive/test/test_fuzz.c
index 42351450b265..2025834ca424 100644
--- a/libarchive/test/test_fuzz.c
+++ b/libarchive/test/test_fuzz.c
@@ -433,7 +433,7 @@ DEFINE_TEST(test_fuzz_tar)
{0, fileset9}, /* Exercise lzo decompressor. */
#endif
#if HAVE_ZSTD_H && HAVE_LIBZSTD
- {0, fileset10}, /* Excercise zstd decompressor. */
+ {0, fileset10}, /* Exercise zstd decompressor. */
#endif
{1, NULL}
};
diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c
index 2196123ddbc5..6c570f1c6643 100644
--- a/libarchive/test/test_read_format_rar5.c
+++ b/libarchive/test/test_read_format_rar5.c
@@ -726,3 +726,44 @@ DEFINE_TEST(test_read_format_rar5_extract_win32)
assertA(0 == extract_one(a, ae, 0x36A448FF));
EPILOGUE();
}
+
+DEFINE_TEST(test_read_format_rar5_block_by_block)
+{
+ /* This test uses strange buffer sizes intentionally. */
+
+ struct archive_entry *ae;
+ struct archive *a;
+ uint8_t buf[173];
+ int bytes_read;
+ uint32_t computed_crc = 0;
+
+ extract_reference_file("test_read_format_rar5_compressed.rar");
+ 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, "test_read_format_rar5_compressed.rar", 130));
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.bin", archive_entry_pathname(ae));
+ assertEqualInt(1200, archive_entry_size(ae));
+
+ /* File size is 1200 bytes, we're reading it using a buffer of 173 bytes.
+ * Libarchive is configured to use a buffer of 130 bytes. */
+
+ while(1) {
+ /* archive_read_data should return one of:
+ * a) 0, if there is no more data to be read,
+ * b) negative value, if there was an error,
+ * c) positive value, meaning how many bytes were read.
+ */
+
+ bytes_read = archive_read_data(a, buf, sizeof(buf));
+ assertA(bytes_read >= 0);
+ if(bytes_read <= 0)
+ break;
+
+ computed_crc = crc32(computed_crc, buf, bytes_read);
+ }
+
+ assertEqualInt(computed_crc, 0x7CCA70CD);
+ EPILOGUE();
+}
diff --git a/libarchive/test/test_write_disk_perms.c b/libarchive/test/test_write_disk_perms.c
index 8205d6abc59a..81f8b1209ce1 100644
--- a/libarchive/test/test_write_disk_perms.c
+++ b/libarchive/test/test_write_disk_perms.c
@@ -203,7 +203,7 @@ DEFINE_TEST(test_write_disk_perms)
failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode);
assertEqualInt(st.st_mode & 0777, 0744);
- /* For dir, the owner should get left when not overwritting. */
+ /* For dir, the owner should get left when not overwriting. */
assertMakeDir("dir_owner", 0744);
if (getuid() == 0) {
diff --git a/tar/write.c b/tar/write.c
index e15cc06ccfc4..09c44a3e747b 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;
}
/*
@@ -557,15 +556,14 @@ 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_entry_free(entry);
- continue;
+ archive_read_close(disk);
+ 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);
}