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>
This commit is contained in:
Kris Kennaway 2001-05-30 20:35:44 +00:00
parent f8fb1acb36
commit fdeb0156dd
2 changed files with 32 additions and 4 deletions

View File

@ -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,11 +453,23 @@ 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;
return (sp->fts_cur = p);

View File

@ -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,11 +453,23 @@ 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;
return (sp->fts_cur = p);