Skip to content

Commit

Permalink
libarchive: merge from vendor branch
Browse files Browse the repository at this point in the history
Libarchive 3.7.4 + three fixes from master

Security fixes:
 CTSRD-CHERI#2135 rar: Fix OOB in rar e8 filter (CVE-2024-26256)
 CTSRD-CHERI#2145 zip: Fix out of boundary access
 CTSRD-CHERI#2148 rar: Fix OOB in rar delta filter
 CTSRD-CHERI#2149 rar: Fix OOB in rar audio filter

Important bugfixes:
 CTSRD-CHERI#2131 7zip: Limit amount of properties
 CTSRD-CHERI#2110 bsdtar: Fix error handling around strtol() usages
 CTSRD-CHERI#2116 passphrase: Never allow empty passwords
 CTSRD-CHERI#2124 rar: Fix "File CRC Error" when extracting specific rar4 archives
 CTSRD-CHERI#2123 xar: Avoid infinite link loop
 CTSRD-CHERI#2150 xar: Fix another infinite loop and expat error handling
 CTSRD-CHERI#2108 zip: Update AppleDouble support for directories
 CTSRD-CHERI#2071 zstd: Implement core detectiongit

PR:		278588 (exp-run)
MFC after:	1 day
  • Loading branch information
mmatuska authored and bsdjhb committed Aug 19, 2024
2 parents edfcf7d + 13d826f commit bd055f3
Show file tree
Hide file tree
Showing 35 changed files with 404 additions and 110 deletions.
2 changes: 2 additions & 0 deletions contrib/libarchive/NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Apr 26, 2024: libarchive 3.7.4 released

Apr 08, 2024: libarchive 3.7.3 released

Sep 12, 2023: libarchive 3.7.2 released
Expand Down
2 changes: 1 addition & 1 deletion contrib/libarchive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ questions we are asked about libarchive:
In case other thread calls the same function in parallel, it might
get interrupted by it and cause the executable to use umask=0 for the
remaining execution.
This will then lead to implicitely created directories to have 777
This will then lead to implicitly created directories to have 777
permissions without sticky bit.

* In particular, libarchive's modules to read or write a directory
Expand Down
16 changes: 11 additions & 5 deletions contrib/libarchive/cat/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,18 @@ bsdcat_getopt(struct bsdcat *bsdcat)
enum { state_start = 0, state_old_tar, state_next_word,
state_short, state_long };

const struct bsdcat_option *popt, *match = NULL, *match2 = NULL;
const char *p, *long_prefix = "--";
const struct bsdcat_option *popt, *match, *match2;
const char *p, *long_prefix;
size_t optlength;
int opt = '?';
int required = 0;
int opt;
int required;

again:
match = NULL;
match2 = NULL;
long_prefix = "--";
opt = '?';
required = 0;
bsdcat->argument = NULL;

/* First time through, initialize everything. */
Expand Down Expand Up @@ -172,7 +178,7 @@ bsdcat_getopt(struct bsdcat *bsdcat)
if (opt == '\0') {
/* End of this group; recurse to get next option. */
bsdcat->getopt_state = state_next_word;
return bsdcat_getopt(bsdcat);
goto again;
}

/* Does this option take an argument? */
Expand Down
16 changes: 11 additions & 5 deletions contrib/libarchive/cpio/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,18 @@ cpio_getopt(struct cpio *cpio)
static int state = state_start;
static char *opt_word;

const struct option *popt, *match = NULL, *match2 = NULL;
const char *p, *long_prefix = "--";
const struct option *popt, *match, *match2;
const char *p, *long_prefix;
size_t optlength;
int opt = '?';
int required = 0;
int opt;
int required;

again:
match = NULL;
match2 = NULL;
long_prefix = "--";
opt = '?';
required = 0;
cpio->argument = NULL;

/* First time through, initialize everything. */
Expand Down Expand Up @@ -169,7 +175,7 @@ cpio_getopt(struct cpio *cpio)
if (opt == '\0') {
/* End of this group; recurse to get next option. */
state = state_next_word;
return cpio_getopt(cpio);
goto again;
}

/* Does this option take an argument? */
Expand Down
6 changes: 3 additions & 3 deletions contrib/libarchive/libarchive/archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3007003
#define ARCHIVE_VERSION_NUMBER 3007004

#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
Expand Down Expand Up @@ -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.7.3"
#define ARCHIVE_VERSION_ONLY_STRING "3.7.4"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);

Expand Down Expand Up @@ -895,7 +895,7 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
const char *opts);

