diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2010-10-26 17:57:44 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2010-10-26 17:58:53 -0700 |
commit | e23d123b9326881803da64b1eb1e35fc0362e993 (patch) | |
tree | 571b2dc9841c10fa25bb79aa24a356f03dc3a675 | |
parent | 6398c7a79c88621453b0f312a5007414ead59843 (diff) | |
download | tar-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.c | 14 |
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) { |