Make a child execute fork_return() only if PTRACE_FORK has been specified.
authormpi <mpi@openbsd.org>
Tue, 23 Mar 2021 10:30:40 +0000 (10:30 +0000)
committermpi <mpi@openbsd.org>
Tue, 23 Mar 2021 10:30:40 +0000 (10:30 +0000)
fork_return() does an additional check to send a SIGTRAP (for a debugger)
but this signal might overwrite the SIGSTOP generated by the parent doing
a PT_ATTACH before the child has a change to execute any instruction.

Prevent a race visible only on SP system with regress/sys/kern/ptrace2.

ok kettenis@

sys/kern/kern_fork.c

index 2c84a9a..9ae645f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_fork.c,v 1.234 2021/02/15 09:35:59 mpi Exp $     */
+/*     $OpenBSD: kern_fork.c,v 1.235 2021/03/23 10:30:40 mpi Exp $     */
 /*     $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $  */
 
 /*
@@ -95,12 +95,15 @@ fork_return(void *arg)
 int
 sys_fork(struct proc *p, void *v, register_t *retval)
 {
+       void (*func)(void *) = child_return;
        int flags;
 
        flags = FORK_FORK;
-       if (p->p_p->ps_ptmask & PTRACE_FORK)
+       if (p->p_p->ps_ptmask & PTRACE_FORK) {
                flags |= FORK_PTRACE;
-       return fork1(p, flags, fork_return, NULL, retval, NULL);
+               func = fork_return;
+       }
+       return fork1(p, flags, func, NULL, retval, NULL);
 }
 
 int