/*
* Set a encryption passphrase.
* Set an encryption passphrase.
*/
__LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
__LA_DECL int archive_write_set_passphrase_callback(struct archive *,
Expand Down
2 changes: 1 addition & 1 deletion contrib/libarchive/libarchive/archive_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED

/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3007003
#define ARCHIVE_VERSION_NUMBER 3007004

/*
* Note: archive_entry.h is for use outside of libarchive; the
Expand Down
2 changes: 1 addition & 1 deletion contrib/libarchive/libarchive/archive_entry_acl.3
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ Prefix each default ACL entry with the word
The mask and other ACLs don not contain a double colon.
.El
.Pp
The following flags are effecive only on NFSv4 ACL:
The following flags are effective only on NFSv4 ACL:
.Bl -tag -offset indent -compact -width ARCHIV
.It Dv ARCHIVE_ENTRY_ACL_STYLE_COMPACT
Do not output minus characters for unset permissions and flags in NFSv4 ACL
Expand Down
4 changes: 2 additions & 2 deletions contrib/libarchive/libarchive/archive_read_disk.3
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,11 @@ calls. If matched based on calls to
.Tn archive_match_time_excluded ,
or
.Tn archive_match_owner_excluded ,
then the callback function specified by the _excluded_func parameter will execute. This function will recieve data provided to the fourth parameter, void *_client_data.
then the callback function specified by the _excluded_func parameter will execute. This function will receive data provided to the fourth parameter, void *_client_data.
.It Fn archive_read_disk_set_metadata_filter_callback
Allows the caller to set a callback function during calls to
.Xr archive_read_header 3
to filter out metadata for each entry. The callback function recieves the
to filter out metadata for each entry. The callback function receives the
.Tn struct archive
object, void* custom filter data, and the
.Tn struct archive_entry .
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2037,6 +2037,8 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
if (parse_7zip_uint64(
a, &(f->coders[i].propertiesSize)) < 0)
return (-1);
if (UMAX_ENTRY < f->coders[i].propertiesSize)
return (-1);
if ((p = header_bytes(
a, (size_t)f->coders[i].propertiesSize)) == NULL)
return (-1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ archive_read_support_format_all(struct archive *a)
* increase the chance that a high bid from someone else will
* make it unnecessary for these to do anything at all.
*/
/* These three have potentially large look-ahead. */
/* These have potentially large look-ahead. */
archive_read_support_format_7zip(a);
archive_read_support_format_cab(a);
archive_read_support_format_rar(a);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
}
if (ar->strtab != NULL) {
archive_set_error(&a->archive, EINVAL,
"More than one string tables exist");
"More than one string table exists");
return (ARCHIVE_FATAL);
}

