[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-tar] [BUG] [PATCH] Multiple Bug Reports for an Old GNU tar Bug
From: |
Paul Eggert |
Subject: |
Re: [Bug-tar] [BUG] [PATCH] Multiple Bug Reports for an Old GNU tar Bug |
Date: |
Wed, 27 Oct 2010 22:35:28 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.11) Gecko/20101006 Thunderbird/3.1.5 |
On 10/27/2010 03:19 AM, Shlomi Fish wrote:
> This bug was originally reported on
> http://www.mail-archive.com/address@hidden/msg02601.html (and a patch was
> provided)
Thanks, I didn't see that. That patch doesn't completely fix the bug,
in the sense that it does not completely fix the technical violation
of the C Standard that GCC only partly detects.
I installed the following patch instead, which I think does fix the
technical violation in question. Could you please give it a try
on your platform? Thanks.
>From c7539fe7236f1cc1658fab56c427850712c141ea Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
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
<http://lists.gnu.org/archive/html/bug-tar/2010-04/msg00023.html>.
* 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;
--
1.7.2