mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-29 11:54:38 +01:00
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
This commit is contained in:
1 parent
5abd1a7c31
commit
bf4374c545
1 file changed
+6
-5
+6
-5
@@ -905,12 +905,13 @@ fts_stat(FTS *sp, FTSENT *p, int follow, int dfd)
|
||||
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;
|
||||
|
||||
Reference in new issue
Block a user