Author: jilles
Date: Sat Apr  4 20:22:12 2015
New Revision: 281082
URL: https://svnweb.freebsd.org/changeset/base/281082

Log:
  fts: Don't return FTS_SLNONE if it's not a symlink (if race).
  
  When following symlinks, fts returned FTS_SLNONE when fstatat(flag=0)
  failed, but a subsequent fstatat(flag=AT_SYMLINK_NOFOLLOW) succeeded. This
  incorrectly triggered if a filename existed to be read from the directory,
  was deleted before the fstatat(flag=0) and created again after the
  fstatat(flag=0).
  
  Fix this by only returning FTS_SLNONE if the result from
  fstatat(flag=AT_SYMLINK_NOFOLLOW) is actually a symlink. If it is not a
  symlink, treat it as if fstatat(flag=0) succeeded.
  
  PR:           196724
  Reported and tested by:       pho
  MFC after:    1 week

Modified:
  head/lib/libc/gen/fts.c

Modified: head/lib/libc/gen/fts.c
==============================================================================
--- head/lib/libc/gen/fts.c     Sat Apr  4 19:56:54 2015        (r281081)
+++ head/lib/libc/gen/fts.c     Sat Apr  4 20:22:12 2015        (r281082)
@@ -905,12 +905,13 @@ fts_stat(FTS *sp, FTSENT *p, int follow,
        if (ISSET(FTS_LOGICAL) || follow) {
                if (fstatat(dfd, path, sbp, 0)) {
                        saved_errno = errno;
-                       if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {
-                               errno = 0;
-                               return (FTS_SLNONE);
+                       if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {
+                               p->fts_errno = saved_errno;
+                               goto err;
                        }
-                       p->fts_errno = saved_errno;
-                       goto err;
+                       errno = 0;
+                       if (S_ISLNK(sbp->st_mode))
+                               return (FTS_SLNONE);
                }
        } else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {
                p->fts_errno = errno;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to