diff options
author | kientzle <kientzle@FreeBSD.org> | 2008-09-07 05:22:33 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2008-09-07 05:22:33 +0000 |
commit | 02ce672bbc07905ebf44d957200a6c633201dee0 (patch) | |
tree | df85ea1bd1ac4ccee68e04cd8ab5d3e7c64d03f8 /lib/libarchive/archive_write_disk.c | |
parent | 5272b43e206a1641c3638e71e7068d76e9eaf194 (diff) | |
download | FreeBSD-src-02ce672bbc07905ebf44d957200a6c633201dee0.zip FreeBSD-src-02ce672bbc07905ebf44d957200a6c633201dee0.tar.gz |
When restoring a directory, allow symlinks to be followed. The full
logic here gets a little complex, but the net effect is that the
SECURE_SYMLINKS flag will prevent us from ever following a symlink.
Without it, we'll only follow symlinks to dirs. bsdtar specifies
SECURE_SYMLINKS by default, suppresses it for -P.
I've also beefed up the write_disk_secure test to verify this
behavior.
PR: bin/126849
Diffstat (limited to 'lib/libarchive/archive_write_disk.c')
-rw-r--r-- | lib/libarchive/archive_write_disk.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c index b7313bc..b63a7b7 100644 --- a/lib/libarchive/archive_write_disk.c +++ b/lib/libarchive/archive_write_disk.c @@ -907,14 +907,26 @@ restore_entry(struct archive_write_disk *a) * We know something is in the way, but we don't know what; * we need to find out before we go any further. */ - if (lstat(a->name, &a->st) != 0) { + int r = 0; + /* + * The SECURE_SYMLINK logic has already removed a + * symlink to a dir if the client wants that. So + * follow the symlink if we're creating a dir. + */ + if (S_ISDIR(a->mode)) + r = stat(a->name, &a->st); + /* + * If it's not a dir (or it's a broken symlink), + * then don't follow it. + */ + if (r != 0 || !S_ISDIR(a->mode)) + r = lstat(a->name, &a->st); + if (r != 0) { archive_set_error(&a->archive, errno, "Can't stat existing object"); return (ARCHIVE_WARN); } - /* TODO: if it's a symlink... */ - /* * NO_OVERWRITE_NEWER doesn't apply to directories. */ |