diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1996-12-23 04:58:35 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1996-12-23 04:58:35 +0000 |
commit | a76a180c215d4d3a3db8f60d8c72293936444932 (patch) | |
tree | be5ca2642c29c7cc440bc2ddb5406365b341b73d /lib/libc | |
parent | 46a983d393e46db3b4911dfe8263016c647d8d8a (diff) |
Avoid spoofing when cd'ing to subdirs. First cut.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/fts.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c index 9aa05381a21..99902818f32 100644 --- a/lib/libc/gen/fts.c +++ b/lib/libc/gen/fts.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: fts.c,v 1.2 1996/08/19 08:22:59 tholo Exp $"; +static char rcsid[] = "$OpenBSD: fts.c,v 1.3 1996/12/23 04:58:34 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -336,12 +336,30 @@ fts_read(sp) * FTS_STOP or the fts_info field of the node. */ if (sp->fts_child) { - if (CHDIR(sp, p->fts_accpath)) { - p->fts_errno = errno; - p->fts_flags |= FTS_DONTCHDIR; - for (p = sp->fts_child; p; p = p->fts_link) - p->fts_accpath = - p->fts_parent->fts_accpath; + if (!ISSET(FTS_NOCHDIR)) { + struct stat *parent1, *fts_statp2, *parent2; + int ret; + + /* XXX - make readable somehow */ + if (!ISSET(FTS_NOSTAT) && !ISSET(FTS_LOGICAL)) + ret = ((lstat(".", parent1) != 0) || + (chdir(p->fts_accpath) != 0) || + (lstat(".", fts_statp2) != 0) || + (lstat("..", parent2) != 0) || + (p->fts_dev != fts_statp2->st_dev) || + (p->fts_ino != fts_statp2->st_ino) || + (parent1->st_dev != parent2->st_dev) || + (parent1->st_ino != parent2->st_ino)); + else + ret = chdir(p->fts_accpath); + + if (ret) { + p->fts_errno = errno; + p->fts_flags |= FTS_DONTCHDIR; + for (p = sp->fts_child; p; p = p->fts_link) + p->fts_accpath = + p->fts_parent->fts_accpath; + } } } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { if (ISSET(FTS_STOP)) |