Avoid undefined behavior in magic checking

* src/buffer.c (check_compressed_archive):
* src/list.c (read_header, decode_header):
Use memcmp, not strcmp, when looking for magic strings in
headers, since input headers are not guaranteed to be
strings and strcmp has undefined behavior otherwise.
This commit is contained in:
Paul Eggert
2025-07-26 00:27:01 -07:00
parent 75735940f1
commit c11084bcc2
2 changed files with 9 additions and 8 deletions

View File

@@ -419,10 +419,11 @@ check_compressed_archive (bool *pshort)
read_full_records = sfr; read_full_records = sfr;
if (record_start != record_end /* no files smaller than BLOCKSIZE */ if (record_start != record_end /* no files smaller than BLOCKSIZE */
&& (strcmp (record_start->header.magic, TMAGIC) == 0 && (memcmp (record_start->header.magic, TMAGIC, sizeof TMAGIC) == 0
|| strcmp (record_start->buffer + offsetof (struct posix_header, || (memcmp (record_start->buffer + offsetof (struct posix_header,
magic), magic),
OLDGNU_MAGIC) == 0) OLDGNU_MAGIC, sizeof OLDGNU_MAGIC)
== 0))
&& tar_checksum (record_start, true) == HEADER_SUCCESS) && tar_checksum (record_start, true) == HEADER_SUCCESS)
/* Probably a valid header */ /* Probably a valid header */
return ct_tar; return ct_tar;

View File

@@ -542,7 +542,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
section 10.1.1. */ section 10.1.1. */
char *np = namebuf; char *np = namebuf;
if (h->prefix[0] && strcmp (h->magic, TMAGIC) == 0) if (h->prefix[0] && memcmp (h->magic, TMAGIC, sizeof TMAGIC) == 0)
{ {
memcpy (np, h->prefix, sizeof h->prefix); memcpy (np, h->prefix, sizeof h->prefix);
np[sizeof h->prefix] = '\0'; np[sizeof h->prefix] = '\0';
@@ -613,7 +613,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
bool hbits; bool hbits;
mode_t mode = MODE_FROM_HEADER (header->header.mode, &hbits); mode_t mode = MODE_FROM_HEADER (header->header.mode, &hbits);
if (strcmp (header->header.magic, TMAGIC) == 0) if (memcmp (header->header.magic, TMAGIC, sizeof TMAGIC) == 0)
{ {
if (header->star_header.prefix[130] == 0 if (header->star_header.prefix[130] == 0
&& is_octal_digit (header->star_header.atime[0]) && is_octal_digit (header->star_header.atime[0])
@@ -626,8 +626,8 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
else else
format = USTAR_FORMAT; format = USTAR_FORMAT;
} }
else if (strcmp (header->buffer + offsetof (struct posix_header, magic), else if (memcmp (header->buffer + offsetof (struct posix_header, magic),
OLDGNU_MAGIC) OLDGNU_MAGIC, sizeof OLDGNU_MAGIC)
== 0) == 0)
format = hbits ? OLDGNU_FORMAT : GNU_FORMAT; format = hbits ? OLDGNU_FORMAT : GNU_FORMAT;
else else