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