Subject: bin/8227: pax is too aggressive in avoiding old gnutar archive damage
To: None <gnats-bugs@gnats.netbsd.org>
From: Seebs <seebs@lobe.fleet.plethora.net>
List: netbsd-bugs
Date: 08/18/1999 10:50:55
>Number: 8227
>Category: bin
>Synopsis: pax has workarounds for GNU tar damage that are too complete
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Aug 18 10:50:01 1999
>Last-Modified:
>Originator: Seebs
>Organization:
>Release: Aug 1999
>Environment:
System: NetBSD lobe.fleet.plethora.net 1.4J NetBSD 1.4J (LOBE) #0: Tue Aug 17 10:44:59 PDT 1999 seebs@lobe.fleet.plethora.net:/usr/src/sys/arch/i386/compile/LOBE i386
>Description:
There's a chunk of code in pax to work around "oldgnutar" (up through
the version released last week, actually) damage, where you'd see
spurious early end-of-archive. It turns out it's too aggressive; the
only "legitimate" failure mode is that GNU tar only writes one
512-byte "trailer" block. (Modulo padding, which means you only see
this flaw one time in 20.)
>How-To-Repeat:
Spend 3 hours studying tar archives and figuring out when they break.
>Fix:
I have enclosed diffs which still don't complain about the "defective"
GNU tar archives, but which will catch any *other* premature end of
archive problems.
GNU has accepted a bug report, and the next release of GNU tar should
not have this problem.
*** ar_io.c.orig Wed Aug 18 10:03:27 1999
--- ar_io.c Wed Aug 18 10:04:14 1999
***************
*** 614,620 ****
lstrval = res;
if (res < 0)
syswarn(1, errno, "Failed read on archive volume %d", arvol);
! else if (!is_oldgnutar)
tty_warn(0, "End of archive volume %d reached", arvol);
return(res);
}
--- 614,620 ----
lstrval = res;
if (res < 0)
syswarn(1, errno, "Failed read on archive volume %d", arvol);
! else
tty_warn(0, "End of archive volume %d reached", arvol);
return(res);
}
***************
*** 1195,1201 ****
if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
syswarn(0, errno, "Unable to restore signal mask");
! if (done || !wr_trail || is_oldgnutar)
return(-1);
tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
--- 1195,1201 ----
if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
syswarn(0, errno, "Unable to restore signal mask");
! if (done || !wr_trail)
return(-1);
tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
*** ar_subs.c.orig Wed Aug 18 10:03:32 1999
--- ar_subs.c Wed Aug 18 10:03:58 1999
***************
*** 1009,1017 ****
* storage device, better give the user the bad news.
*/
if ((ret == 0) || (rd_sync() < 0)) {
! if (!is_oldgnutar)
! tty_warn(1,
! "Premature end of file on archive read");
return(-1);
}
if (!in_resync) {
--- 1009,1016 ----
* storage device, better give the user the bad news.
*/
if ((ret == 0) || (rd_sync() < 0)) {
! tty_warn(1,
! "Premature end of file on archive read");
return(-1);
}
if (!in_resync) {
*** tar.c.orig Wed Aug 18 10:03:35 1999
--- tar.c Wed Aug 18 10:04:46 1999
***************
*** 164,170 ****
* might as well throw this block out since a valid header can NEVER be
* a block of all 0 (we must have a valid file name).
*/
! if (!in_resync && (++*cnt >= NULLCNT))
return(0);
return(1);
}
--- 164,176 ----
* might as well throw this block out since a valid header can NEVER be
* a block of all 0 (we must have a valid file name).
*/
! ++*cnt;
! /* old GNU tar (up through 1.13) only writes one block of trailers,
! * so we pretend we got another
! */
! if (is_oldgnutar)
! ++*cnt;
! if (!in_resync && (*cnt >= NULLCNT))
return(0);
return(1);
}
>Audit-Trail:
>Unformatted: