From ac37cdce0c807cf6357cd9f61ecebd222ccc1e9a Mon Sep 17 00:00:00 2001 From: kamil Date: Thu, 2 May 2019 22:23:49 +0000 Subject: [PATCH] Introduce fixes for ptrace(2) Stop disabling LWP create and exit events for PT_SYSCALL tracing. PT_SYSCALL disabled EXEC reporting for legacy reasons, there is no need to repeat it for LWP and CHLD events. Pass full siginfo from trapsignal events (SEGV, BUS, ILL, TRAP, FPE). This adds missing information about signals like fault address. Set ps_lwp always. Before passing siginfo to userland through p_sigctx.ps_info, make sure that it was zeroed for unused bytes. LWP and CHLD events do not set si_addr and si_trap, these pieces of information are passed for crashes (like software breakpoint). LLDB crash reporting works now correctly: (lldb) r Process 552 launched: '/tmp/a.out' (x86_64) Process 552 stopped * thread #1, stop reason = signal SIGSEGV: invalid address (fault address: 0x123456) --- sys/kern/kern_lwp.c | 6 +++--- sys/kern/kern_sig.c | 16 ++++++++++++---- sys/kern/sys_lwp.c | 10 +++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/sys/kern/kern_lwp.c b/sys/kern/kern_lwp.c index a2f3777df50b..9edad211591d 100644 --- a/sys/kern/kern_lwp.c +++ b/sys/kern/kern_lwp.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lwp.c,v 1.198 2019/05/01 21:57:34 kamil Exp $ */ +/* $NetBSD: kern_lwp.c,v 1.199 2019/05/02 22:23:49 kamil Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -211,7 +211,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.198 2019/05/01 21:57:34 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.199 2019/05/02 22:23:49 kamil Exp $"); #include "opt_ddb.h" #include "opt_lockdebug.h" @@ -1079,7 +1079,7 @@ lwp_exit(struct lwp *l) */ mutex_enter(proc_lock); - if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_EXIT|PSL_SYSCALL)) == + if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_EXIT)) == (PSL_TRACED|PSL_TRACELWP_EXIT)) { mutex_enter(p->p_lock); p->p_lwp_exited = l->l_lid; diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 189b37b7c317..07d2117e570e 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sig.c,v 1.355 2019/05/01 21:52:35 kamil Exp $ */ +/* $NetBSD: kern_sig.c,v 1.356 2019/05/02 22:23:49 kamil Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.355 2019/05/01 21:52:35 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.356 2019/05/02 22:23:49 kamil Exp $"); #include "opt_ptrace.h" #include "opt_dtrace.h" @@ -913,8 +913,14 @@ trapsignal(struct lwp *l, ksiginfo_t *ksi) mutex_enter(p->p_lock); if (ISSET(p->p_slflag, PSL_TRACED) && - !(p->p_pptr == p->p_opptr && ISSET(p->p_lflag, PL_PPWAIT))) { - eventswitch(signo, ksi->ksi_code); + !(p->p_pptr == p->p_opptr && ISSET(p->p_lflag, PL_PPWAIT)) && + p->p_xsig != SIGKILL && + !sigismember(&p->p_sigpend.sp_set, SIGKILL)) { + p->p_xsig = signo; + p->p_sigctx.ps_faked = true; + p->p_sigctx.ps_lwp = ksi->ksi_lid; + p->p_sigctx.ps_info = ksi->ksi_info; + sigswitch(0, signo, false); // XXX ktrpoint(KTR_PSIG) mutex_exit(p->p_lock); return; @@ -1556,6 +1562,8 @@ eventswitch(int signo, int code) p->p_xsig = signo; p->p_sigctx.ps_faked = true; + p->p_sigctx.ps_lwp = l->l_lid; + memset(&p->p_sigctx.ps_info, 0, sizeof(p->p_sigctx.ps_info)); p->p_sigctx.ps_info._signo = signo; p->p_sigctx.ps_info._code = code; diff --git a/sys/kern/sys_lwp.c b/sys/kern/sys_lwp.c index 9b438d197c28..4bffb017a0fc 100644 --- a/sys/kern/sys_lwp.c +++ b/sys/kern/sys_lwp.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_lwp.c,v 1.65 2019/05/01 22:55:55 kamil Exp $ */ +/* $NetBSD: sys_lwp.c,v 1.66 2019/05/02 22:23:49 kamil Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.65 2019/05/01 22:55:55 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.66 2019/05/02 22:23:49 kamil Exp $"); #include #include @@ -78,12 +78,12 @@ mi_startlwp(void *arg) (p->p_emul->e_startlwp)(arg); /* If the process is traced, report lwp creation to a debugger */ - if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_CREATE|PSL_SYSCALL)) == + if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_CREATE)) == (PSL_TRACED|PSL_TRACELWP_CREATE)) { /* Paranoid check */ mutex_enter(proc_lock); - if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_CREATE|PSL_SYSCALL)) != - (PSL_TRACED|PSL_TRACELWP_CREATE)) { + if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_CREATE)) != + (PSL_TRACED|PSL_TRACELWP_CREATE)) { mutex_exit(proc_lock); return; }