Woes of absolute path names in tar

anw at nott-cs.UUCP anw at nott-cs.UUCP
Sat Jun 4 04:22:42 AEST 1988


Many years ago, some kind soul [may even have been me, :-(, I tend to forget
such things] installed a shell script on our PDP 11 [probably when it was a
34 running V6, perhaps when it was a 70 running V7 -- now it's a 44 running
V7, gloom] to copy file hierarchies.  Well, time passes;  and as the discs
fill up, I archive elderly subdirectories:

		copy old-dir /nicedisc/anw/archive
		: check that all is well, then ...
		rm -rf old-dir

Repeat as necessary.  More time passes.  Yesterday, we re-organised our
discs a bit, and suddenly there is oodles of space around my home directory.
Wouldn't it be nice to get all that stuff back in the right place?

		mkdir old-dir
		copy /nicedisc/anw/archive old-dir
		: Aaarrrggghhh!  Lots of error messages

Yikes!  Look in the archive directory.  Funny, all those files are still there,
and "ls -l" shows they haven't been altered, but "cat" one or two, and they're
empty.  More tests -- they aren't actually empty, they've been NULlified.
All my beloved old files!  Hope this wasn't too long ago, might not be able
to find a useful dump tape.  Phew, they are on that morning's dump tape, all
correct, and 10 mins later my sanity and the files are restored.

	What happened?  Well, you've guessed from the "Subject:" line, but I
had to scrat around for a bit.  Here is "/usr/bin/copy", as was:

		echo copying from $1 to $2
		tar cvf - $1 | (cd $2; tar xfp -)

[I don't think this is my code, even from 10 years ago, if only 'cos I
always put quotes around parameters.  Well, nearly always.]  Someone has
been reading the "tar" manual entry;  but this is disastrous.  If "$1"
begins with "/", the right-hand "tar" overwrites the directory the left-
hand "tar" is reading from, zapping most of the files, but restoring the
modified times, etc., with potentially terrible consequences, as I found out.
There are other bugs as well, but to cut a long story short, "/usr/bin/copy"
*now* looks like this:

	error () { echo $0: "$@" 1>&2; exit 1; }

	case $# in
		0)	echo usage: $0 fromdir todir; exit 0 ;;
		1)	error must supply target directory ;;
		2)	;;
		*)	error too many parameters
	esac

	[ -d "$1" -a -d "$2" ] ||
		error parameters must be existing directories

	case "$1" in
		/*)	error first param must not begin with /
	esac

	FROM=`(cd "$1"; pwd)`
	TO=`(cd "$2"; pwd)`
	case "$TO" in
		"$FROM")	error must not copy directory to itself ;;
		"$FROM"/*)	error must not copy directory to sub-dir
	esac

	echo copying from "$1" to "$2"
	sleep 10
	tar cvf - "$1" | (cd "$2"; tar xfp -)

Still not perfect, but at least somewhat safer.  And the morals are:
	a) Good dumping strategies are essential.
	b) Even your most ancient and trusted tools can suddenly bite you.
	c) Those of you with whizzo "cpio"s, and other bells and whistles,
	   and much more careful "tar"s, and Suns, and Crays, and what
	   have-you, please spare a thought for your less fortunate
	   brethren and cistern.
I'd better stop before I get too "comp.RISK"-ish.  Thank you for listening.

-- 
Andy Walker, Maths Dept., Nott'm Univ., UK
anw at maths.nott.ac.uk



More information about the Comp.unix.wizards mailing list