Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F171438367
D30457.id89832.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D30457.id89832.diff
View Options
diff --git a/sys/amd64/linux/linux_ptrace.c b/sys/amd64/linux/linux_ptrace.c
--- a/sys/amd64/linux/linux_ptrace.c
+++ b/sys/amd64/linux/linux_ptrace.c
@@ -70,7 +70,9 @@
#define LINUX_PTRACE_GETSIGINFO 0x4202
#define LINUX_PTRACE_GETREGSET 0x4204
#define LINUX_PTRACE_SEIZE 0x4206
-#define LINUX_PTRACE_GET_SYSCALL_INFO 0x420e
+#define LINUX_PTRACE_INTERRUPT 0x4207
+#define LINUX_PTRACE_LISTEN 0x4208
+#define LINUX_PTRACE_GET_SYSCALL_INFO 0x420e
#define LINUX_PTRACE_EVENT_EXIT 6
@@ -577,14 +579,6 @@
}
}
-static int
-linux_ptrace_seize(struct thread *td, pid_t pid, l_ulong addr, l_ulong data)
-{
-
- linux_msg(td, "PTRACE_SEIZE not implemented; returning EINVAL");
- return (EINVAL);
-}
-
static int
linux_ptrace_get_syscall_info(struct thread *td, pid_t pid, l_ulong addr, l_ulong data)
{
@@ -701,11 +695,18 @@
error = linux_ptrace_getregset(td, pid, uap->addr, uap->data);
break;
case LINUX_PTRACE_SEIZE:
- error = linux_ptrace_seize(td, pid, uap->addr, uap->data);
+ error = linux_ptrace_setoptions(td, pid, uap->data);
+ error = kern_ptrace(td, PT_SEIZE, pid, addr, uap->data);
+ break;
+ case LINUX_PTRACE_INTERRUPT:
+ error = kern_ptrace(td, PT_INTERRUPT, pid, addr, uap->data);
break;
- case LINUX_PTRACE_GET_SYSCALL_INFO:
- error = linux_ptrace_get_syscall_info(td, pid, uap->addr, uap->data);
+ case LINUX_PTRACE_LISTEN:
+ error = kern_ptrace(td, PT_LISTEN, pid, addr, uap->data);
break;
+// case LINUX_PTRACE_GET_SYSCALL_INFO:
+// error = linux_ptrace_get_syscall_info(td, pid, uap->addr, uap->data);
+// break;
default:
linux_msg(td, "ptrace(%ld, ...) not implemented; "
"returning EINVAL", uap->req);
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2884,6 +2884,20 @@
}
}
+
+ if ((p->p_flag & P_TRACED) != 0 &&
+ (p->p_flag2 & P2_SEIZED) != 0 &&
+ SIGISMEMBER(sigpending, SIGKILL)) {
+ /*
+ * If we are seized: linux behavior is to honor
+ * the SIGKILL request without first sending a
+ * STOP signal to the process being debugged.
+ */
+ sig = SIGKILL;
+ //proc_wkilled(p);
+ return (SIGKILL);
+ }
+
if ((p->p_flag & (P_TRACED | P_PPTRACE)) == P_TRACED &&
(p->p_flag2 & P2_PTRACE_FSTP) != 0 &&
SIGISMEMBER(sigpending, SIGSTOP)) {
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
@@ -623,6 +623,8 @@
/* Lock proctree before locking the process. */
switch (req) {
case PT_TRACE_ME:
+ case PT_INTERRUPT:
+ case PT_SEIZE:
case PT_ATTACH:
case PT_STEP:
case PT_CONTINUE:
@@ -709,6 +711,17 @@
* Permissions check
*/
switch (req) {
+ case PT_INTERRUPT:
+ case PT_LISTEN:
+ /*
+ * Only works on tracees attached by PT_SEIZE.
+ */
+ if ((p->p_flag2 & P2_SEIZED) == 0) {
+ error = EINVAL;
+ goto fail;
+ }
+ break;
+
case PT_TRACE_ME:
/*
* Always legal, when there is a parent process which
@@ -724,6 +737,7 @@
}
break;
+ case PT_SEIZE:
case PT_ATTACH:
/* Self */
if (p == td->td_proc) {
@@ -806,6 +820,52 @@
CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid);
break;
+ case PT_SEIZE:
+ proc_set_traced(p, false);
+ proc_reparent(p, td->td_proc, false);
+ CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid,
+ p->p_oppid);
+
+ sx_xunlock(&proctree_lock);
+ proctree_locked = false;
+ MPASS(p->p_xthread == NULL);
+ MPASS((p->p_flag & P_STOPPED_TRACE) == 0);
+
+ p->p_flag2 |= P2_SEIZED;
+
+ /*
+ * XXX Do we actually have to do anything here?
+ */
+ break;
+
+ case PT_INTERRUPT:
+ sx_xunlock(&proctree_lock);
+ proctree_locked = false;
+ MPASS(p->p_xthread == NULL);
+ MPASS((p->p_flag & P_STOPPED_TRACE) == 0);
+
+ /*
+ * If already stopped due to a stop signal, clear the
+ * existing stop before triggering a traced SIGSTOP.
+ */
+ if ((p->p_flag & P_STOPPED_SIG) != 0) {
+ PROC_SLOCK(p);
+ p->p_flag &= ~(P_STOPPED_SIG | P_WAITED);
+ thread_unsuspend(p);
+ PROC_SUNLOCK(p);
+ }
+
+ kern_psignal(p, SIGSTOP);
+ break;
+
+ case PT_LISTEN:
+ // XXX not sure
+ td2->td_dbgflags |= TDB_SUSPEND;
+ thread_lock(td2);
+ td2->td_flags |= TDF_NEEDSUSPCHK;
+ thread_unlock(td2);
+ break;
+
case PT_ATTACH:
/* security check done above */
/*
@@ -817,7 +877,7 @@
* The old parent is remembered so we can put things back
* on a "detach".
*/
- proc_set_traced(p, true);
+ proc_set_traced(p, req == PT_ATTACH);
proc_reparent(p, td->td_proc, false);
CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid,
p->p_oppid);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -813,6 +813,7 @@
MAP_STACK */
#define P2_STKGAP_DISABLE_EXEC 0x00001000 /* Stack gap disabled
after exec */
+#define P2_SEIZED 0x00008000 /* Linux behaviour 'seize'. */
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -83,6 +83,9 @@
#define PT_VM_TIMESTAMP 40 /* Get VM version (timestamp) */
#define PT_VM_ENTRY 41 /* Get VM map (entry) */
+#define PT_SEIZE 42 /* like attach but do not stop */
+#define PT_INTERRUPT 43 /* */
+#define PT_LISTEN 44 /* */
#define PT_FIRSTMACH 64 /* for machine-specific requests */
#include <machine/ptrace.h> /* machine-specific requests, if any */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Sep 12, 3:30 AM (2 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38731795
Default Alt Text
D30457.id89832.diff (5 KB)
Attached To
Mode
D30457: linuxulator: Some ptrace fixes..
Attached
Detach File
Event Timeline
Log In to Comment