NetBSD Problem Report #38646
From martin@duskware.de Tue May 13 06:12:21 2008
Return-Path: <martin@duskware.de>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by narn.NetBSD.org (Postfix) with ESMTP id 1477963B293
for <gnats-bugs@gnats.netbsd.org>; Tue, 13 May 2008 06:12:21 +0000 (UTC)
Message-Id: <20080513012646.EE1BD63B293@narn.NetBSD.org>
Date: Tue, 13 May 2008 01:26:46 +0000 (UTC)
From: ascizo@fiveam.org
Reply-To: ascizo@fiveam.org
To: netbsd-bugs-owner@NetBSD.org
Subject: -current panic with veriexec
X-Send-Pr-Version: www-1.0
>Number: 38646
>Category: kern
>Synopsis: -current panic with veriexec
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: blymn
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue May 13 06:15:00 +0000 2008
>Closed-Date: Sun Oct 12 11:35:19 +0000 2008
>Last-Modified: Sun Oct 12 11:35:19 +0000 2008
>Originator: Jari Kuittinen
>Release: NetBSD/i386 4.99.62 Thu May 8 09:18:09 EEST 2008
>Organization:
>Environment:
>Description:
Reader / writer lock error: rw_vector_enter: locking against myself
lock address : 0x00000000cb37b130
current cpu : 0
current lwp : 0x00000000ccdc8340
owner/count : 0x00000000ccdc8340 flags: 0x0000000000000004
panic: lock error
Stopped in pid 383.1 (ls) at netbsd:breakpoint+0x4: popl %ebp
db{0}> bt
breakpoint()
panic()
lockdebug_abort()
rw_abort()
rw_vector_enter()
vlockmgr()
ffs_lock()
VOP_LOCK()
vn_lock()
vn_rdwr()
veriexec_fp_calc()
veriexex_file_verify()
veriexec_openchk()
vn_open()
sys_open()
syscall()
>How-To-Repeat:
veriexecctl load
[any command]
>Fix:
>Release-Note:
>Audit-Trail:
From: Pierre Pronchery <khorben@defora.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/38646: -current panic with veriexec
Date: Sat, 17 May 2008 17:54:36 +0200
ascizo@fiveam.org wrote:
>> Synopsis: -current panic with veriexec
>> Release: NetBSD/i386 4.99.62 Thu May 8 09:18:09 EEST 2008
Same here with NetBSD/sparc64 4.99.62, on a GENERIC kernel from moments
before Fri May 9 00:11:51 CEST 2008.
>> Description:
> Reader / writer lock error: rw_vector_enter: locking against myself
>
> lock address : 0x00000000cb37b130
> current cpu : 0
> current lwp : 0x00000000ccdc8340
> owner/count : 0x00000000ccdc8340 flags: 0x0000000000000004
>
>
> panic: lock error
> Stopped in pid 383.1 (ls) at netbsd:breakpoint+0x4: popl %ebp
>
> db{0}> bt
> breakpoint()
> panic()
> lockdebug_abort()
> rw_abort()
> rw_vector_enter()
> vlockmgr()
> ffs_lock()
> VOP_LOCK()
> vn_lock()
> vn_rdwr()
> veriexec_fp_calc()
> veriexex_file_verify()
> veriexec_openchk()
> vn_open()
> sys_open()
> syscall()
Here is my stack trace:
lockdebug_abort(c1b0b80, 181bca0, 14d9e18, 1632880, 0, dc081d8) at
netbsd:lockdebug_abort+0x24
rw_vector_enter(c1b0b80, 0, 0, 0, 0, d9c32c8) at
netbsd:rw_vector_enter+0x130
vlockmgr(c1b0b80, 1, d8da800, 0, 1, 0) at netbsd:vlockmgr+0xe4
ffs_lock(d66e000, d9c352c, 2ea5840, ffffffffffffffff, 0, 2ced000) at
netbsd:ffs_lock+0x48
VOP_LOCK(c1b0aa0, 10001, ffffffffffffffff, 0, 0, dc0e000) at
netbsd:VOP_LOCK+0x20
vn_lock(c1b0aa0, 20001, 20, c9bfb60, 0, 0) at netbsd:vn_lock+0x9c
vn_rdwr(0, c1b0aa0, dc0e000, 2000, 0, 1) at netbsd:vn_rdwr+0xfc
veriexec_fp_calc(0, c1b0aa0, db65300, d93e6a0, 1, 0) at
netbsd:veriexec_fp_calc+0xd4
veriexec_file_verify(0, c1b0aa0, c1b7c00, 4, d93e6a0, 0) at
netbsd:veriexec_file_verify+0x7c
veriexec_openchk(d8da800, c1b0aa0, c1b7c00, 1, e, c1b7c00) at
netbsd:veriexec_openchk+0x30
vn_open(0, 1, d6d, ffffffffffffbad8, ffffffffffffbc20, ffffffffffffbc60)
at netbsd:vn_open+0x118
sys_open(0, d9c3dc0, d9c3e00, d9c3c28, 3, 1818a58) at netbsd:sys_open+0x90
syscall_plain(d9c3ed0, 3, 4030b100, 4030b104, 0, d9c3dc0) at
netbsd:syscall_plain+0x110
?(ffffffffffffb168, 0, 7f7f7f7f7f7f7f7f, fefefefefefefeff,
ffffffffffffffff, ff00) at 0x1008c90
>> How-To-Repeat:
> veriexecctl load
> [any command]
I did this:
# /etc/rc.d/veriexec onestart
after running veriexecgen.
I just finished to compile a -current kernel with LOCKDEBUG and will
include the output in another reply.
HTH,
--
khorben
From: Pierre Pronchery <khorben@defora.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/38646: -current panic with veriexec
Date: Sat, 17 May 2008 18:10:44 +0200
Pierre Pronchery wrote:
> I just finished to compile a -current kernel with LOCKDEBUG and will
> include the output in another reply.
I don't know if it helps much, but here it is:
# /etc/rc.d/veriexec onestart
Loading fingerprints... done.
Reader / writer lock error: lockdebug_wantlock: locking against myself
lock address : 0x000000000c1b0b80 type : sleep/adaptive
shared holds : 0 exclusive: 1
shares wanted: 1 exclusive: 0
current cpu : 0 last held: 0
current lwp : 0x000000000d9be440 last held: 0x000000000d9be440
last locked : 0x000000000133c420 unlocked : 0x000000000133c4e0
initialized : 0x000000000133dedc
owner/count : 0x000000000d9be440 flags : 0x000000000000000c
Turnstile chain at 0x18b96e0.
=> No active turnstile for this lock.
panic: LOCKDEBUG
Stopped in pid 392.1 (sysctl) at netbsd:cpu_Debugger+0x4: nop
Cheers,
--
khorben
Responsible-Changed-From-To: kern-bug-people->blymn
Responsible-Changed-By: blymn@NetBSD.org
Responsible-Changed-When: Mon, 23 Jun 2008 12:41:50 +0000
Responsible-Changed-Why:
I will claim this one
From: Brett Lymn <blymn@baesystems.com.au>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/38646 (-current panic with veriexec)
Date: Mon, 23 Jun 2008 22:24:49 +0930
The following patch appears to fix the problem (not sure if it is the
correct way to do this though). Tried mailing the submitter but I
have had no response.
Index: kern_verifiedexec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_verifiedexec.c,v
retrieving revision 1.108
diff -u -r1.108 kern_verifiedexec.c
--- kern_verifiedexec.c 23 Feb 2008 16:05:17 -0000 1.108
+++ kern_verifiedexec.c 8 Jun 2008 12:54:32 -0000
@@ -41,6 +41,7 @@
#include <sys/exec.h>
#include <sys/once.h>
#include <sys/proc.h>
+#include <sys/rwlock.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>
#include <sys/inttypes.h>
@@ -73,6 +74,16 @@
#define REPORT_ALARM 0x10 /* Alarm - also print pid/uid/.. */
#define REPORT_LOGMASK (REPORT_ALWAYS|REPORT_VERBOSE|REPORT_DEBUG)
+/* state of locking for veriexec_file_verify */
+#define VERIEXEC_UNLOCKED 0X00 /* Nothing locked, callee does it */
+#define VERIEXEC_LOCKED 0X01 /* Global op lock held */
+
+
+#define RW_UPGRADE(lock) do { \
+ /* Nothing */ \
+} while((rw_tryupgrade(lock)) == 0); \
+
+
struct veriexec_fpops {
const char *type;
size_t hash_len;
@@ -85,6 +96,7 @@
/* Veriexec per-file entry data. */
struct veriexec_file_entry {
+ krwlock_t lock; /* r/w lock */
u_char *filename; /* File name. */
u_char type; /* Entry type. */
u_char status; /* Evaluation status. */
@@ -126,6 +138,13 @@
static unsigned int veriexec_tablecount = 0;
/*
+ * Veriexec operations global lock - most ops hold this as a read
+ * lock, it is upgraded to a write lock when destroying veriexec file
+ * table entries.
+ */
+static krwlock_t veriexec_op_lock;
+
+/*
* Sysctl helper routine for Veriexec.
*/
static int
@@ -310,6 +329,8 @@
if (error)
panic("Veriexec: Can't create mountspecific key");
+ rw_init(&veriexec_op_lock);
+
#define FPOPS_ADD(a, b, c, d, e, f) \
veriexec_fpops_add(a, b, c, (veriexec_fpop_init_t)d, \
(veriexec_fpop_update_t)e, (veriexec_fpop_final_t)f)
@@ -366,9 +387,11 @@
/*
* Calculate fingerprint. Information on hash length and routines used is
* extracted from veriexec_hash_list according to the hash type.
+ *
+ * NOTE: vfe is assumed to be locked for writing on entry.
*/
static int
-veriexec_fp_calc(struct lwp *l, struct vnode *vp,
+veriexec_fp_calc(struct lwp *l, struct vnode *vp, int lock_state,
struct veriexec_file_entry *vfe, u_char *fp)
{
struct vattr va;
@@ -414,11 +437,8 @@
error = vn_rdwr(UIO_READ, vp, buf, len, offset,
UIO_SYSSPACE,
-#ifdef __FreeBSD__
- IO_NODELOCKED,
-#else
- 0,
-#endif
+ ((lock_state == VERIEXEC_LOCKED)?
+ IO_NODELOCKED : 0),
l->l_cred, &resid, NULL);
if (error) {
@@ -554,17 +574,26 @@
* sys_execve(), 'flag' will be VERIEXEC_DIRECT. If we're called from
* exec_script(), 'flag' will be VERIEXEC_INDIRECT. If we are called from
* vn_open(), 'flag' will be VERIEXEC_FILE.
+ *
+ * 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,
- struct veriexec_file_entry **vfep)
+veriexec_file_verify(struct lwp *l, struct vnode *vp, const u_char *name,
+ int flag, int lockstate, struct veriexec_file_entry **vfep)
{
struct veriexec_file_entry *vfe;
int error;
+#define VFE_NEEDS_EVAL(vfe) ((vfe->status == FINGERPRINT_NOTEVAL) || \
+ (vfe->type & VERIEXEC_UNTRUSTED))
+
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)
@@ -572,20 +601,35 @@
if (vfe == NULL)
goto out;
- /* Evaluate fingerprint if needed. */
error = 0;
- if ((vfe->status == FINGERPRINT_NOTEVAL) ||
- (vfe->type & VERIEXEC_UNTRUSTED)) {
+
+ /*
+ * Grab the lock for the entry, if we need to do an evaluation
+ * then the lock is a write lock, after we have the write
+ * lock, check if we really need it - some other thread may
+ * have already done the work for us.
+ */
+ if (VFE_NEEDS_EVAL(vfe)) {
+ rw_enter(&vfe->lock, RW_WRITER);
+ if (!VFE_NEEDS_EVAL(vfe))
+ rw_downgrade(&vfe->lock);
+ } else
+ rw_enter(&vfe->lock, RW_READER);
+
+ /* Evaluate fingerprint if needed. */
+ if (VFE_NEEDS_EVAL(vfe)) {
u_char *digest;
/* Calculate fingerprint for on-disk file. */
digest = kmem_zalloc(vfe->ops->hash_len, KM_SLEEP);
- error = veriexec_fp_calc(l, vp, vfe, digest);
+ error = veriexec_fp_calc(l, vp, lockstate, 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);
+ rw_exit(&veriexec_op_lock);
return (error);
}
@@ -596,6 +640,7 @@
vfe->status = FINGERPRINT_NOMATCH;
kmem_free(digest, vfe->ops->hash_len);
+ rw_downgrade(&vfe->lock);
}
if (!(vfe->type & flag)) {
@@ -603,8 +648,11 @@
REPORT_ALWAYS|REPORT_ALARM);
/* IPS mode: Enforce access type. */
- if (veriexec_strict >= VERIEXEC_IPS)
+ if (veriexec_strict >= VERIEXEC_IPS) {
+ rw_exit(&vfe->lock);
+ rw_exit(&veriexec_op_lock);
return (EPERM);
+ }
}
out:
@@ -613,6 +661,8 @@
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.
@@ -628,6 +678,8 @@
switch (vfe->status) {
case FINGERPRINT_NOTEVAL:
/* Should not happen. */
+ rw_exit(&vfe->lock);
+ rw_exit(&veriexec_op_lock);
veriexec_file_report(vfe, "Not-evaluated status "
"post evaluation; inconsistency detected.", name,
NULL, REPORT_ALWAYS|REPORT_PANIC);
@@ -647,17 +699,23 @@
NULL, REPORT_ALWAYS|REPORT_ALARM);
/* IDS mode: Deny access on fingerprint mismatch. */
- if (veriexec_strict >= VERIEXEC_IDS)
+ if (veriexec_strict >= VERIEXEC_IDS) {
+ rw_exit(&vfe->lock);
error = EPERM;
+ }
break;
default:
/* Should never happen. */
+ rw_exit(&vfe->lock);
+ rw_exit(&veriexec_op_lock);
veriexec_file_report(vfe, "Invalid status "
"post evaluation.", name, NULL, REPORT_ALWAYS|REPORT_PANIC);
}
+ if (lockstate == VERIEXEC_UNLOCKED)
+ rw_exit(&veriexec_op_lock);
return (error);
}
@@ -671,15 +729,14 @@
if (veriexec_bypass)
return 0;
- KERNEL_LOCK(1, NULL);
+ r = veriexec_file_verify(l, vp, name, flag, VERIEXEC_UNLOCKED, &vfe);
- r = veriexec_file_verify(l, vp, name, flag, &vfe);
+ if ((r == 0) && (vfe != NULL))
+ rw_exit(&vfe->lock);
if (found != NULL)
*found = (vfe != NULL) ? true : false;
- KERNEL_UNLOCK_ONE(NULL);
-
return (r);
}
@@ -769,11 +826,12 @@
if (veriexec_bypass)
return 0;
- KERNEL_LOCK(1, NULL);
+ rw_enter(&veriexec_op_lock, RW_READER);
vfe = veriexec_get(vp);
+ rw_exit(&veriexec_op_lock);
+
if (vfe == NULL) {
- KERNEL_UNLOCK_ONE(NULL);
/* Lockdown mode: Deny access to non-monitored files. */
if (veriexec_strict >= VERIEXEC_LOCKDOWN)
return (EPERM);
@@ -790,7 +848,7 @@
else
error = veriexec_file_delete(l, vp);
- KERNEL_UNLOCK_ONE(NULL);
+
return error;
}
@@ -810,14 +868,14 @@
if (veriexec_bypass)
return 0;
- KERNEL_LOCK(1, NULL);
+ rw_enter(&veriexec_op_lock, RW_READER);
if (veriexec_strict >= VERIEXEC_LOCKDOWN) {
log(LOG_ALERT, "Veriexec: Preventing rename of `%s' to "
"`%s', uid=%u, pid=%u: Lockdown mode.\n", fromname, toname,
kauth_cred_geteuid(l->l_cred), l->l_proc->p_pid);
- KERNEL_UNLOCK_ONE(NULL);
+ rw_exit(&veriexec_op_lock);
return (EPERM);
}
@@ -835,7 +893,7 @@
l->l_proc->p_pid, (vfe != NULL && tvfe != NULL) ?
"files" : "file");
- KERNEL_UNLOCK_ONE(NULL);
+ rw_exit(&veriexec_op_lock);
return (EPERM);
}
@@ -847,25 +905,36 @@
* XXX: big enough for the new filename.
*/
if (vfe != NULL) {
+ /* XXXX get write lock on vfe here? */
+
+ RW_UPGRADE(&veriexec_op_lock);
+ /* once we have the op lock in write mode
+ * there should be no locks on any file
+ * entries so we can destroy the object.
+ */
+
kmem_free(vfe->filename, vfe->filename_len);
vfe->filename = NULL;
vfe->filename_len = 0;
+ rw_downgrade(&veriexec_op_lock);
}
+ log(LOG_NOTICE, "Veriexec: %s file `%s' renamed to "
+ "%s file `%s', uid=%u, pid=%u.\n", (vfe != NULL) ?
+ "Monitored" : "Non-monitored", fromname, (tvfe != NULL) ?
+ "monitored" : "non-monitored", toname,
+ kauth_cred_geteuid(l->l_cred), l->l_proc->p_pid);
+
+ rw_exit(&veriexec_op_lock);
+
/*
* Monitored file is overwritten. Remove the entry.
*/
if (tvfe != NULL)
(void)veriexec_file_delete(l, tovp);
- log(LOG_NOTICE, "Veriexec: %s file `%s' renamed to "
- "%s file `%s', uid=%u, pid=%u.\n", (vfe != NULL) ?
- "Monitored" : "Non-monitored", fromname, (tvfe != NULL) ?
- "monitored" : "non-monitored", toname,
- kauth_cred_geteuid(l->l_cred), l->l_proc->p_pid);
}
- KERNEL_UNLOCK_ONE(NULL);
return (0);
}
@@ -879,23 +948,33 @@
kmem_free(vfe->page_fp, vfe->ops->hash_len);
if (vfe->filename != NULL)
kmem_free(vfe->filename, vfe->filename_len);
+ rw_destroy(&vfe->lock);
kmem_free(vfe, sizeof(*vfe));
}
}
static void
-veriexec_file_purge(struct veriexec_file_entry *vfe)
+veriexec_file_purge(struct veriexec_file_entry *vfe, int have_lock)
{
if (vfe == NULL)
return;
+ if (have_lock == VERIEXEC_UNLOCKED)
+ rw_enter(&vfe->lock, RW_WRITER);
+ else
+ RW_UPGRADE(&vfe->lock);
+
vfe->status = FINGERPRINT_NOTEVAL;
+ if (have_lock == VERIEXEC_UNLOCKED)
+ rw_exit(&vfe->lock);
+ else
+ rw_downgrade(&vfe->lock);
}
static void
veriexec_file_purge_cb(struct veriexec_file_entry *vfe, void *cookie)
{
- veriexec_file_purge(vfe);
+ veriexec_file_purge(vfe, VERIEXEC_UNLOCKED);
}
/*
@@ -905,7 +984,10 @@
void
veriexec_purge(struct vnode *vp)
{
- veriexec_file_purge(veriexec_get(vp));
+
+ rw_enter(&veriexec_op_lock, RW_READER);
+ veriexec_file_purge(veriexec_get(vp), VERIEXEC_UNLOCKED);
+ rw_exit(&veriexec_op_lock);
}
/*
@@ -1024,8 +1106,10 @@
case VERIEXEC_IDS:
result = KAUTH_RESULT_DEFER;
+ rw_enter(&veriexec_op_lock, RW_WRITER);
fileassoc_table_run(bvp->v_mount, veriexec_hook,
(fileassoc_cb_t)veriexec_file_purge_cb, NULL);
+ rw_exit(&veriexec_op_lock);
break;
case VERIEXEC_IPS:
@@ -1145,6 +1229,8 @@
memcpy(vfe->fp, prop_data_data_nocopy(prop_dictionary_get(dict, "fp")),
vfe->ops->hash_len);
+ rw_enter(&veriexec_op_lock, RW_WRITER);
+
/*
* See if we already have an entry for this file. If we do, then
* let the user know and silently pretend to succeed.
@@ -1161,7 +1247,7 @@
if ((veriexec_verbose >= 1) || fp_mismatch)
log(LOG_NOTICE, "Veriexec: Duplicate entry for `%s' "
- "ignored. (%s fingerprint)\n", file,
+ "ignored. (%s fingerprint)\n", file,
fp_mismatch ? "different" : "same");
veriexec_file_free(vfe);
@@ -1169,7 +1255,7 @@
/* XXX Should this be EEXIST if fp_mismatch is true? */
error = 0;
- goto out;
+ goto unlock_out;
}
/* Continue entry initialization. */
@@ -1186,7 +1272,7 @@
error = EINVAL;
- goto out;
+ goto unlock_out;
}
}
if (!(vfe->type & (VERIEXEC_DIRECT | VERIEXEC_INDIRECT |
@@ -1205,6 +1291,7 @@
vfe->page_fp_status = PAGE_FP_NONE;
vfe->npages = 0;
vfe->last_page_size = 0;
+ rw_init(&vfe->lock);
vte = veriexec_table_lookup(nid.ni_vp->v_mount);
if (vte == NULL)
@@ -1214,7 +1301,7 @@
error = fileassoc_add(nid.ni_vp, veriexec_hook, vfe);
if (error)
- goto out;
+ goto unlock_out;
vte->vte_count++;
@@ -1224,7 +1311,8 @@
digest = kmem_zalloc(vfe->ops->hash_len, KM_SLEEP);
- error = veriexec_fp_calc(l, nid.ni_vp, vfe, digest);
+ error = veriexec_fp_calc(l, nid.ni_vp, VERIEXEC_UNLOCKED,
+ vfe, digest);
if (error) {
kmem_free(digest, vfe->ops->hash_len);
goto out;
@@ -1241,7 +1329,10 @@
veriexec_file_report(NULL, "New entry.", file, NULL, REPORT_DEBUG);
veriexec_bypass = 0;
- out:
+ unlock_out:
+ rw_exit(&veriexec_op_lock);
+
+ out:
vrele(nid.ni_vp);
if (error)
veriexec_file_free(vfe);
@@ -1272,7 +1363,9 @@
if (vte == NULL)
return (ENOENT);
+ rw_enter(&veriexec_op_lock, RW_WRITER);
error = fileassoc_clear(vp, veriexec_hook);
+ rw_exit(&veriexec_op_lock);
if (!error)
vte->vte_count--;
@@ -1301,12 +1394,19 @@
{
struct veriexec_file_entry *vfe;
+ rw_enter(&veriexec_op_lock, RW_READER);
+
vfe = veriexec_get(vp);
- if (vfe == NULL)
+ if (vfe == NULL) {
+ rw_exit(&veriexec_op_lock);
return (ENOENT);
+ }
+ rw_enter(&vfe->lock, RW_READER);
veriexec_file_convert(vfe, rdict);
+ rw_exit(&vfe->lock);
+ rw_exit(&veriexec_op_lock);
return (0);
}
@@ -1318,7 +1418,7 @@
if (veriexec_bypass || doing_shutdown)
return (0);
- KERNEL_LOCK(1, NULL);
+ rw_enter(&veriexec_op_lock, RW_READER);
switch (veriexec_strict) {
case VERIEXEC_LEARNING:
@@ -1348,7 +1448,7 @@
error = 0;
break;
}
-
+
case VERIEXEC_LOCKDOWN:
default:
log(LOG_ALERT, "Veriexec: Lockdown mode, preventing unmount "
@@ -1357,7 +1457,7 @@
break;
}
- KERNEL_UNLOCK_ONE(NULL);
+ rw_exit(&veriexec_op_lock);
return (error);
}
@@ -1370,8 +1470,6 @@
if (veriexec_bypass)
return 0;
- KERNEL_LOCK(1, NULL);
-
if (vp == NULL) {
/* If no creation requested, let this fail normally. */
if (!(fmode & O_CREAT))
@@ -1387,9 +1485,14 @@
goto out;
}
- error = veriexec_file_verify(l, vp, path, VERIEXEC_FILE, &vfe);
- if (error)
+ rw_enter(&veriexec_op_lock, RW_READER);
+ error = veriexec_file_verify(l, vp, path, VERIEXEC_FILE,
+ VERIEXEC_LOCKED, &vfe);
+
+ if (error) {
+ rw_exit(&veriexec_op_lock);
goto out;
+ }
if ((vfe != NULL) && ((fmode & FWRITE) || (fmode & O_TRUNC))) {
veriexec_file_report(vfe, "Write access request.", path, l,
@@ -1399,11 +1502,14 @@
if (veriexec_strict >= VERIEXEC_IPS)
error = EPERM;
else
- veriexec_file_purge(vfe);
+ veriexec_file_purge(vfe, VERIEXEC_LOCKED);
}
+ if (vfe != NULL)
+ rw_exit(&vfe->lock);
+
+ rw_exit(&veriexec_op_lock);
out:
- KERNEL_UNLOCK_ONE(NULL);
return (error);
}
--
Brett Lymn
"Warning:
The information contained in this email and any attached files is
confidential to BAE Systems Australia. If you are not the intended
recipient, any use, disclosure or copying of this email or any
attachments is expressly prohibited. If you have received this email
in error, please notify us immediately. VIRUS: Every care has been
taken to ensure this email and its attachments are virus free,
however, any loss or damage incurred in using this email is not the
sender's responsibility. It is your responsibility to ensure virus
checks are completed before installing any data sent in this email to
your computer."
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, blymn@NetBSD.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, ascizo@fiveam.org
Cc:
Subject: Re: kern/38646 (-current panic with veriexec)
Date: Mon, 23 Jun 2008 13:22:33 -0400
On Jun 23, 12:55pm, blymn@baesystems.com.au (Brett Lymn) wrote:
-- Subject: Re: kern/38646 (-current panic with veriexec)
| +#define RW_UPGRADE(lock) do { \
| + /* Nothing */ \
| +} while((rw_tryupgrade(lock)) == 0); \
Why not:
#define RW_UPGRADE(lock) while((rw_tryupgrade(lock)) == 0) continue
christos
From: Matt Fleming <mjf@NetBSD.org>
To: gnats-bugs@NetBSD.org
Cc: blymn@NetBSD.org
Subject: Re: kern/38646: -current panic with veriexec
Date: Sun, 29 Jun 2008 11:41:18 +0100
The patch fixes the issue for me.
State-Changed-From-To: open->feedback
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 11 Oct 2008 18:22:21 +0000
State-Changed-Why:
Did the patch get committed? The submitter says on chat that the problem's
fixed.
State-Changed-From-To: feedback->closed
State-Changed-By: blymn@NetBSD.org
State-Changed-When: Sun, 12 Oct 2008 11:35:19 +0000
State-Changed-Why:
Bug was confirmed fixed.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.