summaryrefslogtreecommitdiff
path: root/contrib/cpio/src/copyout.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cpio/src/copyout.c')
-rw-r--r--contrib/cpio/src/copyout.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/contrib/cpio/src/copyout.c b/contrib/cpio/src/copyout.c
index 75d076b84d95..63cb0e225839 100644
--- a/contrib/cpio/src/copyout.c
+++ b/contrib/cpio/src/copyout.c
@@ -303,12 +303,13 @@ write_out_header (struct new_cpio_header *file_hdr, int out_des)
{
char ascii_header[112];
char *magic_string;
+ int ret;
if (archive_format == arf_crcascii)
magic_string = "070702";
else
magic_string = "070701";
- sprintf (ascii_header,
+ ret = snprintf (ascii_header, sizeof(ascii_header),
"%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
magic_string,
file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
@@ -316,6 +317,10 @@ write_out_header (struct new_cpio_header *file_hdr, int out_des)
file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
file_hdr->c_chksum);
+ if (ret >= sizeof(ascii_header)) {
+ fprintf(stderr, "Internal overflow, aborting\n");
+ exit (1);
+ }
tape_buffered_write (ascii_header, out_des, 110L);
/* Write file name to output. */
@@ -325,6 +330,7 @@ write_out_header (struct new_cpio_header *file_hdr, int out_des)
else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
{
char ascii_header[78];
+ int ret;
dev_t dev;
dev_t rdev;
@@ -365,7 +371,7 @@ write_out_header (struct new_cpio_header *file_hdr, int out_des)
/* Debian hack: The type of dev_t has changed in glibc. Fixed output
to ensure that a long int is passed to sprintf. This has been
reported to "bug-gnu-utils@prep.ai.mit.edu". (1998/5/26) -BEM */
- sprintf (ascii_header,
+ snprintf (ascii_header, sizeof(ascii_header),
"%06ho%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
file_hdr->c_magic & 0xFFFF, (long) dev & 0xFFFF,
file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
@@ -373,6 +379,10 @@ write_out_header (struct new_cpio_header *file_hdr, int out_des)
file_hdr->c_nlink & 0xFFFF, (long) rdev & 0xFFFF,
file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
file_hdr->c_filesize);
+ if (ret >= sizeof(ascii_header)) {
+ fprintf(stderr, "Internal overflow, aborting\n");
+ exit (1);
+ }
tape_buffered_write (ascii_header, out_des, 76L);
/* Write file name to output. */
@@ -508,6 +518,14 @@ process_copy_out ()
file_hdr.c_dev_maj = major (file_stat.st_dev);
file_hdr.c_dev_min = minor (file_stat.st_dev);
file_hdr.c_ino = file_stat.st_ino;
+
+ /* Skip files larger than 4GB which will cause problems on
+ 64bit platforms (and just not work on 32bit). */
+ if (file_stat.st_size > 0xffffffff) {
+ error (0, 0, "%s: skipping >4GB file", input_name.ds_string);
+ continue;
+ }
+
/* For POSIX systems that don't define the S_IF macros,
we can't assume that S_ISfoo means the standard Unix
S_IFfoo bit(s) are set. So do it manually, with a