Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Don't mix veriexec lock and file lock in veriexec_f...
details: https://anonhg.NetBSD.org/src/rev/ff2c15466e11
branches: trunk
changeset: 337724:ff2c15466e11
user: maxv <maxv%NetBSD.org@localhost>
date: Sat Apr 25 09:08:51 2015 +0000
description:
Don't mix veriexec lock and file lock in veriexec_file_verify().
Now:
- 'veriexec_op_lock' needs to be held when calling veriexec_file_verify()
- the 'file_lock_state' argument indicates if the file is locked
- add some KASSERTs
diffstat:
sys/kern/kern_veriexec.c | 52 ++++++++++++++++++++++++------------------------
1 files changed, 26 insertions(+), 26 deletions(-)
diffs (185 lines):
diff -r e812e8d4dae3 -r ff2c15466e11 sys/kern/kern_veriexec.c
--- a/sys/kern/kern_veriexec.c Sat Apr 25 08:48:06 2015 +0000
+++ b/sys/kern/kern_veriexec.c Sat Apr 25 09:08:51 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_veriexec.c,v 1.2 2015/04/25 08:19:06 maxv Exp $ */
+/* $NetBSD: kern_veriexec.c,v 1.3 2015/04/25 09:08:51 maxv Exp $ */
/*-
* Copyright (c) 2005, 2006 Elad Efrat <elad%NetBSD.org@localhost>
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_veriexec.c,v 1.2 2015/04/25 08:19:06 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_veriexec.c,v 1.3 2015/04/25 09:08:51 maxv Exp $");
#include "opt_veriexec.h"
@@ -78,6 +78,9 @@
#define VERIEXEC_UNLOCKED 0x00 /* Nothing locked, callee does it */
#define VERIEXEC_LOCKED 0x01 /* Global op lock held */
+/* state of file locking for veriexec_file_verify */
+#define VERIEXEC_FILE_UNLOCKED 0x02 /* Nothing locked, callee does it */
+#define VERIEXEC_FILE_LOCKED 0x04 /* File locked */
#define VERIEXEC_RW_UPGRADE(lock) while((rw_tryupgrade(lock)) == 0){};
@@ -423,7 +426,7 @@
* NOTE: vfe is assumed to be locked for writing on entry.
*/
static int
-veriexec_fp_calc(struct lwp *l, struct vnode *vp, int lock_state,
+veriexec_fp_calc(struct lwp *l, struct vnode *vp, int file_lock_state,
struct veriexec_file_entry *vfe, u_char *fp)
{
struct vattr va;
@@ -433,10 +436,13 @@
size_t resid, npages;
int error, do_perpage, pagen;
- if (lock_state == VERIEXEC_UNLOCKED)
+ KASSERT((file_lock_state != VERIEXEC_LOCKED) &&
+ (file_lock_state != VERIEXEC_UNLOCKED));
+
+ if (file_lock_state == VERIEXEC_FILE_UNLOCKED)
vn_lock(vp, LK_SHARED | LK_RETRY);
error = VOP_GETATTR(vp, &va, l->l_cred);
- if (lock_state == VERIEXEC_UNLOCKED)
+ if (file_lock_state == VERIEXEC_FILE_UNLOCKED)
VOP_UNLOCK(vp);
if (error)
return (error);
@@ -473,7 +479,7 @@
error = vn_rdwr(UIO_READ, vp, buf, len, offset,
UIO_SYSSPACE,
- ((lock_state == VERIEXEC_LOCKED)?
+ ((file_lock_state == VERIEXEC_FILE_LOCKED)?
IO_NODELOCKED : 0),
l->l_cred, &resid, NULL);
@@ -608,16 +614,22 @@
* exec_script(), 'flag' will be VERIEXEC_INDIRECT. If we are called from
* vn_open(), 'flag' will be VERIEXEC_FILE.
*
+ * 'veriexec_op_lock' must be locked (and remains locked).
+ *
* NOTE: The veriexec file entry pointer (vfep) will be returned LOCKED
* on no error.
*/
static int
veriexec_file_verify(struct lwp *l, struct vnode *vp, const u_char *name,
- int flag, int lockstate, struct veriexec_file_entry **vfep)
+ int flag, int file_lock_state, struct veriexec_file_entry **vfep)
{
struct veriexec_file_entry *vfe;
int error;
+ KASSERT(rw_lock_held(&veriexec_op_lock));
+ KASSERT((file_lock_state != VERIEXEC_LOCKED) &&
+ (file_lock_state != VERIEXEC_UNLOCKED));
+
#define VFE_NEEDS_EVAL(vfe) ((vfe->status == FINGERPRINT_NOTEVAL) || \
(vfe->type & VERIEXEC_UNTRUSTED))
@@ -627,9 +639,6 @@
if (vp->v_type != VREG)
return (0);
- if (lockstate == VERIEXEC_UNLOCKED)
- rw_enter(&veriexec_op_lock, RW_READER);
-
/* Lookup veriexec table entry, save pointer if requested. */
vfe = veriexec_get(vp);
if (vfep != NULL)
@@ -659,14 +668,12 @@
/* Calculate fingerprint for on-disk file. */
digest = kmem_zalloc(vfe->ops->hash_len, KM_SLEEP);
- error = veriexec_fp_calc(l, vp, lockstate, vfe, digest);
+ error = veriexec_fp_calc(l, vp, file_lock_state, vfe, digest);
if (error) {
veriexec_file_report(vfe, "Fingerprint calculation error.",
name, NULL, REPORT_ALWAYS);
kmem_free(digest, vfe->ops->hash_len);
rw_exit(&vfe->lock);
- if (lockstate == VERIEXEC_UNLOCKED)
- rw_exit(&veriexec_op_lock);
return (error);
}
@@ -687,8 +694,6 @@
/* IPS mode: Enforce access type. */
if (veriexec_strict >= VERIEXEC_IPS) {
rw_exit(&vfe->lock);
- if (lockstate == VERIEXEC_UNLOCKED)
- rw_exit(&veriexec_op_lock);
return (EPERM);
}
}
@@ -699,8 +704,6 @@
veriexec_file_report(NULL, "No entry.", name,
l, REPORT_VERBOSE);
- if (lockstate == VERIEXEC_UNLOCKED)
- rw_exit(&veriexec_op_lock);
/*
* Lockdown mode: Deny access to non-monitored files.
* IPS mode: Deny execution of non-monitored files.
@@ -717,8 +720,6 @@
case FINGERPRINT_NOTEVAL:
/* Should not happen. */
rw_exit(&vfe->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);
@@ -747,15 +748,11 @@
default:
/* Should never happen. */
rw_exit(&vfe->lock);
- if (lockstate == VERIEXEC_UNLOCKED)
- rw_exit(&veriexec_op_lock);
veriexec_file_report(vfe, "Invalid status "
"post evaluation.", name, NULL, REPORT_ALWAYS|REPORT_PANIC);
/* NOTREACHED */
}
- if (lockstate == VERIEXEC_UNLOCKED)
- rw_exit(&veriexec_op_lock);
return (error);
}
@@ -769,7 +766,10 @@
if (veriexec_bypass && (veriexec_strict == VERIEXEC_LEARNING))
return 0;
- r = veriexec_file_verify(l, vp, name, flag, VERIEXEC_UNLOCKED, &vfe);
+ rw_enter(&veriexec_op_lock, RW_READER);
+ r = veriexec_file_verify(l, vp, name, flag, VERIEXEC_FILE_UNLOCKED,
+ &vfe);
+ rw_exit(&veriexec_op_lock);
if ((r == 0) && (vfe != NULL))
rw_exit(&vfe->lock);
@@ -1295,7 +1295,7 @@
digest = kmem_zalloc(vfe->ops->hash_len, KM_SLEEP);
- error = veriexec_fp_calc(l, vp, VERIEXEC_UNLOCKED,
+ error = veriexec_fp_calc(l, vp, VERIEXEC_FILE_UNLOCKED,
vfe, digest);
if (error) {
kmem_free(digest, vfe->ops->hash_len);
@@ -1484,7 +1484,7 @@
rw_enter(&veriexec_op_lock, RW_READER);
error = veriexec_file_verify(l, vp, path, VERIEXEC_FILE,
- VERIEXEC_LOCKED, &vfe);
+ VERIEXEC_FILE_LOCKED, &vfe);
if (error) {
rw_exit(&veriexec_op_lock);
Home |
Main Index |
Thread Index |
Old Index