diff options
author | lkundrak <lkundrak@pkgsrc.org> | 2007-07-13 09:26:31 +0000 |
---|---|---|
committer | lkundrak <lkundrak@pkgsrc.org> | 2007-07-13 09:26:31 +0000 |
commit | 439c9678a868914b629e763ba2dadd32ab78100e (patch) | |
tree | 7474142a3770ab05568b3fe07a7b581b4c91c9d6 /archivers | |
parent | 440b684548bc27ca74d32104ab982d0834ca43ac (diff) | |
download | pkgsrc-439c9678a868914b629e763ba2dadd32ab78100e.tar.gz |
Fix for FreeBSD-SA-07:05.libarchive CVE-2007-3641, CVE-2007-3644 and
CVE-2007-3645. PKGREVISION bump.
Diffstat (limited to 'archivers')
-rw-r--r-- | archivers/libarchive/Makefile | 3 | ||||
-rw-r--r-- | archivers/libarchive/distinfo | 3 | ||||
-rw-r--r-- | archivers/libarchive/patches/patch-ad | 230 |
3 files changed, 234 insertions, 2 deletions
diff --git a/archivers/libarchive/Makefile b/archivers/libarchive/Makefile index 3aaf343a49b..c77f882fef9 100644 --- a/archivers/libarchive/Makefile +++ b/archivers/libarchive/Makefile @@ -1,7 +1,8 @@ -# $NetBSD: Makefile,v 1.16 2006/11/14 13:50:13 joerg Exp $ +# $NetBSD: Makefile,v 1.17 2007/07/13 09:26:31 lkundrak Exp $ # DISTNAME= libarchive-1.3.1 +PKGREVISION= 1 CATEGORIES= archivers MASTER_SITES= http://people.freebsd.org/~kientzle/libarchive/src/ diff --git a/archivers/libarchive/distinfo b/archivers/libarchive/distinfo index d785aed7de3..e3a2deb6b23 100644 --- a/archivers/libarchive/distinfo +++ b/archivers/libarchive/distinfo @@ -1,7 +1,8 @@ -$NetBSD: distinfo,v 1.13 2006/11/10 00:29:44 adrianp Exp $ +$NetBSD: distinfo,v 1.14 2007/07/13 09:26:31 lkundrak Exp $ SHA1 (libarchive-1.3.1.tar.gz) = aed6eda15b012adbb88af0f0d76887920ffe7bbf RMD160 (libarchive-1.3.1.tar.gz) = e518f802d9a50afcfede6dd7cbb4f42b2cbe12a1 Size (libarchive-1.3.1.tar.gz) = 901173 bytes SHA1 (patch-ab) = 5e92405b0898123d8240f332475d13abe85f8ad3 SHA1 (patch-ac) = 5775e26d19ace2b94c870c0e8de8e6efbe4b5c63 +SHA1 (patch-ad) = ea7a7ae72ca85589830aefae6e6e4f9f4ba45c7a diff --git a/archivers/libarchive/patches/patch-ad b/archivers/libarchive/patches/patch-ad new file mode 100644 index 00000000000..ef3080bb4dd --- /dev/null +++ b/archivers/libarchive/patches/patch-ad @@ -0,0 +1,230 @@ +$NetBSD: patch-ad,v 1.1 2007/07/13 09:26:32 lkundrak Exp $ + +Fix for CVE-2007-3641, CVE-2007-3644 and CVE-2007-3645 from FreeBSD-SA-07:05.libarchive + +--- libarchive/archive_read_support_format_tar.c.orig 2006-09-05 08:00:48.000000000 +0200 ++++ libarchive/archive_read_support_format_tar.c 2007-07-13 11:35:48.000000000 +0200 +@@ -670,7 +670,13 @@ tar_read_header(struct archive *a, struc + } + } + --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 @@ static int + 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 @@ static int + 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 @@ static int + 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 @@ read_body_to_string(struct archive *a, s + 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 @@ static int + 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 @@ header_pax_extensions(struct archive *a, + { + 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 @@ pax_header(struct archive *a, struct tar + 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 @@ pax_header(struct archive *a, struct tar + 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) { |