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);
 

Reply via email to