diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1997-01-17 06:12:54 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1997-01-17 06:12:54 +0000 |
commit | 67b7a2410740e1bc7fdf400da6a38852de5ebe39 (patch) | |
tree | fd4785cec8fff552e64ac443f943d156973f1bcc | |
parent | 0ea1c6aba679ac47f9349d0bb53c79010d4a31a5 (diff) |
Final fix to make fts(3) spoof-proof.
-rw-r--r-- | lib/libc/gen/fts.c | 148 |
1 files changed, 76 insertions, 72 deletions
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c index 6f9507390cd..d2bf1bc65fb 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.5 1997/01/14 01:02:42 millert Exp $"; +static char rcsid[] = "$OpenBSD: fts.c,v 1.6 1997/01/17 06:12:53 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -628,6 +628,8 @@ fts_build(sp, type) cur->fts_flags |= FTS_DONTCHDIR; descend = 0; cderrno = errno; + (void)closedir(dirp); + dirp = NULL; } else descend = 1; else @@ -654,85 +656,87 @@ fts_build(sp, type) /* Read the directory, attaching each entry to the `link' pointer. */ adjaddr = NULL; - for (head = tail = NULL, nitems = 0; dp = readdir(dirp);) { - if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) - continue; - - if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL) - goto mem1; - if (dp->d_namlen > maxlen) { - if (fts_palloc(sp, (size_t)dp->d_namlen)) { - /* - * No more memory for path or structures. Save - * errno, free up the current structure and the - * structures already allocated. - */ -mem1: saved_errno = errno; - if (p) - free(p); - fts_lfree(head); - (void)closedir(dirp); - errno = saved_errno; - cur->fts_info = FTS_ERR; - SET(FTS_STOP); - return (NULL); + if (dirp) { + for (head = tail = NULL, nitems = 0; dp = readdir(dirp);) { + if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) + continue; + + if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL) + goto mem1; + if (dp->d_namlen > maxlen) { + if (fts_palloc(sp, (size_t)dp->d_namlen)) { + /* + * No more memory for path or structures. Save + * errno, free up the current structure and the + * structures already allocated. + */ + mem1: saved_errno = errno; + if (p) + free(p); + fts_lfree(head); + (void)closedir(dirp); + errno = saved_errno; + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + return (NULL); + } + adjaddr = sp->fts_path; + maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1; } - adjaddr = sp->fts_path; - maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1; - } - p->fts_pathlen = len + dp->d_namlen + 1; - p->fts_parent = sp->fts_cur; - p->fts_level = level; + p->fts_pathlen = len + dp->d_namlen + 1; + p->fts_parent = sp->fts_cur; + p->fts_level = level; -#ifdef FTS_WHITEOUT - if (dp->d_type == DT_WHT) - p->fts_flags |= FTS_ISW; -#endif + #ifdef FTS_WHITEOUT + if (dp->d_type == DT_WHT) + p->fts_flags |= FTS_ISW; + #endif - if (cderrno) { - if (nlinks) { - p->fts_info = FTS_NS; - p->fts_errno = cderrno; - } else + if (cderrno) { + if (nlinks) { + p->fts_info = FTS_NS; + p->fts_errno = cderrno; + } else + p->fts_info = FTS_NSOK; + p->fts_accpath = cur->fts_accpath; + } else if (nlinks == 0 + #ifdef DT_DIR + || nostat && + dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN + #endif + ) { + p->fts_accpath = + ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; p->fts_info = FTS_NSOK; - p->fts_accpath = cur->fts_accpath; - } else if (nlinks == 0 -#ifdef DT_DIR - || nostat && - dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN -#endif - ) { - p->fts_accpath = - ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; - p->fts_info = FTS_NSOK; - } else { - /* Build a file name for fts_stat to stat. */ - if (ISSET(FTS_NOCHDIR)) { - p->fts_accpath = p->fts_path; - memmove(cp, p->fts_name, p->fts_namelen + 1); - } else - p->fts_accpath = p->fts_name; - /* Stat it. */ - p->fts_info = fts_stat(sp, p, 0); - - /* Decrement link count if applicable. */ - if (nlinks > 0 && (p->fts_info == FTS_D || - p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) - --nlinks; - } + } else { + /* Build a file name for fts_stat to stat. */ + if (ISSET(FTS_NOCHDIR)) { + p->fts_accpath = p->fts_path; + memmove(cp, p->fts_name, p->fts_namelen + 1); + } else + p->fts_accpath = p->fts_name; + /* Stat it. */ + p->fts_info = fts_stat(sp, p, 0); + + /* Decrement link count if applicable. */ + if (nlinks > 0 && (p->fts_info == FTS_D || + p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) + --nlinks; + } - /* We walk in directory order so "ls -f" doesn't get upset. */ - p->fts_link = NULL; - if (head == NULL) - head = tail = p; - else { - tail->fts_link = p; - tail = p; + /* We walk in directory order so "ls -f" doesn't get upset. */ + p->fts_link = NULL; + if (head == NULL) + head = tail = p; + else { + tail->fts_link = p; + tail = p; + } + ++nitems; } - ++nitems; + (void)closedir(dirp); } - (void)closedir(dirp); /* * If had to realloc the path, adjust the addresses for the rest |