summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1996-12-23 04:58:35 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1996-12-23 04:58:35 +0000
commita76a180c215d4d3a3db8f60d8c72293936444932 (patch)
treebe5ca2642c29c7cc440bc2ddb5406365b341b73d /lib/libc
parent46a983d393e46db3b4911dfe8263016c647d8d8a (diff)
Avoid spoofing when cd'ing to subdirs. First cut.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/fts.c32
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))