mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-19 22:43:22 +01:00
Improve the handling of large minor numbers:
cpio/copyout.c: Don't output a file if the major, minor or totality of its rdev would be truncated. Print a message about the skipped files to stderr but don't report the error in the exit status. cpio's abysmal error handling doesn't allow continuing after an error, and the rdev checks had to be misplaced to avoid the problem of returning an error code from routines that return void. pax/pax.h: Use the system macros for major(), minor() and makedev(). pax already checks _all_ output conversions for overflow. This has the undesirable effect that failure to convert relatively useless fields such as st_dev for regular files causes files not to be output. pax doesn't report exactly which fields couldn't be converted. tar/create.c: Don't output a file if the major or minor its rdev would be truncated. Print a message about the skipped files to stderr and report the error in the exit status. tar/tar.c: For not immediately fatal errors, exit with status 1, not the error count (mod 256). All: Minor numbers are limited to 21 bits in pax's ustar format and to 18 bits in archives created by gnu tar (gnu tar wastes 3 bits for padding). pax's and cpio's ustar format is incompatible with gnu tar's ustar format for other reasons (see cpio/README).
This commit is contained in:
parent
5d2fb2731f
commit
d1e00e9390
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=9322
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pax.h 8.2 (Berkeley) 4/18/94
|
||||
* $Id: pax.h,v 1.2 1994/09/24 02:56:28 davidg Exp $
|
||||
* $Id: pax.h,v 1.3 1995/05/30 00:07:01 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -227,9 +227,9 @@ typedef struct oplist {
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
#define MAJOR(x) (((unsigned)(x) >> 8) & 0xff)
|
||||
#define MINOR(x) ((x) & 0xff)
|
||||
#define TODEV(x, y) (((unsigned)(x) << 8) | ((unsigned)(y)))
|
||||
#define MAJOR(x) major(x)
|
||||
#define MINOR(x) minor(x)
|
||||
#define TODEV(x, y) makedev((x), (y))
|
||||
|
||||
/*
|
||||
* General Defines
|
||||
|
@ -35,6 +35,7 @@ static void add_link_defer ();
|
||||
static void writeout_other_defers ();
|
||||
static void writeout_final_defers();
|
||||
static void writeout_defered_file ();
|
||||
static int check_rdev ();
|
||||
|
||||
/* Write out header FILE_HDR, including the file name, to file
|
||||
descriptor OUT_DES. */
|
||||
@ -337,6 +338,21 @@ process_copy_out ()
|
||||
error (0, 0, "%s: file name too long", file_hdr.c_name);
|
||||
continue;
|
||||
}
|
||||
switch (check_rdev (&file_hdr))
|
||||
{
|
||||
case 1:
|
||||
error (0, 0, "%s not dumped: major number would be truncated",
|
||||
file_hdr.c_name);
|
||||
continue;
|
||||
case 2:
|
||||
error (0, 0, "%s not dumped: minor number would be truncated",
|
||||
file_hdr.c_name);
|
||||
continue;
|
||||
case 4:
|
||||
error (0, 0, "%s not dumped: device number would be truncated",
|
||||
file_hdr.c_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Copy the named file to the output. */
|
||||
switch (file_hdr.c_mode & CP_IFMT)
|
||||
@ -799,3 +815,98 @@ writeout_defered_file (header, out_file_des)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
check_rdev (file_hdr)
|
||||
struct new_cpio_header *file_hdr;
|
||||
{
|
||||
if (archive_format == arf_newascii || archive_format == arf_crcascii)
|
||||
{
|
||||
if ((file_hdr->c_rdev_maj & 0xFFFFFFFF) != file_hdr->c_rdev_maj)
|
||||
return 1;
|
||||
if ((file_hdr->c_rdev_min & 0xFFFFFFFF) != file_hdr->c_rdev_min)
|
||||
return 2;
|
||||
}
|
||||
else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
|
||||
{
|
||||
#ifndef __MSDOS__
|
||||
dev_t rdev;
|
||||
|
||||
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
||||
if (archive_format == arf_oldascii)
|
||||
{
|
||||
if ((rdev & 0xFFFF) != rdev)
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (file_hdr->c_mode & CP_IFMT)
|
||||
{
|
||||
case CP_IFCHR:
|
||||
case CP_IFBLK:
|
||||
#ifdef CP_IFSOCK
|
||||
case CP_IFSOCK:
|
||||
#endif
|
||||
#ifdef CP_IFIFO
|
||||
case CP_IFIFO:
|
||||
#endif
|
||||
/* We could handle one more bit if longs are >= 33 bits. */
|
||||
if ((rdev & 037777777777) != rdev)
|
||||
return 4;
|
||||
break;
|
||||
default:
|
||||
if ((rdev & 0xFFFF) != rdev)
|
||||
return 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
{
|
||||
/* The major and minor formats are limited to 7 octal digits in ustar
|
||||
format, and to_oct () adds a gratuitous trailing blank to further
|
||||
limit the format to 6 octal digits. */
|
||||
if ((file_hdr->c_rdev_maj & 0777777) != file_hdr->c_rdev_maj)
|
||||
return 1;
|
||||
if ((file_hdr->c_rdev_min & 0777777) != file_hdr->c_rdev_min)
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef __MSDOS__
|
||||
dev_t rdev;
|
||||
|
||||
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
||||
if (archive_format != arf_hpbinary)
|
||||
{
|
||||
if ((rdev & 0xFFFF) != rdev)
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (file_hdr->c_mode & CP_IFMT)
|
||||
{
|
||||
case CP_IFCHR:
|
||||
case CP_IFBLK:
|
||||
#ifdef CP_IFSOCK
|
||||
case CP_IFSOCK:
|
||||
#endif
|
||||
#ifdef CP_IFIFO
|
||||
case CP_IFIFO:
|
||||
#endif
|
||||
if ((rdev & 0xFFFFFFFF) != rdev)
|
||||
return 4;
|
||||
file_hdr->c_filesize = rdev;
|
||||
rdev = makedev (0, 1);
|
||||
break;
|
||||
default:
|
||||
if ((rdev & 0xFFFF) != rdev)
|
||||
return 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -875,10 +875,20 @@ dump_file (p, curdev, toplevel)
|
||||
#if defined(S_IFBLK) || defined(S_IFCHR)
|
||||
if (type != LF_FIFO)
|
||||
{
|
||||
to_oct ((long) major (hstat.st_rdev), 8,
|
||||
header->header.devmajor);
|
||||
to_oct ((long) minor (hstat.st_rdev), 8,
|
||||
header->header.devminor);
|
||||
if (checked_to_oct ((long) major (hstat.st_rdev), 8,
|
||||
header->header.devmajor))
|
||||
{
|
||||
msg ("%s: major number too large; not dumped", p);
|
||||
critical_error = 1;
|
||||
goto badfile;
|
||||
}
|
||||
if (checked_to_oct ((long) minor (hstat.st_rdev), 8,
|
||||
header->header.devminor))
|
||||
{
|
||||
msg ("%s: minor number too large; not dumped", p);
|
||||
critical_error = 1;
|
||||
goto badfile;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1396,6 +1406,22 @@ to_oct (value, digs, where)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call to_oct (), then return nonzero iff the conversion failed.
|
||||
*/
|
||||
int
|
||||
checked_to_oct (value, digs, where)
|
||||
register long value;
|
||||
register int digs;
|
||||
register char *where;
|
||||
{
|
||||
long from_oct ();
|
||||
|
||||
to_oct (value, digs, where);
|
||||
return from_oct (digs, where) != value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write the EOT record(s).
|
||||
* We actually zero at least one record, through the end of the block.
|
||||
|
@ -281,7 +281,7 @@ main (argc, argv)
|
||||
}
|
||||
if (f_volno_file)
|
||||
closeout_volume_number ();
|
||||
exit (errors);
|
||||
exit (errors ? EX_ARGSBAD : 0); /* FIXME (should be EX_NONDESCRIPT) */
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user