From: datauwu Date: Sat, 11 Jul 2026 04:06:46 +0000 (+0800) Subject: cpio: fix read-ahead pointer lifetime issue X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=23b54da0baae02be3beb41ade8e674bcad535310;p=thirdparty%2Flibarchive.git cpio: fix read-ahead pointer lifetime issue Cache the CPIO trailer-name check before consuming the pathname buffer. The reader kept a pointer returned by __archive_read_ahead() and used it after __archive_read_consume(), and after possible symlink body processing. Read-ahead pointers are views into libarchive input buffers and should not be relied on after the associated bytes are consumed. Store the TRAILER!!! decision while the pathname buffer is still valid, then use the saved boolean after the remaining header handling. --- diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c index 5df8f9a0b..7341aa0c1 100644 --- a/libarchive/archive_read_support_format_cpio.c +++ b/libarchive/archive_read_support_format_cpio.c @@ -369,6 +369,7 @@ archive_read_format_cpio_read_header(struct archive_read *a, struct archive_string_conv *sconv; size_t namelength; size_t name_pad; + int is_trailer; int r; cpio = (struct cpio *)(a->format->data); @@ -411,6 +412,9 @@ archive_read_format_cpio_read_header(struct archive_read *a, archive_string_conversion_charset_name(sconv)); r = ARCHIVE_WARN; } + /* Save this before consuming the name buffer below. */ + is_trailer = (namelength == 11 && + memcmp((const char *)h, "TRAILER!!!", 10) == 0); cpio->entry_offset = 0; __archive_read_consume(a, namelength); @@ -451,8 +455,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 && strncmp((const char *)h, "TRAILER!!!", - 10) == 0) { + if (is_trailer) { /* TODO: Store file location of start of block. */ archive_clear_error(&a->archive); return (ARCHIVE_EOF);