[Bug 6908] tar is broken on Android: resulting stream produces damaged files when unpacked

bugzilla at busybox.net bugzilla at busybox.net
Mon Feb 24 13:57:58 UTC 2014


https://bugs.busybox.net/show_bug.cgi?id=6908

--- Comment #7 from Denys Vlasenko <vda.linux at googlemail.com> 2014-02-24 13:57:58 UTC ---
(In reply to comment #6)
> Created attachment 5252 [details]
> strace of the tar command
> 
> Attaching the requested output of this command:
> (strace -s99 busybox tar cf - huge3plus >/dev/null) 2>&1 | bzip2 >z.bz2

Thanks. strace shows 117181 reads of 4096 bytes from the file, then one final
read of 2112 bytes and then tar writes EOF marker and exits:

...
read(3,
"1234567890abcde\n1234567890abcde\n1234567890abcde\n1234567890abcde\n1234567890abcde\n1234567890abcde\n123"...,
2112) = 2112
write(1,
"1234567890abcde\n1234567890abcde\n1234567890abcde\n1234567890abcde\n1234567890abcde\n1234567890abcde\n123"...,
2112) = 2112
close(3)                                = 0
write(1,
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
64) = 64
write(1,
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
close(1)                                = 0
mprotect(0x4018a000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x4018a000, 4096, PROT_READ)   = 0
munmap(0x4018a000, 4096)                = 0
exit_group(0)                           = ?

In total, tar reads 479975488 bytes (~457 Mb) which matches tarball size. Note
that tarball did not reach EOF on read. This is because it uses stat() result
to read exactly as many bytes as stat() indicated:

                /* We record size into header first, */
                /* and then write out file. If file shrinks in between, */
                /* tar will be corrupted. So we don't allow for that. */
                /* NB: GNU tar 1.16 warns and pads with zeroes */
                /* or even seeks back and updates header */
                bb_copyfd_exact_size(inputFileFd, tbInfo->tarFd,
statbuf->st_size);

But stat() did give us the correct size:

lstat64("huge3plus", {st_mode=S_IFREG|075, st_size=3815000000, ...}) = 0
open("huge3plus", O_RDONLY)             = 3

bb_copyfd_exact_size() has a special convention for negative size
parameter:
"size < 0 means "ignore write errors", used by tar --to-command".
If 3815000000 is treated as negative (IOW: if your libc have 32-bit off_t),
then it will think that it was given size = -479967296. Hmm. Looks like that's
it.

Do you have CONFIG_LFS=y in your .config?
What version of libc do you use?
What is its sizeof(off_t)?

-- 
Configure bugmail: https://bugs.busybox.net/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


More information about the busybox-cvs mailing list