Module Name: src
Committed By: manu
Date: Thu Jan 29 15:55:22 UTC 2015
Modified Files:
src/lib/libc/gen: fts.c
Log Message:
Fix double free in fts_read()/fts_close()
When fts_read() gets an error on fchdir(), it exited with sp->fts_cur
set to a freed structure. fts_close() would later attempt to free it
again, crashing the program.
To generate a diff of this commit:
cvs rdiff -u -r1.47 -r1.48 src/lib/libc/gen/fts.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/gen/fts.c
diff -u src/lib/libc/gen/fts.c:1.47 src/lib/libc/gen/fts.c:1.48
--- src/lib/libc/gen/fts.c:1.47 Thu Sep 18 13:58:20 2014
+++ src/lib/libc/gen/fts.c Thu Jan 29 15:55:21 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: fts.c,v 1.47 2014/09/18 13:58:20 christos Exp $ */
+/* $NetBSD: fts.c,v 1.48 2015/01/29 15:55:21 manu Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
#else
-__RCSID("$NetBSD: fts.c,v 1.47 2014/09/18 13:58:20 christos Exp $");
+__RCSID("$NetBSD: fts.c,v 1.48 2015/01/29 15:55:21 manu Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -430,8 +430,19 @@ fts_read(FTS *sp)
goto name;
}
+next:
/* Move to the next node on this level. */
-next: tmp = p;
+ tmp = p;
+
+ /*
+ * We are going to free sp->fts_cur, set it to NULL so
+ * that fts_close() does not attempt to free it again
+ * if we exit without setting it to a new value because
+ * FCHDIR() failed below.
+ */
+ assert(tmp == sp->fts_cur);
+ sp->fts_cur = NULL;
+
if ((p = p->fts_link) != NULL) {
fts_free(tmp);