Expand Down Expand Up @@ -515,7 +515,7 @@ archive_read_format_ar_read_data(struct archive_read *a,
if (ar->entry_padding) {
if (skipped >= 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Truncated ar archive- failed consuming padding");
"Truncated ar archive - failed consuming padding");
}
return (ARCHIVE_FATAL);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1704,7 +1704,7 @@ archive_read_format_lha_cleanup(struct archive_read *a)
* example.
* 1. a symbolic-name is 'aaa/bb/cc'
* 2. a filename is 'xxx/bbb'
* then a archived pathname is 'xxx/bbb|aaa/bb/cc'
* then an archived pathname is 'xxx/bbb|aaa/bb/cc'
*/
static int
lha_parse_linkname(struct archive_wstring *linkname,
Expand Down Expand Up @@ -2400,7 +2400,7 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
return (100);
}

/* lzh_br_read_ahead() always try to fill the
/* lzh_br_read_ahead() always tries to fill the
* cache buffer up. In specific situation we
* are close to the end of the data, the cache
* buffer will not be full and thus we have to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ next_line(struct archive_read *a,
}

/*
* Compare characters with a mtree keyword.
* Returns the length of a mtree keyword if matched.
* Compare characters with an mtree keyword.
* Returns the length of an mtree keyword if matched.
* Returns 0 if not matched.
*/
static int
Expand Down Expand Up @@ -515,7 +515,7 @@ bid_keyword(const char *p, ssize_t len)

/*
* Test whether there is a set of mtree keywords.
* Returns the number of keyword.
* Returns the number of keywords.
* Returns -1 if we got incorrect sequence.
* This function expects a set of "<space characters>keyword=value".
* When "unset" is specified, expects a set of "<space characters>keyword".
Expand Down Expand Up @@ -760,7 +760,7 @@ detect_form(struct archive_read *a, int *is_form_d)
multiline = 1;
else {
/* We've got plenty of correct lines
* to assume that this file is a mtree
* to assume that this file is an mtree
* format. */
if (++entry_cnt >= MAX_BID_ENTRY)
break;
Expand Down
30 changes: 29 additions & 1 deletion contrib/libarchive/libarchive/archive_read_support_format_rar.c
Original file line number Diff line number Diff line change
Expand Up @@ -2176,6 +2176,19 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
{
start = rar->offset;
end = start + rar->dictionary_size;

/* We don't want to overflow the window and overwrite data that we write
* at 'start'. Therefore, reduce the end length by the maximum match size,
* which is 260 bytes. You can compute this maximum by looking at the
* definition of 'expand', in particular when 'symbol >= 271'. */
/* NOTE: It's possible for 'dictionary_size' to be less than this 260
* value, however that will only be the case when 'unp_size' is small,
* which should only happen when the entry size is small and there's no
* risk of overflowing the buffer */
if (rar->dictionary_size > 260) {
end -= 260;
}

if (rar->filters.filterstart < end) {
end = rar->filters.filterstart;
}
Expand Down Expand Up @@ -3599,7 +3612,15 @@ execute_filter_delta(struct rar_filter *filter, struct rar_virtual_machine *vm)
{
uint8_t lastbyte = 0;
for (idx = i; idx < length; idx += numchannels)
{
/*
* The src block should not overlap with the dst block.
* If so it would be better to consider this archive is broken.
*/
if (src >= dst)
return 0;
lastbyte = dst[idx] = lastbyte - *src++;
}
}

filter->filteredblockaddress = length;
Expand All @@ -3615,7 +3636,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
uint32_t filesize = 0x1000000;
uint32_t i;

if (length > PROGRAM_WORK_SIZE || length < 4)
if (length > PROGRAM_WORK_SIZE || length <= 4)
return 0;

for (i = 0; i <= length - 5; i++)
Expand Down Expand Up @@ -3701,6 +3722,13 @@ execute_filter_audio(struct rar_filter *filter, struct rar_virtual_machine *vm)
memset(&state, 0, sizeof(state));
for (j = i; j < length; j += numchannels)
{
/*
* The src block should not overlap with the dst block.
* If so it would be better to consider this archive is broken.
*/
if (src >= dst)
return 0;

int8_t delta = (int8_t)*src++;
uint8_t predbyte, byte;
int prederror;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
const char *buf;
ssize_t nrd;
const char *eoh;
char *tmp;
/* for the file name, saves some strndup()'ing */
warc_string_t fnam;
/* warc record type, not that we really use it a lot */
Expand Down Expand Up @@ -321,7 +322,14 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
* malloc()+free() roundtrip */
if (fnam.len + 1U > w->pool.len) {
w->pool.len = ((fnam.len + 64U) / 64U) * 64U;
w->pool.str = realloc(w->pool.str, w->pool.len);
tmp = realloc(w->pool.str, w->pool.len);
if (tmp == NULL) {
archive_set_error(
&a->archive, ENOMEM,
"Out of memory");
return (ARCHIVE_FATAL);
}
w->pool.str = tmp;
}
memcpy(w->pool.str, fnam.str, fnam.len);
w->pool.str[fnam.len] = '\0';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2055,6 +2055,12 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
attr = attr->next) {
if (strcmp(attr->name, "link") != 0)
continue;
if (xar->file->hdnext != NULL || xar->file->link != 0 ||
xar->file == xar->hdlink_orgs) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"File with multiple link attributes");
return (ARCHIVE_FATAL);
}
if (strcmp(attr->value, "original") == 0) {
xar->file->hdnext = xar->hdlink_orgs;
xar->hdlink_orgs = xar->file;
Expand Down Expand Up @@ -3251,6 +3257,9 @@ expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
struct xmlattr_list list;
int r;

if (ud->state != ARCHIVE_OK)
return;

r = expat_xmlattr_setup(a, &list, atts);
if (r == ARCHIVE_OK)
r = xml_start(a, (const char *)name, &list);
Expand Down
15 changes: 13 additions & 2 deletions contrib/libarchive/libarchive/archive_read_support_format_zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ check_authentication_code(struct archive_read *a, const void *_p)
* [CRC32] [compressed low] [compressed high] [uncompressed low] [uncompressed high] [other PK marker]
* ```
* Since the 32-bit and 64-bit compressed sizes both match, the
* actualy size must fit in 32 bits, which implies the high-order
* actual size must fit in 32 bits, which implies the high-order
* word of the compressed size is zero. So we know the uncompressed
* low word is zero, which again implies that if we accept the shorter
* format, there will not be a valid PK marker following it.
Expand Down Expand Up @@ -4083,14 +4083,25 @@ slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
} else {
/* Generate resource fork name to find its
* resource file at zip->tree_rsrc. */

/* If this is an entry ending with slash,
* make the resource for name slash-less
* as the actual resource fork doesn't end with '/'.
*/
size_t tmp_length = filename_length;
if (tmp_length > 0 && name[tmp_length - 1] == '/') {
tmp_length--;
r = rsrc_basename(name, tmp_length);
}

archive_strcpy(&(zip_entry->rsrcname),
"__MACOSX/");
archive_strncat(&(zip_entry->rsrcname),
name, r - name);
archive_strcat(&(zip_entry->rsrcname), "._");
archive_strncat(&(zip_entry->rsrcname),
name + (r - name),
filename_length - (r - name));
tmp_length - (r - name));
/* Register an entry to RB tree to sort it by
* file offset. */
__archive_rb_tree_insert_node(&zip->tree,
Expand Down
3 changes: 1 addition & 2 deletions contrib/libarchive/libarchive/archive_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,9 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
#endif
fd = -1;
ws = NULL;
archive_string_init(&temp_name);

if (template == NULL) {
archive_string_init(&temp_name);

/* Get a temporary directory. */
if (tmpdir == NULL) {
size_t l;
Expand Down
Loading

0 comments on commit bd055f3

Please sign in to comment.