]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
cpio reader: compare TRAILER!!! against pathname only
authorMartin Matuska <martin@matuska.org>
Mon, 6 Feb 2017 23:57:18 +0000 (00:57 +0100)
committerMartin Matuska <martin@matuska.org>
Tue, 7 Feb 2017 00:01:49 +0000 (01:01 +0100)
If entry was a symlink, the old code replaced the pointer with linkname.

Reported-By: OSS-Fuzz issue 504

libarchive/archive_read_support_format_cpio.c

index d4f6ffd912630bba31373d4978c7524953fe7586..ffd4a8580ab45442082885437eaff9ab4679f832 100644 (file)
@@ -356,7 +356,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
     struct archive_entry *entry)
 {
        struct cpio *cpio;
-       const void *h;
+       const void *h, *hl;
        struct archive_string_conv *sconv;
        size_t namelength;
        size_t name_pad;
@@ -406,11 +406,11 @@ archive_read_format_cpio_read_header(struct archive_read *a,
                            "Rejecting malformed cpio archive: symlink contents exceed 1 megabyte");
                        return (ARCHIVE_FATAL);
                }
-               h = __archive_read_ahead(a,
+               hl = __archive_read_ahead(a,
                        (size_t)cpio->entry_bytes_remaining, NULL);
-               if (h == NULL)
+               if (hl == NULL)
                        return (ARCHIVE_FATAL);
-               if (archive_entry_copy_symlink_l(entry, (const char *)h,
+               if (archive_entry_copy_symlink_l(entry, (const char *)hl,
                    (size_t)cpio->entry_bytes_remaining, sconv) != 0) {
                        if (errno == ENOMEM) {
                                archive_set_error(&a->archive, ENOMEM,
@@ -434,7 +434,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
         * header.  XXX */
 
        /* Compare name to "TRAILER!!!" to test for end-of-archive. */
-       if (namelength == 11 && memcmp((const char *)h, "TRAILER!!!",
+       if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
            11) == 0) {
                /* TODO: Store file location of start of block. */
                archive_clear_error(&a->archive);