Module Name: src Committed By: kamil Date: Fri Mar 8 23:32:31 UTC 2019
Modified Files: src/sys/kern: kern_sig.c Log Message: Stop resetting signal context on a trap signal under a debugger In case of a crash signal, notify debugger immediately passing the signal regardless of signal masking/ignoring. While there pass signals emitted by a debugger to debuggee. Debugger calls proc_unstop() that sets p_stat to SACTIVE and this signal wasn't passed to tracee. This scenario appeared to be triggered in recently added crash signal ATF ptrace(2) tests. To generate a diff of this commit: cvs rdiff -u -r1.350 -r1.351 src/sys/kern/kern_sig.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/kern_sig.c diff -u src/sys/kern/kern_sig.c:1.350 src/sys/kern/kern_sig.c:1.351 --- src/sys/kern/kern_sig.c:1.350 Thu Nov 29 10:27:36 2018 +++ src/sys/kern/kern_sig.c Fri Mar 8 23:32:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sig.c,v 1.350 2018/11/29 10:27:36 maxv Exp $ */ +/* $NetBSD: kern_sig.c,v 1.351 2019/03/08 23:32:30 kamil Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.350 2018/11/29 10:27:36 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.351 2019/03/08 23:32:30 kamil Exp $"); #include "opt_ptrace.h" #include "opt_dtrace.h" @@ -911,13 +911,25 @@ trapsignal(struct lwp *l, ksiginfo_t *ks KASSERT(!cpu_intr_p()); mutex_enter(proc_lock); mutex_enter(p->p_lock); + + if (ISSET(p->p_slflag, PSL_TRACED) && + !(p->p_pptr == p->p_opptr && ISSET(p->p_lflag, PL_PPWAIT))) { + p->p_xsig = signo; + p->p_sigctx.ps_faked = true; // XXX + p->p_sigctx.ps_info._signo = signo; + p->p_sigctx.ps_info._code = ksi->ksi_code; + sigswitch(0, signo, false); + // XXX ktrpoint(KTR_PSIG) + mutex_exit(p->p_lock); + return; + } + mask = &l->l_sigmask; ps = p->p_sigacts; - const bool traced = (p->p_slflag & PSL_TRACED) != 0; const bool caught = sigismember(&p->p_sigctx.ps_sigcatch, signo); const bool masked = sigismember(mask, signo); - if (!traced && caught && !masked) { + if (caught && !masked) { mutex_exit(proc_lock); l->l_ru.ru_nsignals++; kpsendsig(l, ksi, mask); @@ -1678,7 +1690,9 @@ issignal(struct lwp *l) if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) { sigswitch(PS_NOCLDSTOP, 0, true); signo = sigchecktrace(); - } else + } else if (p->p_stat == SACTIVE) + signo = sigchecktrace(); + else signo = 0; /* Signals from the debugger are "out of band". */