]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Guard against a number of theoretical buffer and integer
authorTim Kientzle <kientzle@gmail.com>
Tue, 20 May 2008 19:57:10 +0000 (15:57 -0400)
committerTim Kientzle <kientzle@gmail.com>
Tue, 20 May 2008 19:57:10 +0000 (15:57 -0400)
overflows.  As far as I can tell, none of these are
actually exploitable.

Thanks to David Remahl at Apple for pointing these out.
MFP4 after: 1 day

SVN-Revision: 77

libarchive/archive_read_support_format_ar.c
libarchive/archive_read_support_format_iso9660.c
libarchive/archive_read_support_format_tar.c
tar/util.c

index f6e4cc7e2abe4876655d9f216a12585693c72815..846b4ad94e575a914f26de9c4ed14f4e3c84e71f 100644 (file)
@@ -350,12 +350,16 @@ archive_read_format_ar_read_header(struct archive_read *a,
 
                /* Parse the size of the name, adjust the file size. */
                number = ar_atol10(h + AR_name_offset + 3, AR_name_size - 3);
-               if ((off_t)number > ar->entry_bytes_remaining) {
+               bsd_name_length = (size_t)number;
+               /* Guard against the filename + trailing NUL
+                * overflowing a size_t and against the filename size
+                * being larger than the entire entry. */
+               if (number > (uint64_t)(bsd_name_length + 1)
+                   || (uint64_t)bsd_name_length > ar->entry_bytes_remaining) {
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                            "Bad input file size");
                        return (ARCHIVE_FATAL);
                }
-               bsd_name_length = (size_t)number;
                ar->entry_bytes_remaining -= bsd_name_length;
                /* Adjust file size reported to client. */
                archive_entry_set_size(entry, ar->entry_bytes_remaining);
index 08d64ed78bf44f819cc22892e61f92c1a20953e4..c10870495c085f884711bd21a4b9fa4dd79a3e5c 100644 (file)
@@ -595,6 +595,9 @@ add_entry(struct iso9660 *iso9660, struct file_info *file)
                struct file_info **new_pending_files;
                int new_size = iso9660->pending_files_allocated * 2;
 
+               /* Overflow might keep us from growing the list. */
+               if (new_size <= iso9660->pending_files_allocated)
+                       __archive_errx(1, "Out of memory");
                if (new_size < 1024)
                        new_size = 1024;
                new_pending_files = (struct file_info **)malloc(new_size * sizeof(new_pending_files[0]));
index 147ec0b279525819c5e57319dd8d2ba293369d67..6d7f048a40d8989fc5fc212f9a5074a7a72ac947 100644 (file)
@@ -2303,7 +2303,7 @@ base64_decode(const char *s, size_t len, size_t *out_len)
 
        /* Allocate enough space to hold the entire output. */
        /* Note that we may not use all of this... */
-       out = (char *)malloc((len * 3 + 3) / 4);
+       out = (char *)malloc(len - len / 4 + 1);
        if (out == NULL) {
                *out_len = 0;
                return (NULL);
index 2ae430336e92212f6a8c1aa1ea9dd4dbbb92b48c..1d50dcd801052132227a043f6cea07387bda41ef 100644 (file)
@@ -178,7 +178,7 @@ yes(const char *fmt, ...)
        fprintf(stderr, " (y/N)? ");
        fflush(stderr);
 
-       l = read(2, buff, sizeof(buff));
+       l = read(2, buff, sizeof(buff) - 1);
        if (l <= 0)
                return (0);
        buff[l] = 0;
@@ -215,7 +215,7 @@ process_lines(struct bsdtar *bsdtar, const char *pathname,
 {
        FILE *f;
        char *buff, *buff_end, *line_start, *line_end, *p;
-       size_t buff_length, bytes_read, bytes_wanted;
+       size_t buff_length, new_buff_length, bytes_read, bytes_wanted;
        int separator;
        int ret;
 
@@ -262,7 +262,12 @@ process_lines(struct bsdtar *bsdtar, const char *pathname,
                        line_start = buff;
                } else {
                        /* Line is too big; enlarge the buffer. */
-                       p = realloc(buff, buff_length *= 2);
+                       new_buff_length = buff_length * 2;
+                       if (new_buff_length <= buff_length)
+                               bsdtar_errc(bsdtar, 1, ENOMEM,
+                                   "Line too long in %s", pathname);
+                       buff_length = new_buff_length;
+                       p = realloc(buff, buff_length);
                        if (p == NULL)
                                bsdtar_errc(bsdtar, 1, ENOMEM,
                                    "Line too long in %s", pathname);