diff options
-rw-r--r-- | sys/kern/kern_exit.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 13 |
2 files changed, 14 insertions, 4 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 172fd10..7b409b4 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -503,6 +503,7 @@ wait1(td, uap, compat) { register int nfound; register struct proc *q, *p, *t; + struct pargs *pa; int status, error; mtx_lock(&Giant); @@ -604,6 +605,8 @@ loop: sx_xunlock(&proctree_lock); PROC_LOCK(p); p->p_xstat = 0; + pa = p->p_args; + p->p_args = NULL; PROC_UNLOCK(p); ruadd(&q->p_stats->p_cru, p->p_ru); FREE(p->p_ru, M_ZOMBIE); @@ -637,7 +640,7 @@ loop: /* * Remove unused arguments */ - pargs_drop(p->p_args); + pargs_drop(pa); if (--p->p_procsig->ps_refcnt == 0) { if (p->p_sigacts != &p->p_uarea->u_sigacts) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 79849bc..a1620bc 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1019,10 +1019,17 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) if (req->newptr && curproc != p) return (EPERM); - if (req->oldptr && p->p_args != NULL) - error = SYSCTL_OUT(req, p->p_args->ar_args, p->p_args->ar_length); - if (req->newptr == NULL) + PROC_LOCK(p); + pa = p->p_args; + pargs_hold(pa); + PROC_UNLOCK(p); + if (req->oldptr && pa != NULL) { + error = SYSCTL_OUT(req, pa->ar_args, pa->ar_length); + } + if (req->newptr == NULL) { + pargs_drop(pa); return (error); + } PROC_LOCK(p); pa = p->p_args; |