diff options
Diffstat (limited to 'gnu/usr.bin/tar')
-rw-r--r-- | gnu/usr.bin/tar/create.c | 34 | ||||
-rw-r--r-- | gnu/usr.bin/tar/tar.c | 2 |
2 files changed, 31 insertions, 5 deletions
diff --git a/gnu/usr.bin/tar/create.c b/gnu/usr.bin/tar/create.c index 5d1b71c..c3be00c 100644 --- a/gnu/usr.bin/tar/create.c +++ b/gnu/usr.bin/tar/create.c @@ -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 @@ -1397,6 +1407,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. * Old tar writes garbage after two zeroed records -- and PDtar used to. diff --git a/gnu/usr.bin/tar/tar.c b/gnu/usr.bin/tar/tar.c index 6385986..84e2b94 100644 --- a/gnu/usr.bin/tar/tar.c +++ b/gnu/usr.bin/tar/tar.c @@ -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 */ } |