svn commit: r239989 - head/sys/kern
Pawel Jakub Dawidek
pjd at FreeBSD.org
Sat Sep 1 11:21:57 UTC 2012
Author: pjd
Date: Sat Sep 1 11:21:56 2012
New Revision: 239989
URL: http://svn.freebsd.org/changeset/base/239989
Log:
Fix panic in procdesc that can be triggered in the following scenario:
1. Process A pdfork(2)s process B.
2. Process A passes process descriptor of B to unrelated process C.
3. Hit CTRL+C to terminate process A. Process B is also terminated
with SIGINT.
4. init(8) collects status of process B.
5. Process C closes process descriptor associated with process B.
When we have such order of events, init(8), by collecting status of
process B, will call procdesc_reap(). This function sets pd_proc to NULL.
Now when process C calls close on this process descriptor,
procdesc_close() is called. Unfortunately procdesc_close() assumes that
pd_proc points at a valid proc structure, but it was set to NULL earlier,
so the kernel panics.
The patch also adds setting 'p->p_procdesc' to NULL in procdesc_reap(),
which I think should be done.
MFC after: 1 week
Modified:
head/sys/kern/sys_procdesc.c
Modified: head/sys/kern/sys_procdesc.c
==============================================================================
--- head/sys/kern/sys_procdesc.c Sat Sep 1 10:56:15 2012 (r239988)
+++ head/sys/kern/sys_procdesc.c Sat Sep 1 11:21:56 2012 (r239989)
@@ -333,6 +333,7 @@ procdesc_reap(struct proc *p)
pd = p->p_procdesc;
pd->pd_proc = NULL;
+ p->p_procdesc = NULL;
procdesc_free(pd);
}
@@ -358,14 +359,20 @@ procdesc_close(struct file *fp, struct t
pd->pd_flags |= PDF_CLOSED;
PROCDESC_UNLOCK(pd);
p = pd->pd_proc;
- PROC_LOCK(p);
- if (p->p_state == PRS_ZOMBIE) {
+ if (p == NULL) {
+ /*
+ * This is the case where process' exit status was already
+ * collected and procdesc_reap() was already called.
+ */
+ sx_xunlock(&proctree_lock);
+ } else if (p->p_state == PRS_ZOMBIE) {
/*
* If the process is already dead and just awaiting reaping,
* do that now. This will release the process's reference to
* the process descriptor when it calls back into
* procdesc_reap().
*/
+ PROC_LOCK(p);
PROC_SLOCK(p);
proc_reap(curthread, p, NULL, 0, NULL);
} else {
@@ -376,6 +383,7 @@ procdesc_close(struct file *fp, struct t
* process from its descriptor so that its exit status will
* be reported normally.
*/
+ PROC_LOCK(p);
pd->pd_proc = NULL;
p->p_procdesc = NULL;
procdesc_free(pd);
More information about the svn-src-head
mailing list