summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1997-01-17 06:12:54 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1997-01-17 06:12:54 +0000
commit67b7a2410740e1bc7fdf400da6a38852de5ebe39 (patch)
treefd4785cec8fff552e64ac443f943d156973f1bcc
parent0ea1c6aba679ac47f9349d0bb53c79010d4a31a5 (diff)
Final fix to make fts(3) spoof-proof.
-rw-r--r--lib/libc/gen/fts.c148
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