diff options
author | tegge <tegge@FreeBSD.org> | 2006-05-05 20:25:05 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2006-05-05 20:25:05 +0000 |
commit | ce79e019da722f1599b58071d568b1c5333e0205 (patch) | |
tree | c3b6f91b246648fbe6a9b1e092acec79851a67ac /sys/kern/kern_exec.c | |
parent | b9db75cffced59917509b288a2c8bcae06746d1e (diff) | |
download | FreeBSD-src-ce79e019da722f1599b58071d568b1c5333e0205.zip FreeBSD-src-ce79e019da722f1599b58071d568b1c5333e0205.tar.gz |
Temporarily unlock vnode for new image being executed to avoid lock order
reversals that can lead to deadlocks. Normally vn_close(), namei() or vrele()
should not be called while holding vnode locks.
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r-- | sys/kern/kern_exec.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index de6897a..d4aab82 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -487,7 +487,9 @@ interpret: } /* close files on exec */ + VOP_UNLOCK(imgp->vp, 0, td); fdcloseexec(td); + vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td); /* Get a reference to the vnode prior to locking the proc */ VREF(ndp->ni_vp); @@ -582,7 +584,9 @@ interpret: */ PROC_UNLOCK(p); setugidsafety(td); + VOP_UNLOCK(imgp->vp, 0, td); error = fdcheckstd(td); + vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td); if (error != 0) goto done1; PROC_LOCK(p); @@ -714,6 +718,7 @@ done1: crfree(oldcred); else crfree(newcred); + VOP_UNLOCK(imgp->vp, 0, td); /* * Handle deferred decrement of ref counts. */ @@ -732,6 +737,7 @@ done1: if (tracecred != NULL) crfree(tracecred); #endif + vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td); if (oldargs != NULL) pargs_drop(oldargs); if (newargs != NULL) |