]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Avoid undefined behavior in magic checking
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 26 Jul 2025 07:27:01 +0000 (00:27 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 26 Jul 2025 09:20:53 +0000 (02:20 -0700)
* 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.

src/buffer.c
src/list.c

index 1165186a6c35d29891971fef1c0a0a7a4540d9d8..e0d415c307a733e45552ef9233a500660297df54 100644 (file)
@@ -419,10 +419,11 @@ check_compressed_archive (bool *pshort)
   read_full_records = sfr;
 
   if (record_start != record_end /* no files smaller than BLOCKSIZE */
-      && (strcmp (record_start->header.magic, TMAGIC) == 0
-          || strcmp (record_start->buffer + offsetof (struct posix_header,
-                                                      magic),
-                     OLDGNU_MAGIC) == 0)
+      && (memcmp (record_start->header.magic, TMAGIC, sizeof TMAGIC) == 0
+          || (memcmp (record_start->buffer + offsetof (struct posix_header,
+                                                      magic),
+                     OLDGNU_MAGIC, sizeof OLDGNU_MAGIC)
+             == 0))
       && tar_checksum (record_start, true) == HEADER_SUCCESS)
     /* Probably a valid header */
     return ct_tar;
index 8e80714190f766efccba22ab5f2575a7bab82f1b..822c12dd166c6d1744d66d425f5f978bca47a15c 100644 (file)
@@ -542,7 +542,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
                  section 10.1.1.  */
              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);
                  np[sizeof h->prefix] = '\0';
@@ -613,7 +613,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
   bool 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
          && is_octal_digit (header->star_header.atime[0])
@@ -626,8 +626,8 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
       else
        format = USTAR_FORMAT;
     }
-  else if (strcmp (header->buffer + offsetof (struct posix_header, magic),
-                  OLDGNU_MAGIC)
+  else if (memcmp (header->buffer + offsetof (struct posix_header, magic),
+                  OLDGNU_MAGIC, sizeof OLDGNU_MAGIC)
           == 0)
     format = hbits ? OLDGNU_FORMAT : GNU_FORMAT;
   else