summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/fts-compat.c
diff options
context:
space:
mode:
authorkris <kris@FreeBSD.org>2001-05-30 20:35:44 +0000
committerkris <kris@FreeBSD.org>2001-05-30 20:35:44 +0000
commit187932cd937f1c63f7b2e4d6bab7c799f8e55a76 (patch)
tree91c93549218d29ba51d61b0a5c43df0631a0bc92 /lib/libc/gen/fts-compat.c
parent3322ac29631ab8a7870f51437abae91528a4158f (diff)
downloadFreeBSD-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-compat.c')
-rw-r--r--lib/libc/gen/fts-compat.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/libc/gen/fts-compat.c b/lib/libc/gen/fts-compat.c
index c6b09ff..72e0c4d 100644
--- a/lib/libc/gen/fts-compat.c
+++ b/lib/libc/gen/fts-compat.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;
OpenPOWER on IntegriCloud