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;
}