From 935c8525f606a16964b1cdee6dd30f82c8990459 Mon Sep 17 00:00:00 2001 From: Tyler Yankee Date: Sat, 9 May 2026 19:35:34 -0400 Subject: [PATCH] libarchive: Backport "Validate pathname in record_hardlink" Backport libarchive commit `16ad931073` (cpio reader: Validate pathname in record_hardlink, 2026-05-08). Add a fuzzing test case to expose this to dynamic analysis tools. --- Tests/Fuzzing/corpus/archive/no-pathname.tar | Bin 0 -> 28 bytes .../libarchive/archive_read_support_format_cpio.c | 13 ++++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Tests/Fuzzing/corpus/archive/no-pathname.tar diff --git a/Tests/Fuzzing/corpus/archive/no-pathname.tar b/Tests/Fuzzing/corpus/archive/no-pathname.tar new file mode 100644 index 0000000000000000000000000000000000000000..d02a2c6255ef3a8d7bd71d758c70fe4ce8114b6c GIT binary patch literal 28 WcmXRs{vQb_fY=HQj0!;T|33gsgcIlh literal 0 HcmV?d00001 diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c index 526096b39f..eb52f128fe 100644 --- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c +++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c @@ -1102,6 +1102,16 @@ record_hardlink(struct archive_read *a, ENOMEM, "Out of memory adding file to list"); return (ARCHIVE_FATAL); } + + const char *pathname = archive_entry_pathname(entry); + if (pathname == NULL) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Invalid hardlink entry with no pathname"); + free(le); + return (ARCHIVE_FATAL); + } + if (cpio->links_head != NULL) cpio->links_head->previous = le; le->next = cpio->links_head; @@ -1110,10 +1120,11 @@ record_hardlink(struct archive_read *a, le->dev = dev; le->ino = ino; le->links = archive_entry_nlink(entry) - 1; - le->name = strdup(archive_entry_pathname(entry)); + le->name = strdup(pathname); if (le->name == NULL) { archive_set_error(&a->archive, ENOMEM, "Out of memory adding file to list"); + free(le); return (ARCHIVE_FATAL); }