Page MenuHomeFreeBSD

D30351.id89544.diff
No OneTemporary

D30351.id89544.diff

diff --git a/lib/libc/sys/ptrace.2 b/lib/libc/sys/ptrace.2
--- a/lib/libc/sys/ptrace.2
+++ b/lib/libc/sys/ptrace.2
@@ -2,7 +2,7 @@
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
.\"
.\" This file is in the public domain.
-.Dd May 4, 2021
+.Dd May 20, 2021
.Dt PTRACE 2
.Os
.Sh NAME
@@ -100,6 +100,18 @@
All other additional signal stops use
.Dv SIGTRAP .
.Pp
+Normally, tracing process should detach from all traced processes
+before exiting using
+.Dv PT_DETACH
+request.
+If tracing process exits without detaching, for instance due to abnormal
+termination, the destiny of the traced processes is determined by the
+.Dv kern.kill_on_debugger_exit
+sysctl value.
+If it is set to the default value 1, such traced processes are terminated.
+If set to zero, kernel implicitly detaches tracing process, traced processes
+are continued if stopped, and then continue the execution without tracing.
+.Pp
Each traced process has a tracing event mask.
An event in the traced process only reports a
signal stop if the corresponding flag is set in the tracing event mask.
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -66,6 +66,7 @@
#include <sys/sched.h>
#include <sys/sx.h>
#include <sys/syscallsubr.h>
+#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/ptrace.h>
#include <sys/acct.h> /* for acct_process() function prototype */
@@ -99,6 +100,11 @@
SDT_PROVIDER_DECLARE(proc);
SDT_PROBE_DEFINE1(proc, , , exit, "int");
+static int kern_kill_on_dbg_exit = 1;
+SYSCTL_INT(_kern, OID_AUTO, kill_on_debugger_exit, CTLFLAG_RWTUN,
+ &kern_kill_on_dbg_exit, 0,
+ "Kill ptraced processes when debugger exits");
+
struct proc *
proc_realparent(struct proc *child)
{
@@ -504,8 +510,9 @@
}
} else {
/*
- * Traced processes are killed since their existence
- * means someone is screwing up.
+ * Traced processes are killed by default
+ * since their existence means someone is
+ * screwing up.
*/
t = proc_realparent(q);
if (t == p) {
@@ -522,14 +529,20 @@
* orphan link for q now while q is locked.
*/
proc_clear_orphan(q);
- q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
+ q->p_flag &= ~P_TRACED;
q->p_flag2 &= ~P2_PTRACE_FSTP;
q->p_ptevents = 0;
FOREACH_THREAD_IN_PROC(q, tdt) {
tdt->td_dbgflags &= ~(TDB_SUSPEND | TDB_XSIG |
TDB_FSTP);
}
- kern_psignal(q, SIGKILL);
+ if (kern_kill_on_dbg_exit) {
+ q->p_flag &= ~P_STOPPED_TRACE;
+ kern_psignal(q, SIGKILL);
+ } else if ((q->p_flag & (P_STOPPED_TRACE |
+ P_STOPPED_SIG)) != 0) {
+ ptrace_unsuspend(q);
+ }
}
PROC_UNLOCK(q);
if (ksi != NULL)
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -610,6 +610,19 @@
p->p_ptevents = PTRACE_DEFAULT;
}
+void
+ptrace_unsuspend(struct proc *p)
+{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ PROC_SLOCK(p);
+ p->p_flag &= ~(P_STOPPED_TRACE | P_STOPPED_SIG | P_WAITED);
+ thread_unsuspend(p);
+ PROC_SUNLOCK(p);
+ itimer_proc_continue(p);
+ kqtimer_proc_continue(p);
+}
+
static int
proc_can_ptrace(struct thread *td, struct proc *p)
{
@@ -1164,12 +1177,7 @@
* suspended, use PT_SUSPEND to suspend it before
* continuing the process.
*/
- PROC_SLOCK(p);
- p->p_flag &= ~(P_STOPPED_TRACE | P_STOPPED_SIG | P_WAITED);
- thread_unsuspend(p);
- PROC_SUNLOCK(p);
- itimer_proc_continue(p);
- kqtimer_proc_continue(p);
+ ptrace_unsuspend(p);
break;
case PT_WRITE_I:
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -240,6 +240,9 @@
int proc_read_dbregs32(struct thread *_td, struct dbreg32 *_dbreg32);
int proc_write_dbregs32(struct thread *_td, struct dbreg32 *_dbreg32);
#endif
+
+void ptrace_unsuspend(struct proc *p);
+
#else /* !_KERNEL */
#include <sys/cdefs.h>

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 14, 9:27 AM (18 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29642568
Default Alt Text
D30351.id89544.diff (3 KB)

Event Timeline