Module Name: src Committed By: kamil Date: Thu Oct 3 22:48:44 UTC 2019
Modified Files: src/sys/kern: kern_exit.c kern_lwp.c kern_sig.c kern_synch.c sys_ptrace_common.c Log Message: Separate flag for suspended by _lwp_suspend and suspended by a debugger Once a thread was stopped with ptrace(2), userland process must not be able to unstop it deliberately or by an accident. This was a Windows-style behavior that makes threading tracing fragile. To generate a diff of this commit: cvs rdiff -u -r1.276 -r1.277 src/sys/kern/kern_exit.c cvs rdiff -u -r1.203 -r1.204 src/sys/kern/kern_lwp.c cvs rdiff -u -r1.365 -r1.366 src/sys/kern/kern_sig.c cvs rdiff -u -r1.323 -r1.324 src/sys/kern/kern_synch.c cvs rdiff -u -r1.61 -r1.62 src/sys/kern/sys_ptrace_common.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_exit.c diff -u src/sys/kern/kern_exit.c:1.276 src/sys/kern/kern_exit.c:1.277 --- src/sys/kern/kern_exit.c:1.276 Thu Jun 13 20:20:18 2019 +++ src/sys/kern/kern_exit.c Thu Oct 3 22:48:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exit.c,v 1.276 2019/06/13 20:20:18 kamil Exp $ */ +/* $NetBSD: kern_exit.c,v 1.277 2019/10/03 22:48:44 kamil Exp $ */ /*- * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.276 2019/06/13 20:20:18 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.277 2019/10/03 22:48:44 kamil Exp $"); #include "opt_ktrace.h" #include "opt_dtrace.h" @@ -617,6 +617,7 @@ retry: l2->l_flag |= LW_WEXIT; if ((l2->l_stat == LSSLEEP && (l2->l_flag & LW_SINTR)) || l2->l_stat == LSSUSPENDED || l2->l_stat == LSSTOP) { + l2->l_flag &= ~LW_DBGSUSPEND; /* setrunnable() will release the lock. */ setrunnable(l2); continue; Index: src/sys/kern/kern_lwp.c diff -u src/sys/kern/kern_lwp.c:1.203 src/sys/kern/kern_lwp.c:1.204 --- src/sys/kern/kern_lwp.c:1.203 Mon Sep 30 21:13:33 2019 +++ src/sys/kern/kern_lwp.c Thu Oct 3 22:48:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lwp.c,v 1.203 2019/09/30 21:13:33 kamil Exp $ */ +/* $NetBSD: kern_lwp.c,v 1.204 2019/10/03 22:48:44 kamil Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -211,7 +211,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.203 2019/09/30 21:13:33 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.204 2019/10/03 22:48:44 kamil Exp $"); #include "opt_ddb.h" #include "opt_lockdebug.h" @@ -408,6 +408,11 @@ lwp_suspend(struct lwp *curl, struct lwp return (EDEADLK); } + if ((t->l_flag & LW_DBGSUSPEND) != 0) { + lwp_unlock(t); + return 0; + } + error = 0; switch (t->l_stat) { @@ -472,7 +477,7 @@ lwp_continue(struct lwp *l) l->l_flag &= ~LW_WSUSPEND; - if (l->l_stat != LSSUSPENDED) { + if (l->l_stat != LSSUSPENDED || (l->l_flag & LW_DBGSUSPEND) != 0) { lwp_unlock(l); return; } @@ -497,6 +502,8 @@ lwp_unstop(struct lwp *l) lwp_lock(l); + KASSERT((l->l_flag & LW_DBGSUSPEND) == 0); + /* If not stopped, then just bail out. */ if (l->l_stat != LSSTOP) { lwp_unlock(l); Index: src/sys/kern/kern_sig.c diff -u src/sys/kern/kern_sig.c:1.365 src/sys/kern/kern_sig.c:1.366 --- src/sys/kern/kern_sig.c:1.365 Mon Sep 30 21:13:33 2019 +++ src/sys/kern/kern_sig.c Thu Oct 3 22:48:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sig.c,v 1.365 2019/09/30 21:13:33 kamil Exp $ */ +/* $NetBSD: kern_sig.c,v 1.366 2019/10/03 22:48:44 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.365 2019/09/30 21:13:33 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.366 2019/10/03 22:48:44 kamil Exp $"); #include "opt_ptrace.h" #include "opt_dtrace.h" @@ -1108,11 +1108,20 @@ sigpost(struct lwp *l, sig_t action, int SDT_PROBE(proc, kernel, , signal__send, l, p, sig, 0, 0); + lwp_lock(l); + if (__predict_false((l->l_flag & LW_DBGSUSPEND) != 0)) { + if ((prop & SA_KILL) != 0) + l->l_flag &= ~LW_DBGSUSPEND; + else { + lwp_unlock(l); + return 0; + } + } + /* * Have the LWP check for signals. This ensures that even if no LWP * is found to take the signal immediately, it should be taken soon. */ - lwp_lock(l); l->l_flag |= LW_PENDSIG; /* @@ -2179,7 +2188,8 @@ sigexit(struct lwp *l, int signo) LIST_FOREACH(t, &p->p_lwps, l_sibling) { lwp_lock(t); if (t == l) { - t->l_flag &= ~LW_WSUSPEND; + t->l_flag &= + ~(LW_WSUSPEND | LW_DBGSUSPEND); lwp_unlock(t); continue; } @@ -2376,7 +2386,7 @@ proc_unstop(struct proc *p) LIST_FOREACH(l, &p->p_lwps, l_sibling) { lwp_lock(l); - if (l->l_stat != LSSTOP) { + if (l->l_stat != LSSTOP || (l->l_flag & LW_DBGSUSPEND) != 0) { lwp_unlock(l); continue; } Index: src/sys/kern/kern_synch.c diff -u src/sys/kern/kern_synch.c:1.323 src/sys/kern/kern_synch.c:1.324 --- src/sys/kern/kern_synch.c:1.323 Sun Feb 3 03:19:28 2019 +++ src/sys/kern/kern_synch.c Thu Oct 3 22:48:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_synch.c,v 1.323 2019/02/03 03:19:28 mrg Exp $ */ +/* $NetBSD: kern_synch.c,v 1.324 2019/10/03 22:48:44 kamil Exp $ */ /*- * Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009 @@ -69,7 +69,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.323 2019/02/03 03:19:28 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.324 2019/10/03 22:48:44 kamil Exp $"); #include "opt_kstack.h" #include "opt_dtrace.h" @@ -885,6 +885,7 @@ setrunnable(struct lwp *l) struct cpu_info *ci; KASSERT((l->l_flag & LW_IDLE) == 0); + KASSERT((l->l_flag & LW_DBGSUSPEND) == 0); KASSERT(mutex_owned(p->p_lock)); KASSERT(lwp_locked(l, NULL)); KASSERT(l->l_mutex != l->l_cpu->ci_schedstate.spc_mutex); Index: src/sys/kern/sys_ptrace_common.c diff -u src/sys/kern/sys_ptrace_common.c:1.61 src/sys/kern/sys_ptrace_common.c:1.62 --- src/sys/kern/sys_ptrace_common.c:1.61 Tue Oct 1 21:49:50 2019 +++ src/sys/kern/sys_ptrace_common.c Thu Oct 3 22:48:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_ptrace_common.c,v 1.61 2019/10/01 21:49:50 kamil Exp $ */ +/* $NetBSD: sys_ptrace_common.c,v 1.62 2019/10/03 22:48:44 kamil Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -118,7 +118,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.61 2019/10/01 21:49:50 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.62 2019/10/03 22:48:44 kamil Exp $"); #ifdef _KERNEL_OPT #include "opt_ptrace.h" @@ -787,9 +787,12 @@ ptrace_startstop(struct proc *t, struct DPRINTF(("%s: lwp=%d request=%d\n", __func__, (*lt)->l_lid, rq)); lwp_lock(*lt); if (rq == PT_SUSPEND) - (*lt)->l_flag |= LW_WSUSPEND; - else - (*lt)->l_flag &= ~LW_WSUSPEND; + (*lt)->l_flag |= LW_DBGSUSPEND; + else { + (*lt)->l_flag &= ~LW_DBGSUSPEND; + if ((*lt)->l_flag != LSSUSPENDED) + (*lt)->l_stat = LSSTOP; + } lwp_unlock(*lt); return 0; } @@ -1233,7 +1236,8 @@ do_ptrace(struct ptrace_methods *ptm, st if (resume_all) { #ifdef PT_STEP if (req == PT_STEP) { - if (lt->l_flag & LW_WSUSPEND) { + if (lt->l_flag & + (LW_WSUSPEND | LW_DBGSUSPEND)) { error = EDEADLK; break; } @@ -1242,7 +1246,9 @@ do_ptrace(struct ptrace_methods *ptm, st { error = EDEADLK; LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { - if ((lt2->l_flag & LW_WSUSPEND) == 0) { + if ((lt2->l_flag & + (LW_WSUSPEND | LW_DBGSUSPEND)) == 0 + ) { error = 0; break; } @@ -1251,7 +1257,7 @@ do_ptrace(struct ptrace_methods *ptm, st break; } } else { - if (lt->l_flag & LW_WSUSPEND) { + if (lt->l_flag & (LW_WSUSPEND | LW_WSUSPEND)) { error = EDEADLK; break; }