doc/website/static/security/patches/SA-07:05/libarchive.patch
Sergio Carlavilla Delgado 989d921f5d Migrate doc to Hugo/AsciiDoctor
I'm very pleased to announce the release of
our new website and documentation using
the new toolchain with Hugo and AsciiDoctor.

To get more information about the new toolchain
please read the FreeBSD Documentation Project Primer[1],
Hugo docs[2] and AsciiDoctor docs[3].

Acknowledgment:
Benedict Reuschling <bcr@>
Glen Barber <gjb@>
Hiroki Sato <hrs@>
Li-Wen Hsu <lwhsu@>
Sean Chittenden <seanc@>
The FreeBSD Foundation

[1] https://docs.FreeBSD.org/en/books/fdp-primer/
[2] https://gohugo.io/documentation/
[3] https://docs.asciidoctor.org/home/

Approved by:    doceng, core
2021-01-26 00:31:29 +01:00

231 lines
6.5 KiB
Diff

Index: lib/libarchive/archive_read_support_format_tar.c
===================================================================
RCS file: /home/ncvs/src/lib/libarchive/archive_read_support_format_tar.c,v
retrieving revision 1.32.2.2
diff -u -I__FBSDID -I$FreeBSD -r1.32.2.2 archive_read_support_format_tar.c
--- lib/libarchive/archive_read_support_format_tar.c 5 Sep 2006 05:23:51 -0000 1.32.2.2
+++ lib/libarchive/archive_read_support_format_tar.c 10 Jul 2007 09:10:24 -0000
@@ -670,7 +670,13 @@
}
}
--tar->header_recursion_depth;
- return (err);
+ /* We return warnings or success as-is. Anything else is fatal. */
+ if (err == ARCHIVE_WARN || err == ARCHIVE_OK)
+ return (err);
+ if (err == ARCHIVE_EOF)
+ /* EOF when recursively reading a header is bad. */
+ archive_set_error(a, EINVAL, "Damaged tar archive");
+ return (ARCHIVE_FATAL);
}
/*
@@ -741,32 +747,55 @@
header_Solaris_ACL(struct archive *a, struct tar *tar,
struct archive_entry *entry, struct stat *st, const void *h)
{
- int err, err2;
- char *p;
+ const struct archive_entry_header_ustar *header;
+ size_t size;
+ int err;
+ char *acl, *p;
wchar_t *wp;
+ /*
+ * read_body_to_string adds a NUL terminator, but we need a little
+ * more to make sure that we don't overrun acl_text later.
+ */
+ header = (const struct archive_entry_header_ustar *)h;
+ size = tar_atol(header->size, sizeof(header->size));
err = read_body_to_string(a, tar, &(tar->acl_text), h);
- err2 = tar_read_header(a, tar, entry, st);
- err = err_combine(err, err2);
-
- /* XXX Ensure p doesn't overrun acl_text */
+ if (err != ARCHIVE_OK)
+ return (err);
+ err = tar_read_header(a, tar, entry, st);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
/* Skip leading octal number. */
/* XXX TODO: Parse the octal number and sanity-check it. */
- p = tar->acl_text.s;
- while (*p != '\0')
+ p = acl = tar->acl_text.s;
+ while (*p != '\0' && p < acl + size)
p++;
p++;
- wp = malloc((strlen(p) + 1) * sizeof(wchar_t));
- if (wp != NULL) {
- utf8_decode(wp, p, strlen(p));
- err2 = __archive_entry_acl_parse_w(entry, wp,
- ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
- err = err_combine(err, err2);
- free(wp);
+ if (p >= acl + size) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Malformed Solaris ACL attribute");
+ return(ARCHIVE_WARN);
}
+ /* Skip leading octal number. */
+ size -= (p - acl);
+ acl = p;
+
+ while (*p != '\0' && p < acl + size)
+ p++;
+
+ wp = malloc((p - acl + 1) * sizeof(wchar_t));
+ if (wp == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate work buffer for ACL parsing");
+ return (ARCHIVE_FATAL);
+ }
+ utf8_decode(wp, acl, p - acl);
+ err = __archive_entry_acl_parse_w(entry, wp,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ free(wp);
return (err);
}
@@ -777,15 +806,17 @@
header_longlink(struct archive *a, struct tar *tar,
struct archive_entry *entry, struct stat *st, const void *h)
{
- int err, err2;
+ int err;
err = read_body_to_string(a, tar, &(tar->longlink), h);
- err2 = tar_read_header(a, tar, entry, st);
- if (err == ARCHIVE_OK && err2 == ARCHIVE_OK) {
- /* Set symlink if symlink already set, else hardlink. */
- archive_entry_set_link(entry, tar->longlink.s);
- }
- return (err_combine(err, err2));
+ if (err != ARCHIVE_OK)
+ return (err);
+ err = tar_read_header(a, tar, entry, st);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
+ /* Set symlink if symlink already set, else hardlink. */
+ archive_entry_set_link(entry, tar->longlink.s);
+ return (ARCHIVE_OK);
}
/*
@@ -795,14 +826,17 @@
header_longname(struct archive *a, struct tar *tar,
struct archive_entry *entry, struct stat *st, const void *h)
{
- int err, err2;
+ int err;
err = read_body_to_string(a, tar, &(tar->longname), h);
+ if (err != ARCHIVE_OK)
+ return (err);
/* Read and parse "real" header, then override name. */
- err2 = tar_read_header(a, tar, entry, st);
- if (err == ARCHIVE_OK && err2 == ARCHIVE_OK)
- archive_entry_set_pathname(entry, tar->longname.s);
- return (err_combine(err, err2));
+ err = tar_read_header(a, tar, entry, st);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
+ archive_entry_set_pathname(entry, tar->longname.s);
+ return (ARCHIVE_OK);
}
@@ -836,12 +870,20 @@
header = h;
size = tar_atol(header->size, sizeof(header->size));
+ /* Sanity check. */
+ if ((size > 1048576) || (size < 0)) {
+ archive_set_error(a, EINVAL, "Special header too large");
+ return (ARCHIVE_FATAL);
+ }
+
/* Read the body into the string. */
archive_string_ensure(as, size+1);
padded_size = (size + 511) & ~ 511;
dest = as->s;
while (padded_size > 0) {
bytes_read = (a->compression_read_ahead)(a, &src, padded_size);
+ if (bytes_read == 0)
+ return (ARCHIVE_EOF);
if (bytes_read < 0)
return (ARCHIVE_FATAL);
if (bytes_read > padded_size)
@@ -1027,11 +1069,13 @@
header_pax_global(struct archive *a, struct tar *tar,
struct archive_entry *entry, struct stat *st, const void *h)
{
- int err, err2;
+ int err;
err = read_body_to_string(a, tar, &(tar->pax_global), h);
- err2 = tar_read_header(a, tar, entry, st);
- return (err_combine(err, err2));
+ if (err != ARCHIVE_OK)
+ return (err);
+ err = tar_read_header(a, tar, entry, st);
+ return (err);
}
static int
@@ -1040,10 +1084,14 @@
{
int err, err2;
- read_body_to_string(a, tar, &(tar->pax_header), h);
+ err = read_body_to_string(a, tar, &(tar->pax_header), h);
+ if (err != ARCHIVE_OK)
+ return (err);
/* Parse the next header. */
err = tar_read_header(a, tar, entry, st);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
/*
* TODO: Parse global/default options into 'entry' struct here
@@ -1141,8 +1189,11 @@
l--;
break;
}
- if (*p < '0' || *p > '9')
- return (-1);
+ if (*p < '0' || *p > '9') {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Ignoring malformed pax extended attributes");
+ return (ARCHIVE_WARN);
+ }
line_length *= 10;
line_length += *p - '0';
if (line_length > 999999) {
@@ -1154,8 +1205,19 @@
l--;
}
- if (line_length > attr_length)
- return (0);
+ /*
+ * Parsed length must be no bigger than available data,
+ * at least 1, and the last character of the line must
+ * be '\n'.
+ */
+ if (line_length > attr_length
+ || line_length < 1
+ || attr[line_length - 1] != '\n')
+ {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Ignoring malformed pax extended attribute");
+ return (ARCHIVE_WARN);
+ }
/* Ensure pax_entry buffer is big enough. */
if (tar->pax_entry_length <= line_length) {