[BusyBox] Race condition with tar zxf

Glenn McGrath bug1 at optushome.com.au
Tue Mar 27 13:50:45 UTC 2001


Robert Kaiser wrote:
> 
> Hi,
> 
> I just experienced an interesting problem with BusyBox tar
> (current CVS version):
> 
> when extracting a compressed tar file onto a JFFS file system
> with "tar zxvf", the last extracted file is always too short
> by -in my case- ~3KB. This does not happen when the same tar
> file is being extracted onto -for example- a RAMFS filesystem.
> It also does not happen if I do a
> 
>  zcat <tarfile.tgz> | tar xvf -
> 
> rather than a
> 
>  tar zxvf <tarfile.tgz>
> 
> though both should really do the same thing.
> 
> The JFFS filesystem is relatively slow on writes, so, apparently
> what happens is that the unzip process that busybox tar forks off
> terminates before the tar process has begun processing the last
> chunk of data. The termination of unzip triggers the signal handler
> ("child_died()") which in turn causes tar to exit prematurely
> (i.e. before it has completely written the last file).
> 
> The attached "patch-sighand" fixes this problem by explicitly
> retrieving the child's exit status and continuing if the child
> exited normally.
> 
> However, I'm still wondering why we need this signal fuss at all.
> I would expect that read() returns zero (indicating EOF) when the
> gzip process at the other end of the pipe terminates and the pipe
> is empty, so, not setting up a signal handler at all should work
> fine. I have tried this (see the second attached "patch-no-sighand")
> and it solved my problem just as well. Question is: have I broken
> anything ?
> 
> What do you all think ?
> 
> Rob
> 

Ive been working on some dpkg applets, which are .ar files that contain
.tar.gz files inside, in this case the .tar.gz is in the middle of other
data, so if read is allowed to continue it will read past the end of the
.tar.gz and then encounter invalid data (the start of the next file) and
report an error.

I have some cleanup to gunzip, which also provides a gz_open() and
gz_close() function, gz_open passes back the file handler and the
proccess id, gz_close just uses kill to abort the forked process.

Tommorow i will commit my new gunzip cleanup (which im pretty happy
with), the gz_open and gz_close wont be used for anything stright away,
but i should be able to come up with a quick patch to show how tar could
use it

The gz_open code is mostly taken from tar anyway, i think the forking
code for accessing a decompressed stream of data really should go in the
gunzip.c rather than in applets prior to calling unzip.


Glenn





More information about the busybox mailing list