The oldgnu format can encode large header fields in base-256. On the Hurd, for example, a fifo is a translator and its mode bits contain at least the S_IROOT (040000000) bit set. For the v7 and ustar formats all unknown mode bits are masked at the call site, and ustar, posix and gnu formats only encode known mode bits. But oldgnu is left unmasked and encoding all unknown bits, which is very unexpected as these are system-specific internal details on how to represent fifos (or other translators).
GNU tar should consider oldgnu in the same way as the gnu, posix and ustar formats, and ignore unknown bits when encoding the mode. * src/create.c (mode_to_chars): Exclude OLDGNU_FORMAT from the common case. --- src/create.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/create.c b/src/create.c index 7737c52..568e048 100644 --- a/src/create.c +++ b/src/create.c @@ -380,7 +380,7 @@ static bool mode_to_chars (mode_t v, char *p, size_t s) { /* In the common case where the internal and external mode bits are the same, - and we are not using POSIX or GNU format, + and we are not using POSIX or GNU formats, propagate all unknown bits to the external mode. This matches historical practice. Otherwise, just copy the bits we know about. */ @@ -392,6 +392,7 @@ mode_to_chars (mode_t v, char *p, size_t s) && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC && archive_format != POSIX_FORMAT && archive_format != USTAR_FORMAT + && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT) { negative = v < 0; -- 2.19.1.1182.g4ecb1133ce