summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzoulasc <christos@zoulas.com>2020-02-10 19:43:32 -0500
committerzoulasc <christos@zoulas.com>2020-02-10 19:43:32 -0500
commit99e20e46c7561dae42be7fae3f561676e43fa1f5 (patch)
tree009d260fd81cfa0ac5e03eaf6900355a56afe326
parent15bd094e500991ee0dea46badb538fc75c91428f (diff)
downloadlibarchive-99e20e46c7561dae42be7fae3f561676e43fa1f5.tar.gz
Just like the hard link case, for symlinks we need to remove first
for ARCHIVE_EXTRACT_SAFE_WRITES.
-rw-r--r--libarchive/archive_write_disk_posix.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
index 63a5fc71..cc53a3d3 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -2306,6 +2306,13 @@ create_filesystem_object(struct archive_write_disk *a)
linkname = archive_entry_symlink(a->entry);
if (linkname != NULL) {
#if HAVE_SYMLINK
+ /*
+ * Unlinking and linking here is really not atomic,
+ * but doing it right, would require us to construct
+ * an mktempsymlink() function, and then use rename(2).
+ */
+ if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
+ unlink(a->name);
return symlink(linkname, a->name) ? errno : 0;
#else
return (EPERM);