summaryrefslogtreecommitdiff
path: root/archival/tar.c
diff options
context:
space:
mode:
authorDenis Vlasenko2006-11-24 14:55:23 +0000
committerDenis Vlasenko2006-11-24 14:55:23 +0000
commit4fbb584a0e6ee086d6b30936c7124c687b3e977f (patch)
tree279f3ff5c1a47d36ad4eec248240f11c7ef8d438 /archival/tar.c
parent0b35470d9b5e75a7a1df2e6860b48831e7920353 (diff)
downloadbusybox-4fbb584a0e6ee086d6b30936c7124c687b3e977f.zip
busybox-4fbb584a0e6ee086d6b30936c7124c687b3e977f.tar.gz
tar: cry murder and bail out if file shrinks under us while we tar it up
Diffstat (limited to 'archival/tar.c')
-rw-r--r--archival/tar.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 6aaa422..99c4adb 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -59,7 +59,7 @@ struct TarHeader { /* byte offset */
typedef struct TarHeader TarHeader;
/*
-** writeTarFile(), writeFileToTarball(), and writeTarHeader() are
+** writeTarFile(), writeFileToTarball(), and writeTarHeader() are
** the only functions that deal with the HardLinkInfo structure.
** Even these functions use the xxxHardLinkInfo() functions.
*/
@@ -397,7 +397,17 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf,
off_t readSize = 0;
/* write the file to the archive */
- readSize = bb_copyfd_eof(inputFileFd, tbInfo->tarFd);
+ readSize = bb_copyfd_size(inputFileFd, tbInfo->tarFd, statbuf->st_size);
+ if (readSize != statbuf->st_size) {
+ /* Deadly. We record size into header first, */
+ /* and then write out file. If file shrinks in between, */
+ /* tar will be corrupted. So bail out. */
+ /* NB: GNU tar 1.16 warns and pads with zeroes */
+ /* or even seeks back and updates header */
+ bb_error_msg_and_die("short read from %s", fileName);
+ }
+ /* Check that file did not grow in between? */
+ /* if (safe_read(inputFileFd,1) == 1) warn but continue? */
close(inputFileFd);
/* Pad the file up to the tar block size */