pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/archivers/libarchive Fix for FreeBSD-SA-07:05.libarchi...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/76b92aaa6825
branches:  trunk
changeset: 530881:76b92aaa6825
user:      lkundrak <lkundrak%pkgsrc.org@localhost>
date:      Fri Jul 13 09:26:31 2007 +0000

description:
Fix for FreeBSD-SA-07:05.libarchive CVE-2007-3641, CVE-2007-3644 and
CVE-2007-3645.  PKGREVISION bump.

diffstat:

 archivers/libarchive/Makefile         |    3 +-
 archivers/libarchive/distinfo         |    3 +-
 archivers/libarchive/patches/patch-ad |  230 ++++++++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+), 2 deletions(-)

diffs (260 lines):

diff -r 552e3724ee95 -r 76b92aaa6825 archivers/libarchive/Makefile
--- a/archivers/libarchive/Makefile     Fri Jul 13 09:25:52 2007 +0000
+++ b/archivers/libarchive/Makefile     Fri Jul 13 09:26:31 2007 +0000
@@ -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 -r 552e3724ee95 -r 76b92aaa6825 archivers/libarchive/distinfo
--- a/archivers/libarchive/distinfo     Fri Jul 13 09:25:52 2007 +0000
+++ b/archivers/libarchive/distinfo     Fri Jul 13 09:26:31 2007 +0000
@@ -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 -r 552e3724ee95 -r 76b92aaa6825 archivers/libarchive/patches/patch-ad
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/archivers/libarchive/patches/patch-ad     Fri Jul 13 09:26:31 2007 +0000
@@ -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) {



Home | Main Index | Thread Index | Old Index