Module Name:    src
Committed By:   elad
Date:           Sat May  2 21:47:12 UTC 2009

Modified Files:
        src/sys/kern: kern_verifiedexec.c

Log Message:
Fix locking around mountlist usage, as pointed out by ad@ in:

  http://mail-index.netbsd.org/source-changes-d/2009/04/22/msg000322.html
  http://mail-index.netbsd.org/tech-kern/2009/04/22/msg004897.html

Use vfs_busy() and vfs_unbusy(), and properly iterate the mountlist.


To generate a diff of this commit:
cvs rdiff -u -r1.113 -r1.114 src/sys/kern/kern_verifiedexec.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_verifiedexec.c
diff -u src/sys/kern/kern_verifiedexec.c:1.113 src/sys/kern/kern_verifiedexec.c:1.114
--- src/sys/kern/kern_verifiedexec.c:1.113	Mon Apr 20 22:09:54 2009
+++ src/sys/kern/kern_verifiedexec.c	Sat May  2 21:47:12 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_verifiedexec.c,v 1.113 2009/04/20 22:09:54 elad Exp $	*/
+/*	$NetBSD: kern_verifiedexec.c,v 1.114 2009/05/02 21:47:12 elad Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2006 Elad Efrat <e...@netbsd.org>
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.113 2009/04/20 22:09:54 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.114 2009/05/02 21:47:12 elad Exp $");
 
 #include "opt_veriexec.h"
 
@@ -1535,12 +1535,19 @@
 int
 veriexec_dump(struct lwp *l, prop_array_t rarray)
 {
-	struct mount *mp;
+	struct mount *mp, *nmp;
 
 	mutex_enter(&mountlist_lock);
-	CIRCLEQ_FOREACH(mp, &mountlist, mnt_list) {
+	for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
+	    mp = nmp) {
+		/* If it fails, the file-system is [being] unmounted. */
+		if (vfs_busy(mp, &nmp) != 0)
+			continue;
+
 		fileassoc_table_run(mp, veriexec_hook,
 		    (fileassoc_cb_t)veriexec_file_dump, rarray);
+
+		vfs_unbusy(mp, false, &nmp);
 	}
 	mutex_exit(&mountlist_lock);
 
@@ -1550,16 +1557,23 @@
 int
 veriexec_flush(struct lwp *l)
 {
-	struct mount *mp;
+	struct mount *mp, *nmp;
 	int error = 0;
 
 	mutex_enter(&mountlist_lock);
-	CIRCLEQ_FOREACH(mp, &mountlist, mnt_list) {
+	for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
+	    mp = nmp) {
 		int lerror;
 
+		/* If it fails, the file-system is [being] unmounted. */
+		if (vfs_busy(mp, &nmp) != 0)
+			continue;
+
 		lerror = veriexec_table_delete(l, mp);
 		if (lerror && lerror != ENOENT)
 			error = lerror;
+
+		vfs_unbusy(mp, false, &nmp);
 	}
 	mutex_exit(&mountlist_lock);
 

Reply via email to