summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2010-10-26 17:57:44 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2010-10-26 17:58:53 -0700
commite23d123b9326881803da64b1eb1e35fc0362e993 (patch)
tree571b2dc9841c10fa25bb79aa24a356f03dc3a675
parent6398c7a79c88621453b0f312a5007414ead59843 (diff)
downloadtar-e23d123b9326881803da64b1eb1e35fc0362e993.tar.gz
tar: fix -x --overwrite bug (no --dereference, ! O_NOFOLLOW)
This bug was discovered on Solaris 8. On older hosts lacking O_NOFOLLOW, tar -x --overwrite (without --dereference) follows symbolic links, causing the "extract over symlinks" test to fail. * src/extract.c (open_output_file): If O_NOFOLLOW is needed but does not work, check for a symlink separately.
-rw-r--r--src/extract.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/extract.c b/src/extract.c
index 98236aca..44233b9e 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -864,6 +864,20 @@ open_output_file (char const *file_name, int typeflag, mode_t mode,
}
}
+ /* If O_NOFOLLOW is needed but does not work, check for a symlink
+ separately. There's a race condition, but that cannot be avoided
+ on hosts lacking O_NOFOLLOW. */
+ if (! O_NOFOLLOW && overwriting_old_files && ! dereference_option)
+ {
+ struct stat st;
+ if (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0
+ && S_ISLNK (st.st_mode))
+ {
+ errno = ELOOP;
+ return -1;
+ }
+ }
+
fd = openat (chdir_fd, file_name, openflag, mode);
if (0 <= fd)
{