diff options
author | pjd <pjd@FreeBSD.org> | 2012-12-16 14:53:27 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2012-12-16 14:53:27 +0000 |
commit | 3e4021fec3c9920b852f3dec03a22a5a644fd6e4 (patch) | |
tree | fda6d6771c62d7cc67c33d65daa0f4d16d2e8f90 | |
parent | 1fdcf9e7be7549ebb4e865fadc73f5f6c4daf661 (diff) | |
download | FreeBSD-src-3e4021fec3c9920b852f3dec03a22a5a644fd6e4.zip FreeBSD-src-3e4021fec3c9920b852f3dec03a22a5a644fd6e4.tar.gz |
Move expand_name() after process lock is released.
This fixed panic where we hold mutex (process lock) and try to obtain sleepable
lock (vnode lock in expand_name()). The panic could occur when %I was used
in kern.corefile.
Additionally we avoid expand_name() overhead when coredumps are disabled.
Obtained from: WHEEL Systems
-rw-r--r-- | sys/kern/kern_sig.c | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 957f3d4..f7a2d31 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -3210,14 +3210,8 @@ coredump(struct thread *td) MPASS((p->p_flag & P_HADTHREADS) == 0 || p->p_singlethread == td); _STOPEVENT(p, S_CORE, 0); - name = expand_name(p->p_comm, cred->cr_uid, p->p_pid, td, compress); - if (name == NULL) { - PROC_UNLOCK(p); - return (EINVAL); - } if (!do_coredump || (!sugid_coredump && (p->p_flag & P_SUGID) != 0)) { PROC_UNLOCK(p); - free(name, M_TEMP); return (EFAULT); } @@ -3232,11 +3226,14 @@ coredump(struct thread *td) limit = (off_t)lim_cur(p, RLIMIT_CORE); if (limit == 0 || racct_get_available(p, RACCT_CORE) == 0) { PROC_UNLOCK(p); - free(name, M_TEMP); return (EFBIG); } PROC_UNLOCK(p); + name = expand_name(p->p_comm, cred->cr_uid, p->p_pid, td, compress); + if (name == NULL) + return (EINVAL); + restart: NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); flags = O_CREAT | FWRITE | O_NOFOLLOW; |