diff options
author | kris <kris@FreeBSD.org> | 2001-05-30 20:35:44 +0000 |
---|---|---|
committer | kris <kris@FreeBSD.org> | 2001-05-30 20:35:44 +0000 |
commit | 187932cd937f1c63f7b2e4d6bab7c799f8e55a76 (patch) | |
tree | 91c93549218d29ba51d61b0a5c43df0631a0bc92 /lib/libc/gen/fts.c | |
parent | 3322ac29631ab8a7870f51437abae91528a4158f (diff) | |
download | FreeBSD-src-187932cd937f1c63f7b2e4d6bab7c799f8e55a76.zip FreeBSD-src-187932cd937f1c63f7b2e4d6bab7c799f8e55a76.tar.gz |
When doing the chdir("..") in the !FTS_NOCHDIR case, stat() after we get
there and compare the inode and device numbers to the values we remember,
to guard against the directory having been moved around in the meantime.
Reported by: Nick Cleaton <nick@cleaton.net>
Diffstat (limited to 'lib/libc/gen/fts.c')
-rw-r--r-- | lib/libc/gen/fts.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c index c6b09ff..72e0c4d 100644 --- a/lib/libc/gen/fts.c +++ b/lib/libc/gen/fts.c @@ -44,6 +44,7 @@ static char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" +#include <sys/types.h> #include <sys/param.h> #include <sys/stat.h> @@ -278,6 +279,7 @@ fts_read(sp) register FTS *sp; { register FTSENT *p, *tmp; + struct stat sb; register int instr; register char *t; int saved_errno; @@ -451,10 +453,22 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); return (NULL); } (void)_close(p->fts_symfd); - } else if (!(p->fts_flags & FTS_DONTCHDIR)) { - if (CHDIR(sp, "..")) { + } else if (!(p->fts_flags & FTS_DONTCHDIR) && + !ISSET(FTS_NOCHDIR)) { + if (chdir("..")) { + SET(FTS_STOP); + return (NULL); + } + if (stat(".", &sb) == -1) { SET(FTS_STOP); return (NULL); + } else { + if (sb.st_ino != p->fts_parent->fts_ino || + sb.st_dev != p->fts_parent->fts_dev) { + errno = ENOENT; + SET(FTS_STOP); + return (NULL); + } } } p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; |