summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-03-28 21:30:22 +0000
committerjhb <jhb@FreeBSD.org>2006-03-28 21:30:22 +0000
commit44f0d9f5195c6fba57e25137546f98690ea5f1d2 (patch)
tree4f5f0c0176236c8d422846a1ad3de7d7acc57d6e /sys/kern/kern_sig.c
parent0d8b767dc84c60efc1d4a020824e0fb91f8015e9 (diff)
downloadFreeBSD-src-44f0d9f5195c6fba57e25137546f98690ea5f1d2.zip
FreeBSD-src-44f0d9f5195c6fba57e25137546f98690ea5f1d2.tar.gz
- Conditionalize Giant around VFS operations for ALQ, ktrace, and
generating a coredump as the result of a signal. - Fix a bug where we could leak a Giant lock if vn_start_write() failed in coredump(). Reported by: jmg (2)
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 7e919c8..2d99ff1 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -3062,6 +3062,7 @@ coredump(struct thread *td)
struct mount *mp;
char *name; /* name of corefile */
off_t limit;
+ int vfslocked;
PROC_LOCK_ASSERT(p, MA_OWNED);
MPASS((p->p_flag & P_HADTHREADS) == 0 || p->p_singlethread == td);
@@ -3085,21 +3086,17 @@ coredump(struct thread *td)
if (limit == 0)
return (EFBIG);
- mtx_lock(&Giant);
restart:
name = expand_name(p->p_comm, td->td_ucred->cr_uid, p->p_pid);
- if (name == NULL) {
- mtx_unlock(&Giant);
+ if (name == NULL)
return (EINVAL);
- }
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); /* XXXKSE */
+ NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, name, td);
flags = O_CREAT | FWRITE | O_NOFOLLOW;
error = vn_open(&nd, &flags, S_IRUSR | S_IWUSR, -1);
free(name, M_TEMP);
- if (error) {
- mtx_unlock(&Giant);
+ if (error)
return (error);
- }
+ vfslocked = NDHASGIANT(&nd);
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
@@ -3108,7 +3105,7 @@ restart:
VOP_GETATTR(vp, &vattr, cred, td) || vattr.va_nlink != 1) {
VOP_UNLOCK(vp, 0, td);
error = EFAULT;
- goto out;
+ goto close;
}
VOP_UNLOCK(vp, 0, td);
@@ -3123,9 +3120,10 @@ restart:
if (locked)
VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK);
if ((error = vn_close(vp, FWRITE, cred, td)) != 0)
- return (error);
+ goto out;
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
- return (error);
+ goto out;
+ VFS_UNLOCK_GIANT(vfslocked);
goto restart;
}
@@ -3150,11 +3148,12 @@ restart:
VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK);
}
vn_finished_write(mp);
-out:
+close:
error1 = vn_close(vp, FWRITE, cred, td);
- mtx_unlock(&Giant);
if (error == 0)
error = error1;
+out:
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
OpenPOWER on IntegriCloud