Module Name:    src
Committed By:   elad
Date:           Mon Dec 28 07:16:41 UTC 2009

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

Log Message:
In veriexec_file_verify(), always check 'lockstate' before unlocking
'veriexec_op_lock'. Triggering a panic is possible in the path from
veriexec_openchk() (easily repeatable). The two switch cases at the
bottom of the function are going to panic anyway, but they might as well
panic as they're intended to as opposed to tripping over a locking
violation...


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 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.120 src/sys/kern/kern_verifiedexec.c:1.121
--- src/sys/kern/kern_verifiedexec.c:1.120	Mon Dec 28 02:35:20 2009
+++ src/sys/kern/kern_verifiedexec.c	Mon Dec 28 07:16:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_verifiedexec.c,v 1.120 2009/12/28 02:35:20 elad Exp $	*/
+/*	$NetBSD: kern_verifiedexec.c,v 1.121 2009/12/28 07:16:41 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.120 2009/12/28 02:35:20 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.121 2009/12/28 07:16:41 elad Exp $");
 
 #include "opt_veriexec.h"
 
@@ -629,7 +629,8 @@
 			    name, NULL, REPORT_ALWAYS);
 			kmem_free(digest, vfe->ops->hash_len);
 			rw_exit(&vfe->lock);
-			rw_exit(&veriexec_op_lock);
+			if (lockstate == VERIEXEC_UNLOCKED)
+				rw_exit(&veriexec_op_lock);
 			return (error);
 		}
 
@@ -650,7 +651,8 @@
 		/* IPS mode: Enforce access type. */
 		if (veriexec_strict >= VERIEXEC_IPS) {
 			rw_exit(&vfe->lock);
-			rw_exit(&veriexec_op_lock);
+			if (lockstate == VERIEXEC_UNLOCKED)
+				rw_exit(&veriexec_op_lock);
 			return (EPERM);
 		}
 	}
@@ -679,7 +681,8 @@
 	case FINGERPRINT_NOTEVAL:
 		/* Should not happen. */
 		rw_exit(&vfe->lock);
-		rw_exit(&veriexec_op_lock);
+		if (lockstate == VERIEXEC_UNLOCKED)
+			rw_exit(&veriexec_op_lock);
 		veriexec_file_report(vfe, "Not-evaluated status "
 		    "post evaluation; inconsistency detected.", name,
 		    NULL, REPORT_ALWAYS|REPORT_PANIC);
@@ -709,7 +712,8 @@
 	default:
 		/* Should never happen. */
 		rw_exit(&vfe->lock);
-		rw_exit(&veriexec_op_lock);
+		if (lockstate == VERIEXEC_UNLOCKED)
+			rw_exit(&veriexec_op_lock);
 		veriexec_file_report(vfe, "Invalid status "
 		    "post evaluation.", name, NULL, REPORT_ALWAYS|REPORT_PANIC);
         }

Reply via email to