Module Name: src Committed By: ad Date: Mon Jan 6 11:18:51 UTC 2020
Modified Files: src/sys/kern: tty.c Log Message: ttygetinfo(): avoid crash with zombies. From skrll@, tweaked by me. To generate a diff of this commit: cvs rdiff -u -r1.283 -r1.284 src/sys/kern/tty.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/tty.c diff -u src/sys/kern/tty.c:1.283 src/sys/kern/tty.c:1.284 --- src/sys/kern/tty.c:1.283 Thu Jan 2 16:52:55 2020 +++ src/sys/kern/tty.c Mon Jan 6 11:18:51 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.283 2020/01/02 16:52:55 skrll Exp $ */ +/* $NetBSD: tty.c,v 1.284 2020/01/06 11:18:51 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.283 2020/01/02 16:52:55 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.284 2020/01/06 11:18:51 ad Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -2533,11 +2533,13 @@ ttygetinfo(struct tty *tp, int fromsig, const char *msg; char lmsg[100]; long rss; + bool again = false; KASSERT(mutex_owned(proc_lock)); *buf = '\0'; + retry: if (tp->t_session == NULL) msg = "not a controlling terminal\n"; else if (tp->t_pgrp == NULL) @@ -2568,11 +2570,26 @@ ttygetinfo(struct tty *tp, int fromsig, if (p->p_lock != oldpick->p_lock) mutex_exit(oldpick->p_lock); } - if (fromsig && - (SIGACTION_PS(pick->p_sigacts, SIGINFO).sa_flags & - SA_NOKERNINFO)) - return; - msg = NULL; + + if (pick != NULL) { + mutex_enter(pick->p_lock); + if (P_ZOMBIE(pick)) { + mutex_exit(pick->p_lock); + pick = NULL; + if (!again) { + again = true; + goto retry; + } + msg = "found only zombie processes\n"; + } + if (fromsig && + (SIGACTION_PS(pick->p_sigacts, SIGINFO).sa_flags & + SA_NOKERNINFO)) { + mutex_exit(pick->p_lock); + return; + } + msg = NULL; + } } /* Print load average. */ @@ -2589,7 +2606,7 @@ ttygetinfo(struct tty *tp, int fromsig, pick->p_pid); strlcat(buf, lmsg, bufsz); - mutex_enter(pick->p_lock); + KASSERT(mutex_owned(pick->p_lock)); LIST_FOREACH(l, &pick->p_lwps, l_sibling) { const char *lp; lwp_lock(l); @@ -2679,11 +2696,8 @@ proc_compare_wrapper(struct proc *p1, st KASSERT(mutex_owned(p1->p_lock)); KASSERT(mutex_owned(p2->p_lock)); - if ((l1 = LIST_FIRST(&p1->p_lwps)) == NULL) - return 1; - - if ((l2 = LIST_FIRST(&p2->p_lwps)) == NULL) - return 0; + l1 = LIST_FIRST(&p1->p_lwps); + l2 = LIST_FIRST(&p2->p_lwps); return proc_compare(p1, l1, p2, l2); }