Date: Fri, 21 May 2004 15:29:41 -0700 From: Tim Kientzle <tim@kientzle.com> To: Pete Carah <pete@altadena.net> Cc: current@freebsd.org Subject: Re: Tar problem Message-ID: <40AE82D5.6050403@kientzle.com> In-Reply-To: <20040521211712.GA80346@users.altadena.net> References: <20040521180520.GA79342@users.altadena.net> <40AE542F.1060905@freebsd.org> <20040521211712.GA80346@users.altadena.net>
next in thread | previous in thread | raw e-mail | index | archive | help
Pete Carah wrote: > On Fri, May 21, 2004 at 12:10:39PM -0700, Tim Kientzle wrote: >>Pete Carah wrote: >> >>>When I unpack the ports collection, the symlink >>>has been overwritten with the real directory >> >>This is deliberate; bsdtar does essentially the >>same thing. > >>o ... absolute pathnames. ... bsdtar removes the leading / ... >>o ... pathnames that include .. components. >>o ... exploit symbolic links to restore files to other directories. > GNU tar didn't do this a year or two ago... GNU tar was just one of many archiving programs that were recently reamed on a security forum for this type of problem. It has, of course, been stripping absolute paths for a long time. Consider, for example, a malicious FreeBSD package that happens to include one of the following: * A trojaned /bin/sh (stored with an absolute path) * A trojaned ../../../bin/sh (stored using ..) * A symlink bin -> /bin followed by a trojaned bin/sh * A symlink foo -> /bin/sh following by a trojaned foo A naive tar program would overwrite /bin/sh in any of these cases. Similar issues, of course, can arise with any tar, cpio, zip, or other archiving program that tries to properly handle symlinks. Both gtar and bsdtar try to provide default behavior that protects casual users from such malicious archives. One difficulty is that any tar program (in particular) must treat each entry extracted as a separate operation. So, if you create /usr/ports -> /other/ports, then tar is going to have to make a decision about each of the following as it extracts it: usr/ports (directory to be extracted) usr/ports/foo (file within that directory to be extracted) Any reasonably safe handling of symlinks will destroy the pre-existing symlink in the process of restoring one of these. If you know a strategy that doesn't, please let me know. (Preferably, a strategy that doesn't require keeping a list of every directory and/or symlink restored during the course of extraction.) Keeping track of a "top-level dir" isn't really an option, as there is no such concept within a tar archive. (Which is, of course, part of the problem.) The best way around this is to create the ports archive by: cd /usr/ports && tar cjf file.tbz * and restore it with: cd /usr/ports && tar xf file.tbz Then, the /usr/ports symlink is never inspected and you can redirect it however you want. Similar care can handle other problems with "top-level" symlinks. > And I may well want to accomplish the 2nd and 3rd (e.g. restore a > complete system image with symlinks containing .. chars...) (ln -s ../netscape-6/netscape > netscape in /usr/local/bin, for example... bsdtar certainly does not screen symlink contents, so this example would not be affected by the security checks. It will restore such symlinks; it just won't restore something else with a symlink as part of the path. I.e., you could not restore the symlink you describe and then restore a regular file called 'netscape'. (In this case, both gtar and bsdtar will simply remove the symlink and replace the file. If the symlink were an intermediate dir, gtar would remove it and create the intermediate dirs, bsdtar would refuse to extract the file.) > symlinks pointing to dirs and symlinks pointing to files > are qualitatively different ... Not really, no. I've constructed trojan tar archives that exploit both symlinks to files and symlinks to dirs to overwrite files outside of the target directory. I constructed these to test gtar's and bsdtar's security checks. > Also note that my complaint involves NONE of these; the ports collection archive contains > no symlinks. The symlink preexists and moves only the top-level directory... I suspect that gtar and bsdtar would both end up doing the same thing, even though they would get there in slightly different ways. For bsdtar, the key is that the "top-level directory" is being restored by the archive, so the existing symlink will get deleted and replaced with a real directory. > The only completely secure way ... is to remove symlinks from the system entirely ... Noone's suggesting that. But, symlinks can be used to fool unsuspecting users and, as such, need to be handled carefully. The tricky part is finding a good balance between safety and flexibility that feels "natural" to as many people as possible. > And tar doesn't always handle hardlinks right either... (e.g. - a hardlink on the source system which crosses > a filesystem boundary on the target. What tar does here is restore multiple copies. > A sysadmin would usually apply a symlink here instead...) Good point. Right now, I think bsdtar simply fails to restore the hardlink. Converting it to a symlink is an interesting idea, though it carries risks as well. Duplicating the file is arguably less risky. (Hardlinks are symmetric and have the property that deleting one link does not affect the other links. Symlinks are not symmetric; tar cannot be expected to guess which copy should be kept and which converted to symlinks.) > And the gtar behavior changed from historical without > explanation or notice... in either the (unofficial) man > page or the (more official) info If you would like to submit some diffs to the gtar.1 man page, I'd be happy to commit them. I can't speak to other gtar issues, though, as I'm (for obvious reasons) trying hard to avoid reading gtar source. Tim
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?40AE82D5.6050403>