summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2001-06-18 08:17:47 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2001-06-18 08:17:47 +0000
commite0e5bdc12c236f0ebb2829c2716e1dc148e568a4 (patch)
tree10175810742057f53d0634f77f60e902c684b4d3 /sys
parent59e50ace281d97c3d5734668a48766f8ea1abf93 (diff)
split PT_DETACH handling, so that pc cannot be set by it; art ok
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_process.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index bbe5b104ca3..b22ac8fc097 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_process.c,v 1.10 2001/04/09 07:14:18 tholo Exp $ */
+/* $OpenBSD: sys_process.c,v 1.11 2001/06/18 08:17:46 deraadt Exp $ */
/* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
/*-
@@ -243,7 +243,6 @@ sys_ptrace(p, v, retval)
*/
#endif
case PT_CONTINUE:
- case PT_DETACH:
/*
* From the 4.4BSD PRM:
* "The data argument is taken as a signal number and the
@@ -261,7 +260,6 @@ sys_ptrace(p, v, retval)
return (EINVAL);
PHOLD(t);
-
#ifdef PT_STEP
/*
* Arrange for a single-step, if that's requested and possible.
@@ -275,23 +273,49 @@ sys_ptrace(p, v, retval)
if ((int *)SCARG(uap, addr) != (int *)1)
if ((error = process_set_pc(t, SCARG(uap, addr))) != 0)
goto relebad;
-
PRELE(t);
+ goto sendsig;
+
+ case PT_DETACH:
+ /*
+ * From the 4.4BSD PRM:
+ * "The data argument is taken as a signal number and the
+ * child's execution continues at location addr as if it
+ * incurred that signal. Normally the signal number will
+ * be either 0 to indicate that the signal that caused the
+ * stop should be ignored, or that value fetched out of
+ * the process's image indicating which signal caused
+ * the stop. If addr is (int *)1 then execution continues
+ * from where it stopped."
+ */
+
+ /* Check that the data is a valid signal number or zero. */
+ if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
+ return (EINVAL);
- if (SCARG(uap, req) == PT_DETACH) {
- /* give process back to original parent or init */
- if (t->p_oppid != t->p_pptr->p_pid) {
- struct proc *pp;
+ PHOLD(t);
+#ifdef PT_STEP
+ /*
+ * Arrange for a single-step, if that's requested and possible.
+ */
+ error = process_sstep(t, SCARG(uap, req) == PT_STEP);
+ if (error)
+ goto relebad;
+#endif
+ PRELE(t);
- pp = pfind(t->p_oppid);
- proc_reparent(t, pp ? pp : initproc);
- }
+ /* give process back to original parent or init */
+ if (t->p_oppid != t->p_pptr->p_pid) {
+ struct proc *pp;
- /* not being traced any more */
- t->p_oppid = 0;
- CLR(t->p_flag, P_TRACED|P_WAITED);
+ pp = pfind(t->p_oppid);
+ proc_reparent(t, pp ? pp : initproc);
}
+ /* not being traced any more */
+ t->p_oppid = 0;
+ CLR(t->p_flag, P_TRACED|P_WAITED);
+
sendsig:
/* Finally, deliver the requested signal (or none). */
if (t->p_stat == SSTOP) {