From b8feb2b14247d76200fd53607d3613c82b6e5b81 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 27 Oct 2010 22:25:18 -0700 Subject: [PATCH] tar: don't cross struct member boundaries with OLDGNU_MAGIC * src/create.c (write_gnu_long_link, start_header): Access header->buffer + offsetof (struct posix_header, magic), instead of header->header.magic, when reading or writing the OLDGNU_MAGIC pattern. The code violates the C standard without this change, and GCC warns about this if fortify checking is enabled. It's not a bug on traditional (i.e., non-debugging) platforms, but it does violate the C standard so it should be fixed. Problem originally reported by John Emil Karlson in . * src/list.c (decode_header): Likewise. --- src/create.c | 6 ++++-- src/list.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/create.c b/src/create.c index 05af0d9..a1e90a3 100644 --- a/src/create.c +++ b/src/create.c @@ -562,7 +562,8 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type) GNAME_TO_CHARS (tmpname, header->header.gname); free (tmpname); - strcpy (header->header.magic, OLDGNU_MAGIC); + strcpy (header->buffer + offsetof (struct posix_header, magic), + OLDGNU_MAGIC); header->header.typeflag = type; finish_header (st, header, -1); @@ -899,7 +900,8 @@ start_header (struct tar_stat_info *st) case OLDGNU_FORMAT: case GNU_FORMAT: /*FIXME?*/ /* Overwrite header->header.magic and header.version in one blow. */ - strcpy (header->header.magic, OLDGNU_MAGIC); + strcpy (header->buffer + offsetof (struct posix_header, magic), + OLDGNU_MAGIC); break; case POSIX_FORMAT: diff --git a/src/list.c b/src/list.c index c65e171..a70f0d3 100644 --- a/src/list.c +++ b/src/list.c @@ -122,7 +122,7 @@ transform_stat_info (int typeflag, struct tar_stat_info *stat_info) if (typeflag == GNUTYPE_VOLHDR) /* Name transformations don't apply to volume headers. */ return; - + transform_member_name (&stat_info->file_name, XFORM_REGFILE); switch (typeflag) { @@ -592,7 +592,9 @@ decode_header (union block *header, struct tar_stat_info *stat_info, else format = USTAR_FORMAT; } - else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0) + else if (strcmp (header->buffer + offsetof (struct posix_header, magic), + OLDGNU_MAGIC) + == 0) format = hbits ? OLDGNU_FORMAT : GNU_FORMAT; else format = V7_FORMAT; -- 2.44.0