Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern In veriexec_file_verify(), always check 'lockstate'...



details:   https://anonhg.NetBSD.org/src/rev/6dc072a2c832
branches:  trunk
changeset: 750364:6dc072a2c832
user:      elad <elad%NetBSD.org@localhost>
date:      Mon Dec 28 07:16:41 2009 +0000

description:
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...

diffstat:

 sys/kern/kern_verifiedexec.c |  16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

diffs (58 lines):

diff -r 658cc755f35f -r 6dc072a2c832 sys/kern/kern_verifiedexec.c
--- a/sys/kern/kern_verifiedexec.c      Mon Dec 28 03:22:19 2009 +0000
+++ b/sys/kern/kern_verifiedexec.c      Mon Dec 28 07:16:41 2009 +0000
@@ -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 <elad%NetBSD.org@localhost>
@@ -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);
         }



Home | Main Index | Thread Index | Old Index