mirror of
https://github.com/sheumann/hush.git
synced 2025-01-18 07:31:34 +00:00
tar: abort if tarring up file larger that 64Gb
(otherwise we will produce garbled tarfile)
This commit is contained in:
parent
5dd27b1ee0
commit
f2408e6c3f
@ -150,40 +150,29 @@ static HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, struct stat *statbu
|
|||||||
|
|
||||||
/* Put an octal string into the specified buffer.
|
/* Put an octal string into the specified buffer.
|
||||||
* The number is zero padded and possibly null terminated.
|
* The number is zero padded and possibly null terminated.
|
||||||
* Returns TRUE if successful. - DISABLED (no caller ever checked) */
|
* Stores low-order bits only if whole value does not fit.
|
||||||
/* FIXME: we leave field untouched if value doesn't fit. */
|
* Returns FALSE if that happens. */
|
||||||
/* This is not good - what will happen at untar time?? */
|
static int putOctal(char *cp, int len, off_t value)
|
||||||
static void putOctal(char *cp, int len, long long value)
|
|
||||||
{
|
{
|
||||||
int tempLength;
|
char tempBuffer[sizeof(off_t)*3+1];
|
||||||
/* long long for the sake of storing lengths of 4Gb+ files */
|
|
||||||
/* (we are bust anyway after 64Gb: it doesn't fit into the field) */
|
|
||||||
char tempBuffer[sizeof(long long)*3+1];
|
|
||||||
char *tempString = tempBuffer;
|
char *tempString = tempBuffer;
|
||||||
|
int width;
|
||||||
|
|
||||||
/* Create a string of the specified length with
|
width = sprintf(tempBuffer, "%0*"OFF_FMT"o", len, value);
|
||||||
* leading zeroes and the octal number, and a trailing null. */
|
tempString += (width - len);
|
||||||
tempLength = sprintf(tempBuffer, "%0*llo", len - 1, value);
|
|
||||||
|
|
||||||
/* If the string is too large, suppress leading 0's. */
|
/* If string has leading zeroes, we can drop one */
|
||||||
/* If that is not enough, drop trailing null. */
|
/* and field will have trailing '\0' */
|
||||||
tempLength -= len; /* easier to do checks */
|
/* (increases chances of compat with other tars) */
|
||||||
while (tempLength >= 0) {
|
if (tempString[0] == '0')
|
||||||
if (tempString[0] != '0') {
|
tempString++;
|
||||||
if (!tempLength) {
|
|
||||||
/* 1234 barely fits in 4 chars (w/o EOL '\0') */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* 12345 doesn't fit into 4 chars */
|
|
||||||
return /*FALSE*/;
|
|
||||||
}
|
|
||||||
tempLength--; /* still have leading '0', */
|
|
||||||
tempString++; /* can afford to drop it but retain EOL '\0' */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the string to the field. */
|
/* Copy the string to the field */
|
||||||
memcpy(cp, tempString, len);
|
memcpy(cp, tempString, len);
|
||||||
/*return TRUE;*/
|
|
||||||
|
/* If after shift we have zero - value did not overflow, */
|
||||||
|
/* return 1 (TRUE) then */
|
||||||
|
return (value >> (len*3)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out a tar header for the specified file/directory/whatever */
|
/* Write out a tar header for the specified file/directory/whatever */
|
||||||
@ -203,12 +192,13 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
|
|||||||
|
|
||||||
safe_strncpy(header.name, header_name, sizeof(header.name));
|
safe_strncpy(header.name, header_name, sizeof(header.name));
|
||||||
|
|
||||||
|
#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b))
|
||||||
/* POSIX says to mask mode with 07777. */
|
/* POSIX says to mask mode with 07777. */
|
||||||
putOctal(header.mode, sizeof(header.mode), statbuf->st_mode & 07777);
|
PUT_OCTAL(header.mode, statbuf->st_mode & 07777);
|
||||||
putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
|
PUT_OCTAL(header.uid, statbuf->st_uid);
|
||||||
putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
|
PUT_OCTAL(header.gid, statbuf->st_gid);
|
||||||
memset(header.size, '0', sizeof(header.size)-1); /* Regular file size is handled later */
|
memset(header.size, '0', sizeof(header.size)-1); /* Regular file size is handled later */
|
||||||
putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
|
PUT_OCTAL(header.mtime, statbuf->st_mtime);
|
||||||
strcpy(header.magic, "ustar ");
|
strcpy(header.magic, "ustar ");
|
||||||
|
|
||||||
/* Enter the user and group names */
|
/* Enter the user and group names */
|
||||||
@ -240,25 +230,28 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
|
|||||||
strncat(header.name, "/", sizeof(header.name));
|
strncat(header.name, "/", sizeof(header.name));
|
||||||
} else if (S_ISCHR(statbuf->st_mode)) {
|
} else if (S_ISCHR(statbuf->st_mode)) {
|
||||||
header.typeflag = CHRTYPE;
|
header.typeflag = CHRTYPE;
|
||||||
putOctal(header.devmajor, sizeof(header.devmajor),
|
PUT_OCTAL(header.devmajor, major(statbuf->st_rdev));
|
||||||
major(statbuf->st_rdev));
|
PUT_OCTAL(header.devminor, minor(statbuf->st_rdev));
|
||||||
putOctal(header.devminor, sizeof(header.devminor),
|
|
||||||
minor(statbuf->st_rdev));
|
|
||||||
} else if (S_ISBLK(statbuf->st_mode)) {
|
} else if (S_ISBLK(statbuf->st_mode)) {
|
||||||
header.typeflag = BLKTYPE;
|
header.typeflag = BLKTYPE;
|
||||||
putOctal(header.devmajor, sizeof(header.devmajor),
|
PUT_OCTAL(header.devmajor, major(statbuf->st_rdev));
|
||||||
major(statbuf->st_rdev));
|
PUT_OCTAL(header.devminor, minor(statbuf->st_rdev));
|
||||||
putOctal(header.devminor, sizeof(header.devminor),
|
|
||||||
minor(statbuf->st_rdev));
|
|
||||||
} else if (S_ISFIFO(statbuf->st_mode)) {
|
} else if (S_ISFIFO(statbuf->st_mode)) {
|
||||||
header.typeflag = FIFOTYPE;
|
header.typeflag = FIFOTYPE;
|
||||||
} else if (S_ISREG(statbuf->st_mode)) {
|
} else if (S_ISREG(statbuf->st_mode)) {
|
||||||
header.typeflag = REGTYPE;
|
header.typeflag = REGTYPE;
|
||||||
putOctal(header.size, sizeof(header.size), statbuf->st_size);
|
if ((PUT_OCTAL(header.size, statbuf->st_size) == FALSE)
|
||||||
|
&& sizeof(statbuf->st_size) > 4
|
||||||
|
) {
|
||||||
|
bb_error_msg_and_die("cannot store file '%s' "
|
||||||
|
"of size %"OFF_FMT"d, aborting",
|
||||||
|
fileName, statbuf->st_size);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
bb_error_msg("%s: unknown file type", fileName);
|
bb_error_msg("%s: unknown file type", fileName);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#undef PUT_OCTAL
|
||||||
|
|
||||||
/* Calculate and store the checksum (i.e., the sum of all of the bytes of
|
/* Calculate and store the checksum (i.e., the sum of all of the bytes of
|
||||||
* the header). The checksum field must be filled with blanks for the
|
* the header). The checksum field must be filled with blanks for the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user