cpio reader: compare TRAILER!!! against pathname only
If entry was a symlink, the old code replaced the pointer with linkname.
Reported-By: OSS-Fuzz issue 504
diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
index d4f6ffd..ffd4a85 100644
--- a/libarchive/archive_read_support_format_cpio.c
+++ b/libarchive/archive_read_support_format_cpio.c
@@ -356,7 +356,7 @@
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 @@
"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 @@
* 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);