summaryrefslogtreecommitdiffstats
path: root/usr.bin/tar
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2004-06-07 04:10:43 +0000
committerkientzle <kientzle@FreeBSD.org>2004-06-07 04:10:43 +0000
commit0769b9f0d649d685716fbd042d363777f72c4127 (patch)
tree4480b4da4ad89c124e9c82e817fb863546302db1 /usr.bin/tar
parent42e3d5a6499e714d6a10fc6909834c261e418bc5 (diff)
downloadFreeBSD-src-0769b9f0d649d685716fbd042d363777f72c4127.zip
FreeBSD-src-0769b9f0d649d685716fbd042d363777f72c4127.tar.gz
Fix the symlink-detection code. Don't squawk if we're just replacing
an existing symlink (as might happen if you extract an archive twice). Also, if we remove the offending link, then we've removed the problem and can safely go forward with the extraction. Pointed out by: print/adobe-cmaps port (whose distfile has duplicate entries for the same symlinks) Thanks to: Kris Kennaway (for using ports as a testbed for bsdtar)
Diffstat (limited to 'usr.bin/tar')
-rw-r--r--usr.bin/tar/read.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/usr.bin/tar/read.c b/usr.bin/tar/read.c
index db34fd5..d6532f3 100644
--- a/usr.bin/tar/read.c
+++ b/usr.bin/tar/read.c
@@ -315,10 +315,12 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry)
if (name[0] == '/') {
/* Generate a warning the first time this happens. */
if (!bsdtar->warned_lead_slash) {
- bsdtar_warnc(bsdtar, 0, "Removing leading '/' from member names");
+ bsdtar_warnc(bsdtar, 0,
+ "Removing leading '/' from member names");
bsdtar->warned_lead_slash = 1;
}
- name++;
+ while (name[0] == '/')
+ name++;
archive_entry_set_pathname(entry, name);
}
@@ -329,6 +331,7 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry)
(pn[2] == '\0' || pn[2] == '/')) {
bsdtar_warnc(bsdtar, 0,
"Skipping pathname containing ..");
+ bsdtar->return_value = 1;
return (1);
}
pn = strchr(pn, '/');
@@ -367,11 +370,23 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry)
break;
} else if (S_ISLNK(st.st_mode)) {
if (pn[0] == '\0') {
- /* Last element is symlink; just remove it. */
- bsdtar_warnc(bsdtar, 0, "Removing symlink %s",
- bsdtar->security->path);
+ /*
+ * Last element is symlink; remove it
+ * so we can overwrite it with the
+ * item being extracted.
+ */
+ if (!S_ISLNK(archive_entry_mode(entry))) {
+ /*
+ * Warn only if the symlink is being
+ * replaced with a non-symlink.
+ */
+ bsdtar_warnc(bsdtar, 0,
+ "Removing symlink %s",
+ bsdtar->security->path);
+ }
unlink(bsdtar->security->path);
- return (1);
+ /* Symlink gone. No more problem! */
+ return (0);
} else if (bsdtar->option_unlink_first) {
/* User asked us to remove problems. */
unlink(bsdtar->security->path);
@@ -379,6 +394,7 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry)
bsdtar_warnc(bsdtar, 0,
"Cannot extract %s through symlink %s",
name, bsdtar->security->path);
+ bsdtar->return_value = 1;
return (1);
}
}
OpenPOWER on IntegriCloud