From c008d3ad1975408adf2003ca58de38555c5e5450 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 30 Jun 2003 22:19:41 +0000 Subject: [PATCH] Fix a race in sysctl_out_proc() vs copyout() that could crash the kernel. --- sys/kern/kern_exit.c | 16 ++++++++++++++-- sys/kern/kern_proc.c | 5 +++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index fe3495b839..d29141f42e 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -37,7 +37,7 @@ * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 * $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $ - * $DragonFly: src/sys/kern/kern_exit.c,v 1.12 2003/06/30 19:50:31 dillon Exp $ + * $DragonFly: src/sys/kern/kern_exit.c,v 1.13 2003/06/30 22:19:41 dillon Exp $ */ #include "opt_compat.h" @@ -451,7 +451,19 @@ loop: tsleep(p->p_thread, PWAIT, "reap", 0); goto loop; } - KASSERT(p->p_lock == 0, ("p_lock not 0! %p", p)); + + /* + * Other kernel threads may be in the middle of + * accessing the proc. For example, kern/kern_proc.c + * could be blocked writing proc data to a sysctl. + * At the moment, if this occurs, we are not woken + * up and rely on a one-second retry. + */ + if (p->p_lock) { + printf("Diagnostic: waiting for p_lock\n"); + while (p->p_lock) + tsleep(p, PWAIT, "reap2", hz); + } /* charge childs scheduling cpu usage to parent */ if (curproc->p_pid != 1) { diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 111888f981..eb03eea959 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -32,7 +32,7 @@ * * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95 * $FreeBSD: src/sys/kern/kern_proc.c,v 1.63.2.9 2003/05/08 07:47:16 kbyanc Exp $ - * $DragonFly: src/sys/kern/kern_proc.c,v 1.7 2003/06/28 02:36:43 dillon Exp $ + * $DragonFly: src/sys/kern/kern_proc.c,v 1.8 2003/06/30 22:19:41 dillon Exp $ */ #include @@ -529,8 +529,9 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) if (!PRISON_CHECK(cr1, p->p_ucred)) continue; - + PHOLD(p); error = sysctl_out_proc(p, req, doingzomb); + PRELE(p); if (error) return (error); } -- 2.41.0