]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(fts_read): When about to fail (by returning NULL) due
authorJim Meyering <jim@meyering.net>
Wed, 13 Oct 2004 19:25:30 +0000 (19:25 +0000)
committerJim Meyering <jim@meyering.net>
Wed, 13 Oct 2004 19:25:30 +0000 (19:25 +0000)
to a failed fchdir or failed fts_safe_changedir call, set
`sp->fts_cur = p'.  Do this by removing the explicit `return NULL;'
statements and setting p->fts_errno so execution falls through
to the common-case code below.  Otherwise, after such a failure,
calling fts_close would attempt to free an already-freed buffer.
Reported by Luis Lopez Lopez in http://bugs.debian.org/276352.

lib/fts.c

index 32b82f5ea7c50d8dc930cd9170668cc7df5aad98..00be3d2cc9e383e0c28e88abe9cd0248d0d0bb40 100644 (file)
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -716,27 +716,28 @@ name:             t = sp->fts_path + NAPPEND(p->fts_parent);
         */
        if (p->fts_level == FTS_ROOTLEVEL) {
                if (FCHDIR(sp, sp->fts_rfd)) {
+                       p->fts_errno = errno;
                        SET(FTS_STOP);
-                       return (NULL);
                }
        } else if (p->fts_flags & FTS_SYMFOLLOW) {
                if (FCHDIR(sp, p->fts_symfd)) {
                        saved_errno = errno;
                        (void)close(p->fts_symfd);
                        __set_errno (saved_errno);
+                       p->fts_errno = errno;
                        SET(FTS_STOP);
-                       return (NULL);
                }
                (void)close(p->fts_symfd);
        } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
                   fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+               p->fts_errno = errno;
                SET(FTS_STOP);
-               return (NULL);
        }
        p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
        if (p->fts_errno == 0)
                LEAVE_DIR (sp, p, "3");
-       return (sp->fts_cur = p);
+       sp->fts_cur = p;
+       return ISSET(FTS_STOP) ? NULL : p;
 }
 
 /*