]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Issue 412: Be more careful about symlink length before trying to read it
authorTim Kientzle <kientzle@acm.org>
Sat, 21 Feb 2015 05:36:06 +0000 (21:36 -0800)
committerTim Kientzle <kientzle@acm.org>
Sat, 21 Feb 2015 05:36:06 +0000 (21:36 -0800)
libarchive/archive_read_support_format_zip.c

index bac07c171f55762b924c51524faca988aa97a98a..19dd333eab0594f1499ad7df0cc85374170d5455 100644 (file)
@@ -906,7 +906,15 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
        archive_entry_set_atime(entry, zip_entry->atime, 0);
 
        if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
-               size_t linkname_length = zip_entry->compressed_size;
+               size_t linkname_length;
+
+               if (zip_entry->compressed_size > 64 * 1024) {
+                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                           "Zip file with oversized link entry");
+                       return ARCHIVE_FATAL;
+               }
+
+               linkname_length = (size_t)zip_entry->compressed_size;
 
                archive_entry_set_size(entry, 0);
                p = __archive_read_ahead(a, linkname_length, NULL);
@@ -915,11 +923,6 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
                            "Truncated Zip file");
                        return ARCHIVE_FATAL;
                }
-               if (__archive_read_consume(a, linkname_length) < 0) {
-                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-                           "Read error skipping symlink target name");
-                       return ARCHIVE_FATAL;
-               }
 
                sconv = zip->sconv;
                if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
@@ -954,6 +957,12 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
                        }
                }
                zip_entry->uncompressed_size = zip_entry->compressed_size = 0;
+
+               if (__archive_read_consume(a, linkname_length) < 0) {
+                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                           "Read error skipping symlink target name");
+                       return ARCHIVE_FATAL;
+               }
        } else if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
            || zip_entry->uncompressed_size > 0) {
                /* Set the size only if it's meaningful. */
@@ -2316,7 +2325,7 @@ read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
        eocd64_size = archive_le64dec(p + 4) + 12;
        if (eocd64_size < 56 || eocd64_size > 16384)
                return;
-       if ((p = __archive_read_ahead(a, eocd64_size, NULL)) == NULL)
+       if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL)
                return;
 
        /* Sanity-check the EOCD64 */