xref: /netbsd-src/tests/lib/libc/sys/t_ptrace_fork_wait.h (revision db4bf4da471b2f504f1f79ae20c31b6624b28f44)
1 /*	$NetBSD: t_ptrace_fork_wait.h,v 1.7 2020/06/09 00:28:57 kamil Exp $	*/
2 
3 /*-
4  * Copyright (c) 2016, 2017, 2018, 2020 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 static void
fork_body(const char * fn,bool trackspawn,bool trackfork,bool trackvfork,bool trackvforkdone,bool newpgrp)31 fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork,
32     bool trackvforkdone, bool newpgrp)
33 {
34 	const int exitval = 5;
35 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
36 	const int sigval = SIGSTOP;
37 	pid_t child, child2 = 0, wpid;
38 #if defined(TWAIT_HAVE_STATUS)
39 	int status;
40 #endif
41 	sigset_t set;
42 	ptrace_state_t state;
43 	const int slen = sizeof(state);
44 	ptrace_event_t event;
45 	const int elen = sizeof(event);
46 
47 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
48 
49 	if (newpgrp)
50 		atf_tc_skip("kernel panic (pg_jobc going negative)");
51 
52 	DPRINTF("Before forking process PID=%d\n", getpid());
53 	SYSCALL_REQUIRE((child = fork()) != -1);
54 	if (child == 0) {
55 		if (newpgrp) {
56 			DPRINTF("Before entering new process group");
57 			setpgid(0, 0);
58 		}
59 
60 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62 
63 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64 		FORKEE_ASSERT(raise(sigval) == 0);
65 
66 		if (strcmp(fn, "spawn") == 0) {
67 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
68 			    arg[0], NULL, NULL, arg, NULL), 0);
69 		} else {
70 			if (strcmp(fn, "fork") == 0) {
71 				FORKEE_ASSERT((child2 = fork()) != -1);
72 			} else if (strcmp(fn, "vfork") == 0) {
73 				FORKEE_ASSERT((child2 = vfork()) != -1);
74 			}
75 
76 			if (child2 == 0)
77 				_exit(exitval2);
78 		}
79 		FORKEE_REQUIRE_SUCCESS
80 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
81 
82 		forkee_status_exited(status, exitval2);
83 
84 		DPRINTF("Before exiting of the child process\n");
85 		_exit(exitval);
86 	}
87 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
88 
89 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
90 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
91 
92 	validate_status_stopped(status, sigval);
93 
94 	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
95 	    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
96 	    trackfork ? "|PTRACE_FORK" : "",
97 	    trackvfork ? "|PTRACE_VFORK" : "",
98 	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
99 	event.pe_set_event = 0;
100 	if (trackspawn)
101 		event.pe_set_event |= PTRACE_POSIX_SPAWN;
102 	if (trackfork)
103 		event.pe_set_event |= PTRACE_FORK;
104 	if (trackvfork)
105 		event.pe_set_event |= PTRACE_VFORK;
106 	if (trackvforkdone)
107 		event.pe_set_event |= PTRACE_VFORK_DONE;
108 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
109 
110 	/*
111 	 * Ignore interception of the SIGCHLD signals.
112 	 *
113 	 * SIGCHLD once blocked is discarded by the kernel as it has the
114 	 * SA_IGNORE property. During the fork(2) operation all signals can be
115 	 * shortly blocked and missed (unless there is a registered signal
116 	 * handler in the traced child). This leads to a race in this test if
117 	 * there would be an intention to catch SIGCHLD.
118 	 */
119 	sigemptyset(&set);
120 	sigaddset(&set, SIGCHLD);
121 	SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1);
122 
123 	DPRINTF("Before resuming the child process where it left off and "
124 	    "without signal to be sent\n");
125 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
126 
127 #if defined(TWAIT_HAVE_PID)
128 	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
129 	    (trackfork && strcmp(fn, "fork") == 0) ||
130 	    (trackvfork && strcmp(fn, "vfork") == 0)) {
131 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
132 		    child);
133 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
134 		    child);
135 
136 		validate_status_stopped(status, SIGTRAP);
137 
138 		SYSCALL_REQUIRE(
139 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
140 		if (trackspawn && strcmp(fn, "spawn") == 0) {
141 			ATF_REQUIRE_EQ(
142 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
143 			       PTRACE_POSIX_SPAWN);
144 		}
145 		if (trackfork && strcmp(fn, "fork") == 0) {
146 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
147 			       PTRACE_FORK);
148 		}
149 		if (trackvfork && strcmp(fn, "vfork") == 0) {
150 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
151 			       PTRACE_VFORK);
152 		}
153 
154 		child2 = state.pe_other_pid;
155 		DPRINTF("Reported ptrace event with forkee %d\n", child2);
156 
157 		DPRINTF("Before calling %s() for the forkee %d of the child "
158 		    "%d\n", TWAIT_FNAME, child2, child);
159 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
160 		    child2);
161 
162 		validate_status_stopped(status, SIGTRAP);
163 
164 		SYSCALL_REQUIRE(
165 		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
166 		if (trackspawn && strcmp(fn, "spawn") == 0) {
167 			ATF_REQUIRE_EQ(
168 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
169 			       PTRACE_POSIX_SPAWN);
170 		}
171 		if (trackfork && strcmp(fn, "fork") == 0) {
172 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
173 			       PTRACE_FORK);
174 		}
175 		if (trackvfork && strcmp(fn, "vfork") == 0) {
176 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
177 			       PTRACE_VFORK);
178 		}
179 
180 		ATF_REQUIRE_EQ(state.pe_other_pid, child);
181 
182 		DPRINTF("Before resuming the forkee process where it left off "
183 		    "and without signal to be sent\n");
184 		SYSCALL_REQUIRE(
185 		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
186 
187 		DPRINTF("Before resuming the child process where it left off "
188 		    "and without signal to be sent\n");
189 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
190 	}
191 #endif
192 
193 	if (trackvforkdone && strcmp(fn, "vfork") == 0) {
194 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
195 		    child);
196 		TWAIT_REQUIRE_SUCCESS(
197 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
198 
199 		validate_status_stopped(status, SIGTRAP);
200 
201 		SYSCALL_REQUIRE(
202 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
203 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
204 
205 		child2 = state.pe_other_pid;
206 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
207 		    child2);
208 
209 		DPRINTF("Before resuming the child process where it left off "
210 		    "and without signal to be sent\n");
211 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
212 	}
213 
214 #if defined(TWAIT_HAVE_PID)
215 	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
216 	    (trackfork && strcmp(fn, "fork") == 0) ||
217 	    (trackvfork && strcmp(fn, "vfork") == 0)) {
218 		DPRINTF("Before calling %s() for the forkee - expected exited"
219 		    "\n", TWAIT_FNAME);
220 		TWAIT_REQUIRE_SUCCESS(
221 		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
222 
223 		validate_status_exited(status, exitval2);
224 
225 		DPRINTF("Before calling %s() for the forkee - expected no "
226 		    "process\n", TWAIT_FNAME);
227 		TWAIT_REQUIRE_FAILURE(ECHILD,
228 		    wpid = TWAIT_GENERIC(child2, &status, 0));
229 	}
230 #endif
231 
232 	DPRINTF("Before calling %s() for the child - expected exited\n",
233 	    TWAIT_FNAME);
234 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
235 
236 	validate_status_exited(status, exitval);
237 
238 	DPRINTF("Before calling %s() for the child - expected no process\n",
239 	    TWAIT_FNAME);
240 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
241 }
242 
243 #define FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp)	\
244 ATF_TC(name);								\
245 ATF_TC_HEAD(name, tc)							\
246 {									\
247 	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
248 	    "called with 0%s%s%s%s in EVENT_MASK%s",			\
249 	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
250 	    tfork ? "|PTRACE_FORK" : "",				\
251 	    tvfork ? "|PTRACE_VFORK" : "",				\
252 	    tvforkdone ? "|PTRACE_VFORK_DONE" : "",			\
253 	    newpgrp ? " and the traced processes call setpgrp(0,0)":"");\
254 }									\
255 									\
256 ATF_TC_BODY(name, tc)							\
257 {									\
258 									\
259 	fork_body(fun, tspawn, tfork, tvfork, tvforkdone, newpgrp);	\
260 }
261 
262 #define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)		\
263 	FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false)
264 
265 FORK_TEST(fork1, "fork", false, false, false, false)
266 #if defined(TWAIT_HAVE_PID)
267 FORK_TEST(fork2, "fork", false, true, false, false)
268 FORK_TEST(fork3, "fork", false, false, true, false)
269 FORK_TEST(fork4, "fork", false, true, true, false)
270 #endif
271 FORK_TEST(fork5, "fork", false, false, false, true)
272 #if defined(TWAIT_HAVE_PID)
273 FORK_TEST(fork6, "fork", false, true, false, true)
274 FORK_TEST(fork7, "fork", false, false, true, true)
275 FORK_TEST(fork8, "fork", false, true, true, true)
276 #endif
277 FORK_TEST(fork9, "fork", true, false, false, false)
278 #if defined(TWAIT_HAVE_PID)
279 FORK_TEST(fork10, "fork", true, true, false, false)
280 FORK_TEST(fork11, "fork", true, false, true, false)
281 FORK_TEST(fork12, "fork", true, true, true, false)
282 #endif
283 FORK_TEST(fork13, "fork", true, false, false, true)
284 #if defined(TWAIT_HAVE_PID)
285 FORK_TEST(fork14, "fork", true, true, false, true)
286 FORK_TEST(fork15, "fork", true, false, true, true)
287 FORK_TEST(fork16, "fork", true, true, true, true)
288 #endif
289 
290 #if defined(TWAIT_HAVE_PID)
291 FORK_TEST2(fork_setpgid, "fork", true, true, true, true, true)
292 #endif
293 
294 FORK_TEST(vfork1, "vfork", false, false, false, false)
295 #if defined(TWAIT_HAVE_PID)
296 FORK_TEST(vfork2, "vfork", false, true, false, false)
297 FORK_TEST(vfork3, "vfork", false, false, true, false)
298 FORK_TEST(vfork4, "vfork", false, true, true, false)
299 #endif
300 FORK_TEST(vfork5, "vfork", false, false, false, true)
301 #if defined(TWAIT_HAVE_PID)
302 FORK_TEST(vfork6, "vfork", false, true, false, true)
303 FORK_TEST(vfork7, "vfork", false, false, true, true)
304 FORK_TEST(vfork8, "vfork", false, true, true, true)
305 #endif
306 FORK_TEST(vfork9, "vfork", true, false, false, false)
307 #if defined(TWAIT_HAVE_PID)
308 FORK_TEST(vfork10, "vfork", true, true, false, false)
309 FORK_TEST(vfork11, "vfork", true, false, true, false)
310 FORK_TEST(vfork12, "vfork", true, true, true, false)
311 #endif
312 FORK_TEST(vfork13, "vfork", true, false, false, true)
313 #if defined(TWAIT_HAVE_PID)
314 FORK_TEST(vfork14, "vfork", true, true, false, true)
315 FORK_TEST(vfork15, "vfork", true, false, true, true)
316 FORK_TEST(vfork16, "vfork", true, true, true, true)
317 #endif
318 
319 #if defined(TWAIT_HAVE_PID)
320 FORK_TEST2(vfork_setpgid, "vfork", true, true, true, true, true)
321 #endif
322 
323 FORK_TEST(posix_spawn1, "spawn", false, false, false, false)
324 FORK_TEST(posix_spawn2, "spawn", false, true, false, false)
325 FORK_TEST(posix_spawn3, "spawn", false, false, true, false)
326 FORK_TEST(posix_spawn4, "spawn", false, true, true, false)
327 FORK_TEST(posix_spawn5, "spawn", false, false, false, true)
328 FORK_TEST(posix_spawn6, "spawn", false, true, false, true)
329 FORK_TEST(posix_spawn7, "spawn", false, false, true, true)
330 FORK_TEST(posix_spawn8, "spawn", false, true, true, true)
331 #if defined(TWAIT_HAVE_PID)
332 FORK_TEST(posix_spawn9, "spawn", true, false, false, false)
333 FORK_TEST(posix_spawn10, "spawn", true, true, false, false)
334 FORK_TEST(posix_spawn11, "spawn", true, false, true, false)
335 FORK_TEST(posix_spawn12, "spawn", true, true, true, false)
336 FORK_TEST(posix_spawn13, "spawn", true, false, false, true)
337 FORK_TEST(posix_spawn14, "spawn", true, true, false, true)
338 FORK_TEST(posix_spawn15, "spawn", true, false, true, true)
339 FORK_TEST(posix_spawn16, "spawn", true, true, true, true)
340 #endif
341 
342 #if defined(TWAIT_HAVE_PID)
343 FORK_TEST2(posix_spawn_setpgid, "spawn", true, true, true, true, true)
344 #endif
345 
346 /// ----------------------------------------------------------------------------
347 
348 #if defined(TWAIT_HAVE_PID)
349 static void
unrelated_tracer_fork_body(const char * fn,bool trackspawn,bool trackfork,bool trackvfork,bool trackvforkdone,bool newpgrp)350 unrelated_tracer_fork_body(const char *fn, bool trackspawn, bool trackfork,
351     bool trackvfork, bool trackvforkdone, bool newpgrp)
352 {
353 	const int sigval = SIGSTOP;
354 	struct msg_fds parent_tracee, parent_tracer;
355 	const int exitval = 10;
356 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
357 	pid_t tracee, tracer, wpid;
358 	pid_t tracee2 = 0;
359 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
360 #if defined(TWAIT_HAVE_STATUS)
361 	int status;
362 #endif
363 
364 	sigset_t set;
365 	struct ptrace_siginfo info;
366 	ptrace_state_t state;
367 	const int slen = sizeof(state);
368 	ptrace_event_t event;
369 	const int elen = sizeof(event);
370 
371 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
372 
373 	if (newpgrp)
374 		atf_tc_skip("kernel panic (pg_jobc going negative)");
375 
376 	DPRINTF("Spawn tracee\n");
377 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
378 	tracee = atf_utils_fork();
379 	if (tracee == 0) {
380 		if (newpgrp) {
381 			DPRINTF("Before entering new process group");
382 			setpgid(0, 0);
383 		}
384 
385 		// Wait for parent to let us crash
386 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
387 
388 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
389 		FORKEE_ASSERT(raise(sigval) == 0);
390 
391 		if (strcmp(fn, "spawn") == 0) {
392 			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
393 			    arg[0], NULL, NULL, arg, NULL), 0);
394 		} else {
395 			if (strcmp(fn, "fork") == 0) {
396 				FORKEE_ASSERT((tracee2 = fork()) != -1);
397 			} else if (strcmp(fn, "vfork") == 0) {
398 				FORKEE_ASSERT((tracee2 = vfork()) != -1);
399 			}
400 
401 			if (tracee2 == 0)
402 				_exit(exitval2);
403 		}
404 		FORKEE_REQUIRE_SUCCESS
405 		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
406 
407 		forkee_status_exited(status, exitval2);
408 
409 		DPRINTF("Before exiting of the child process\n");
410 		_exit(exitval);
411 	}
412 
413 	DPRINTF("Spawn debugger\n");
414 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
415 	tracer = atf_utils_fork();
416 	if (tracer == 0) {
417 		/* Fork again and drop parent to reattach to PID 1 */
418 		tracer = atf_utils_fork();
419 		if (tracer != 0)
420 			_exit(exitval);
421 
422 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
423 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
424 
425 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
426 		FORKEE_REQUIRE_SUCCESS(
427 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
428 
429 		forkee_status_stopped(status, SIGSTOP);
430 
431 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
432 		    "traced process\n");
433 		SYSCALL_REQUIRE(
434 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
435 
436 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
437 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
438 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
439 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
440 
441 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
442 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
443 
444 		/* Resume tracee with PT_CONTINUE */
445 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
446 
447 		/* Inform parent that tracer has attached to tracee */
448 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
449 
450 		/* Wait for parent to tell use that tracee should have exited */
451 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
452 
453 		/* Wait for tracee and assert that it exited */
454 		FORKEE_REQUIRE_SUCCESS(
455 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
456 
457 		forkee_status_stopped(status, sigval);
458 
459 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
460 		    "traced process\n");
461 		SYSCALL_REQUIRE(
462 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
463 
464 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
465 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
466 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
467 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
468 
469 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
470 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
471 
472 		DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
473 		    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
474 		    trackfork ? "|PTRACE_FORK" : "",
475 		    trackvfork ? "|PTRACE_VFORK" : "",
476 		    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", tracee);
477 		event.pe_set_event = 0;
478 		if (trackspawn)
479 			event.pe_set_event |= PTRACE_POSIX_SPAWN;
480 		if (trackfork)
481 			event.pe_set_event |= PTRACE_FORK;
482 		if (trackvfork)
483 			event.pe_set_event |= PTRACE_VFORK;
484 		if (trackvforkdone)
485 			event.pe_set_event |= PTRACE_VFORK_DONE;
486 		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen)
487 		    != -1);
488 
489 		/*
490 		 * Ignore interception of the SIGCHLD signals.
491 		 *
492 		 * SIGCHLD once blocked is discarded by the kernel as it has the
493 		 * SA_IGNORE property. During the fork(2) operation all signals
494 		 * can be shortly blocked and missed (unless there is a
495 		 * registered signal handler in the traced child). This leads to
496 		 * a race in this test if there would be an intention to catch
497 		 * SIGCHLD.
498 		 */
499 		sigemptyset(&set);
500 		sigaddset(&set, SIGCHLD);
501 		SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, tracee, &set,
502 		    sizeof(set)) != -1);
503 
504 		DPRINTF("Before resuming the child process where it left off "
505 		    "and without signal to be sent\n");
506 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
507 
508 		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
509 		    (trackfork && strcmp(fn, "fork") == 0) ||
510 		    (trackvfork && strcmp(fn, "vfork") == 0)) {
511 			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
512 			    tracee);
513 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
514 			    tracee);
515 
516 			validate_status_stopped(status, SIGTRAP);
517 
518 			SYSCALL_REQUIRE(
519 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
520 			if (trackspawn && strcmp(fn, "spawn") == 0) {
521 				ATF_REQUIRE_EQ(
522 				    state.pe_report_event & PTRACE_POSIX_SPAWN,
523 				       PTRACE_POSIX_SPAWN);
524 			}
525 			if (trackfork && strcmp(fn, "fork") == 0) {
526 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
527 				       PTRACE_FORK);
528 			}
529 			if (trackvfork && strcmp(fn, "vfork") == 0) {
530 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
531 				       PTRACE_VFORK);
532 			}
533 
534 			tracee2 = state.pe_other_pid;
535 			DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
536 
537 			DPRINTF("Before calling %s() for the forkee %d of the tracee "
538 			    "%d\n", TWAIT_FNAME, tracee2, tracee);
539 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0),
540 			    tracee2);
541 
542 			validate_status_stopped(status, SIGTRAP);
543 
544 			SYSCALL_REQUIRE(
545 			    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
546 			if (trackspawn && strcmp(fn, "spawn") == 0) {
547 				ATF_REQUIRE_EQ(
548 				    state.pe_report_event & PTRACE_POSIX_SPAWN,
549 				       PTRACE_POSIX_SPAWN);
550 			}
551 			if (trackfork && strcmp(fn, "fork") == 0) {
552 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
553 				       PTRACE_FORK);
554 			}
555 			if (trackvfork && strcmp(fn, "vfork") == 0) {
556 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
557 				       PTRACE_VFORK);
558 			}
559 
560 			ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
561 
562 			DPRINTF("Before resuming the forkee process where it left off "
563 			    "and without signal to be sent\n");
564 			SYSCALL_REQUIRE(
565 			    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
566 
567 			DPRINTF("Before resuming the tracee process where it left off "
568 			    "and without signal to be sent\n");
569 			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
570 		}
571 
572 		if (trackvforkdone && strcmp(fn, "vfork") == 0) {
573 			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
574 			    tracee);
575 			TWAIT_REQUIRE_SUCCESS(
576 			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
577 
578 			validate_status_stopped(status, SIGTRAP);
579 
580 			SYSCALL_REQUIRE(
581 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
582 			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
583 
584 			tracee2 = state.pe_other_pid;
585 			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
586 			    tracee2);
587 
588 			DPRINTF("Before resuming the tracee process where it left off "
589 			    "and without signal to be sent\n");
590 			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
591 		}
592 
593 
594 		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
595 		    (trackfork && strcmp(fn, "fork") == 0) ||
596 		    (trackvfork && strcmp(fn, "vfork") == 0)) {
597 			DPRINTF("Before calling %s() for the forkee - expected exited"
598 			    "\n", TWAIT_FNAME);
599 			TWAIT_REQUIRE_SUCCESS(
600 			    wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
601 
602 			validate_status_exited(status, exitval2);
603 
604 			DPRINTF("Before calling %s() for the forkee - expected no "
605 			    "process\n", TWAIT_FNAME);
606 			TWAIT_REQUIRE_FAILURE(ECHILD,
607 			    wpid = TWAIT_GENERIC(tracee2, &status, 0));
608 		}
609 
610 		DPRINTF("Before calling %s() for the tracee - expected exited\n",
611 		    TWAIT_FNAME);
612 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
613 
614 		validate_status_exited(status, exitval);
615 
616 		/* Inform parent that tracer is exiting normally */
617 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
618 
619 		DPRINTF("Before exiting of the tracer process\n");
620 		_exit(0 /* collect by initproc */);
621 	}
622 
623 	DPRINTF("Wait for the tracer process (direct child) to exit "
624 	    "calling %s()\n", TWAIT_FNAME);
625 	TWAIT_REQUIRE_SUCCESS(
626 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
627 
628 	validate_status_exited(status, exitval);
629 
630 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
631 	    TWAIT_FNAME);
632 	TWAIT_REQUIRE_SUCCESS(
633 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
634 
635 	DPRINTF("Wait for the tracer to attach to the tracee\n");
636 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
637 
638 	DPRINTF("Resume the tracee and let it crash\n");
639 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
640 
641 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
642 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
643 
644 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
645 	    TWAIT_FNAME);
646 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
647 
648 	validate_status_exited(status, exitval);
649 
650 	DPRINTF("Await normal exit of tracer\n");
651 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
652 
653 	msg_close(&parent_tracer);
654 	msg_close(&parent_tracee);
655 }
656 
657 #define UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp)\
658 ATF_TC(name);								\
659 ATF_TC_HEAD(name, tc)							\
660 {									\
661 	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
662 	    "called with 0%s%s%s%s in EVENT_MASK%s",			\
663 	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
664 	    tfork ? "|PTRACE_FORK" : "",				\
665 	    tvfork ? "|PTRACE_VFORK" : "",				\
666 	    tvforkdone ? "|PTRACE_VFORK_DONE" : "",			\
667 	    newpgrp ? " and the traced processes call setpgrp(0,0)":"");\
668 }									\
669 									\
670 ATF_TC_BODY(name, tc)							\
671 {									\
672 									\
673 	unrelated_tracer_fork_body(fun, tspawn, tfork, tvfork,		\
674 	    tvforkdone, newpgrp);					\
675 }
676 
677 #define UNRELATED_TRACER_FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)	\
678 	UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false)
679 
680 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork1, "fork", false, false, false, false)
681 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork2, "fork", false, true, false, false)
682 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork3, "fork", false, false, true, false)
683 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork4, "fork", false, true, true, false)
684 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork5, "fork", false, false, false, true)
685 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork6, "fork", false, true, false, true)
686 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork7, "fork", false, false, true, true)
687 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork8, "fork", false, true, true, true)
688 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork9, "fork", true, false, false, false)
689 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork10, "fork", true, true, false, false)
690 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork11, "fork", true, false, true, false)
691 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork12, "fork", true, true, true, false)
692 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork13, "fork", true, false, false, true)
693 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork14, "fork", true, true, false, true)
694 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork15, "fork", true, false, true, true)
695 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork16, "fork", true, true, true, true)
696 
697 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_fork_setpgid, "fork", true, true, true, true, true)
698 
699 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork1, "vfork", false, false, false, false)
700 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork2, "vfork", false, true, false, false)
701 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork3, "vfork", false, false, true, false)
702 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork4, "vfork", false, true, true, false)
703 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork5, "vfork", false, false, false, true)
704 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork6, "vfork", false, true, false, true)
705 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork7, "vfork", false, false, true, true)
706 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork8, "vfork", false, true, true, true)
707 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork9, "vfork", true, false, false, false)
708 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork10, "vfork", true, true, false, false)
709 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork11, "vfork", true, false, true, false)
710 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork12, "vfork", true, true, true, false)
711 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork13, "vfork", true, false, false, true)
712 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork14, "vfork", true, true, false, true)
713 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork15, "vfork", true, false, true, true)
714 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork16, "vfork", true, true, true, true)
715 
716 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_vfork_setpgid, "vfork", true, true, true, true, true)
717 
718 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn1, "spawn", false, false, false, false)
719 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn2, "spawn", false, true, false, false)
720 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn3, "spawn", false, false, true, false)
721 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn4, "spawn", false, true, true, false)
722 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn5, "spawn", false, false, false, true)
723 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn6, "spawn", false, true, false, true)
724 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn7, "spawn", false, false, true, true)
725 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn8, "spawn", false, true, true, true)
726 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn9, "spawn", true, false, false, false)
727 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn10, "spawn", true, true, false, false)
728 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn11, "spawn", true, false, true, false)
729 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn12, "spawn", true, true, true, false)
730 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn13, "spawn", true, false, false, true)
731 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn14, "spawn", true, true, false, true)
732 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn15, "spawn", true, false, true, true)
733 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn16, "spawn", true, true, true, true)
734 
735 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_posix_spawn_setpgid, "spawn", true, true, true, true, true)
736 #endif
737 
738 /// ----------------------------------------------------------------------------
739 
740 #if defined(TWAIT_HAVE_PID)
741 static void
fork_detach_forker_body(const char * fn,bool kill_process)742 fork_detach_forker_body(const char *fn, bool kill_process)
743 {
744 	const int exitval = 5;
745 	const int exitval2 = 0; /* Matches exit value from /bin/echo */
746 	const int sigval = SIGSTOP;
747 	pid_t child, child2 = 0, wpid;
748 #if defined(TWAIT_HAVE_STATUS)
749 	int status;
750 #endif
751 	ptrace_state_t state;
752 	const int slen = sizeof(state);
753 	ptrace_event_t event;
754 	const int elen = sizeof(event);
755 
756 	int op;
757 
758 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
759 
760 	DPRINTF("Before forking process PID=%d\n", getpid());
761 	SYSCALL_REQUIRE((child = fork()) != -1);
762 	if (child == 0) {
763 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
764 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
765 
766 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
767 		FORKEE_ASSERT(raise(sigval) == 0);
768 
769 		if (strcmp(fn, "spawn") == 0) {
770 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
771 			    arg[0], NULL, NULL, arg, NULL), 0);
772 		} else  {
773 			if (strcmp(fn, "fork") == 0) {
774 				FORKEE_ASSERT((child2 = fork()) != -1);
775 			} else {
776 				FORKEE_ASSERT((child2 = vfork()) != -1);
777 			}
778 
779 			if (child2 == 0)
780 				_exit(exitval2);
781 		}
782 
783 		FORKEE_REQUIRE_SUCCESS
784 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
785 
786 		forkee_status_exited(status, exitval2);
787 
788 		DPRINTF("Before exiting of the child process\n");
789 		_exit(exitval);
790 	}
791 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
792 
793 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
794 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
795 
796 	validate_status_stopped(status, sigval);
797 
798 	DPRINTF("Set EVENT_MASK for the child %d\n", child);
799 	event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
800 		| PTRACE_VFORK_DONE;
801 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
802 
803 	DPRINTF("Before resuming the child process where it left off and "
804 	    "without signal to be sent\n");
805 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
806 
807 	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
808 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
809 
810 	validate_status_stopped(status, SIGTRAP);
811 
812 	SYSCALL_REQUIRE(
813 	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
814 
815 	if (strcmp(fn, "spawn") == 0)
816 		op = PTRACE_POSIX_SPAWN;
817 	else if (strcmp(fn, "fork") == 0)
818 		op = PTRACE_FORK;
819 	else
820 		op = PTRACE_VFORK;
821 
822 	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
823 
824 	child2 = state.pe_other_pid;
825 	DPRINTF("Reported ptrace event with forkee %d\n", child2);
826 
827 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
828 	    strcmp(fn, "vfork") == 0)
829 		op = kill_process ? PT_KILL : PT_DETACH;
830 	else
831 		op = PT_CONTINUE;
832 	SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
833 
834 	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
835 	    TWAIT_FNAME, child2, child);
836 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
837 
838 	validate_status_stopped(status, SIGTRAP);
839 
840 	SYSCALL_REQUIRE(
841 	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
842 	if (strcmp(fn, "spawn") == 0)
843 		op = PTRACE_POSIX_SPAWN;
844 	else if (strcmp(fn, "fork") == 0)
845 		op = PTRACE_FORK;
846 	else
847 		op = PTRACE_VFORK;
848 
849 	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
850 	ATF_REQUIRE_EQ(state.pe_other_pid, child);
851 
852 	DPRINTF("Before resuming the forkee process where it left off "
853 	    "and without signal to be sent\n");
854  	SYSCALL_REQUIRE(
855 	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
856 
857 	if (strcmp(fn, "vforkdone") == 0) {
858 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
859 		    child);
860 		TWAIT_REQUIRE_SUCCESS(
861 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
862 
863 		validate_status_stopped(status, SIGTRAP);
864 
865 		SYSCALL_REQUIRE(
866 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
867 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
868 
869 		child2 = state.pe_other_pid;
870 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
871 		    child2);
872 
873 		op = kill_process ? PT_KILL : PT_DETACH;
874 		DPRINTF("Before resuming the child process where it left off "
875 		    "and without signal to be sent\n");
876 		SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
877 	}
878 
879 	DPRINTF("Before calling %s() for the forkee - expected exited\n",
880 	    TWAIT_FNAME);
881 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
882 
883 	validate_status_exited(status, exitval2);
884 
885 	DPRINTF("Before calling %s() for the forkee - expected no process\n",
886 	    TWAIT_FNAME);
887 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0));
888 
889 	DPRINTF("Before calling %s() for the forkee - expected exited\n",
890 	    TWAIT_FNAME);
891 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
892 
893 	if (kill_process) {
894 		validate_status_signaled(status, SIGKILL, 0);
895 	} else {
896 		validate_status_exited(status, exitval);
897 	}
898 
899 	DPRINTF("Before calling %s() for the child - expected no process\n",
900 	    TWAIT_FNAME);
901 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
902 }
903 
904 #define FORK_DETACH_FORKER(name,event,kprocess)				\
905 ATF_TC(name);								\
906 ATF_TC_HEAD(name, tc)							\
907 {									\
908 	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
909 	    kprocess ? "killed" : "detached");				\
910 }									\
911 									\
912 ATF_TC_BODY(name, tc)							\
913 {									\
914 									\
915 	fork_detach_forker_body(event, kprocess);			\
916 }
917 
918 FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false)
919 FORK_DETACH_FORKER(fork_detach_forker, "fork", false)
920 FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false)
921 FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false)
922 
923 FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true)
924 FORK_DETACH_FORKER(fork_kill_forker, "fork", true)
925 FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true)
926 FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true)
927 #endif
928 
929 /// ----------------------------------------------------------------------------
930 
931 #if defined(TWAIT_HAVE_PID)
932 static void
unrelated_tracer_fork_detach_forker_body(const char * fn,bool kill_process)933 unrelated_tracer_fork_detach_forker_body(const char *fn, bool kill_process)
934 {
935 	const int sigval = SIGSTOP;
936 	struct msg_fds parent_tracee, parent_tracer;
937 	const int exitval = 10;
938 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
939 	pid_t tracee, tracer, wpid;
940 	pid_t tracee2 = 0;
941 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
942 #if defined(TWAIT_HAVE_STATUS)
943 	int status;
944 #endif
945 	int op;
946 
947 	struct ptrace_siginfo info;
948 	ptrace_state_t state;
949 	const int slen = sizeof(state);
950 	ptrace_event_t event;
951 	const int elen = sizeof(event);
952 
953 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
954 
955 	DPRINTF("Spawn tracee\n");
956 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
957 	tracee = atf_utils_fork();
958 	if (tracee == 0) {
959 		// Wait for parent to let us crash
960 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
961 
962 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
963 		FORKEE_ASSERT(raise(sigval) == 0);
964 
965 		if (strcmp(fn, "spawn") == 0) {
966 			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
967 			    arg[0], NULL, NULL, arg, NULL), 0);
968 		} else  {
969 			if (strcmp(fn, "fork") == 0) {
970 				FORKEE_ASSERT((tracee2 = fork()) != -1);
971 			} else {
972 				FORKEE_ASSERT((tracee2 = vfork()) != -1);
973 			}
974 
975 			if (tracee2 == 0)
976 				_exit(exitval2);
977 		}
978 
979 		FORKEE_REQUIRE_SUCCESS
980 		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
981 
982 		forkee_status_exited(status, exitval2);
983 
984 		DPRINTF("Before exiting of the child process\n");
985 		_exit(exitval);
986 	}
987 
988 	DPRINTF("Spawn debugger\n");
989 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
990 	tracer = atf_utils_fork();
991 	if (tracer == 0) {
992 		/* Fork again and drop parent to reattach to PID 1 */
993 		tracer = atf_utils_fork();
994 		if (tracer != 0)
995 			_exit(exitval);
996 
997 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
998 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
999 
1000 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1001 		FORKEE_REQUIRE_SUCCESS(
1002 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1003 
1004 		forkee_status_stopped(status, SIGSTOP);
1005 
1006 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1007 		    "traced process\n");
1008 		SYSCALL_REQUIRE(
1009 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1010 
1011 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1012 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1013 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1014 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1015 
1016 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
1017 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
1018 
1019 		/* Resume tracee with PT_CONTINUE */
1020 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1021 
1022 		/* Inform parent that tracer has attached to tracee */
1023 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1024 
1025 		/* Wait for parent to tell use that tracee should have exited */
1026 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
1027 
1028 		/* Wait for tracee and assert that it exited */
1029 		FORKEE_REQUIRE_SUCCESS(
1030 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1031 
1032 		forkee_status_stopped(status, sigval);
1033 
1034 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1035 		    "traced process\n");
1036 		SYSCALL_REQUIRE(
1037 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1038 
1039 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1040 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1041 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1042 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1043 
1044 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
1045 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
1046 
1047 		DPRINTF("Set EVENT_MASK for the child %d\n", tracee);
1048 		event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
1049 			| PTRACE_VFORK_DONE;
1050 		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) != -1);
1051 
1052 		DPRINTF("Before resuming the child process where it left off and "
1053 		    "without signal to be sent\n");
1054 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1055 
1056 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, tracee);
1057 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1058 
1059 		validate_status_stopped(status, SIGTRAP);
1060 
1061 		SYSCALL_REQUIRE(
1062 		    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
1063 
1064 		if (strcmp(fn, "spawn") == 0)
1065 			op = PTRACE_POSIX_SPAWN;
1066 		else if (strcmp(fn, "fork") == 0)
1067 			op = PTRACE_FORK;
1068 		else
1069 			op = PTRACE_VFORK;
1070 
1071 		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
1072 
1073 		tracee2 = state.pe_other_pid;
1074 		DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
1075 		if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
1076 		    strcmp(fn, "vfork") == 0)
1077 			op = kill_process ? PT_KILL : PT_DETACH;
1078 		else
1079 			op = PT_CONTINUE;
1080 		SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
1081 
1082 		DPRINTF("Before calling %s() for the forkee %d of the tracee %d\n",
1083 		    TWAIT_FNAME, tracee2, tracee);
1084 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
1085 
1086 		validate_status_stopped(status, SIGTRAP);
1087 
1088 		SYSCALL_REQUIRE(
1089 		    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
1090 		if (strcmp(fn, "spawn") == 0)
1091 			op = PTRACE_POSIX_SPAWN;
1092 		else if (strcmp(fn, "fork") == 0)
1093 			op = PTRACE_FORK;
1094 		else
1095 			op = PTRACE_VFORK;
1096 
1097 		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
1098 		ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
1099 
1100 		DPRINTF("Before resuming the forkee process where it left off "
1101 		    "and without signal to be sent\n");
1102 		SYSCALL_REQUIRE(
1103 		    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
1104 
1105 		if (strcmp(fn, "vforkdone") == 0) {
1106 			DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
1107 			    tracee);
1108 			TWAIT_REQUIRE_SUCCESS(
1109 			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1110 
1111 			validate_status_stopped(status, SIGTRAP);
1112 
1113 			SYSCALL_REQUIRE(
1114 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
1115 			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
1116 
1117 			tracee2 = state.pe_other_pid;
1118 			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
1119 			    tracee2);
1120 
1121 			op = kill_process ? PT_KILL : PT_DETACH;
1122 			DPRINTF("Before resuming the child process where it left off "
1123 			    "and without signal to be sent\n");
1124 			SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
1125 		}
1126 
1127 		DPRINTF("Before calling %s() for the forkee - expected exited\n",
1128 		    TWAIT_FNAME);
1129 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
1130 
1131 		validate_status_exited(status, exitval2);
1132 
1133 		DPRINTF("Before calling %s() for the forkee - expected no process\n",
1134 		    TWAIT_FNAME);
1135 		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(tracee2, &status, 0));
1136 
1137 		if (kill_process) {
1138 			DPRINTF("Before calling %s() for the forkee - expected signaled\n",
1139 			    TWAIT_FNAME);
1140 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1141 
1142 			validate_status_signaled(status, SIGKILL, 0);
1143 		}
1144 
1145 		/* Inform parent that tracer is exiting normally */
1146 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
1147 
1148 		DPRINTF("Before exiting of the tracer process\n");
1149 		_exit(0 /* collect by initproc */);
1150 	}
1151 
1152 	DPRINTF("Wait for the tracer process (direct child) to exit "
1153 	    "calling %s()\n", TWAIT_FNAME);
1154 	TWAIT_REQUIRE_SUCCESS(
1155 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
1156 
1157 	validate_status_exited(status, exitval);
1158 
1159 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
1160 	    TWAIT_FNAME);
1161 	TWAIT_REQUIRE_SUCCESS(
1162 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
1163 
1164 	DPRINTF("Wait for the tracer to attach to the tracee\n");
1165 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
1166 
1167 	DPRINTF("Resume the tracee and let it crash\n");
1168 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
1169 
1170 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
1171 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
1172 
1173 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1174 	    TWAIT_FNAME);
1175 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1176 
1177 	if (kill_process) {
1178 		validate_status_signaled(status, SIGKILL, 0);
1179 	} else {
1180 		validate_status_exited(status, exitval);
1181 	}
1182 
1183 	DPRINTF("Await normal exit of tracer\n");
1184 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
1185 
1186 	msg_close(&parent_tracer);
1187 	msg_close(&parent_tracee);
1188 }
1189 
1190 #define UNRELATED_TRACER_FORK_DETACH_FORKER(name,event,kprocess)	\
1191 ATF_TC(name);								\
1192 ATF_TC_HEAD(name, tc)							\
1193 {									\
1194 	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
1195 	    kprocess ? "killed" : "detached");				\
1196 }									\
1197 									\
1198 ATF_TC_BODY(name, tc)							\
1199 {									\
1200 									\
1201 	unrelated_tracer_fork_detach_forker_body(event, kprocess);	\
1202 }
1203 
1204 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_detach_spawner, "spawn", false)
1205 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_detach_forker, "fork", false)
1206 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforker, "vfork", false)
1207 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforkerdone, "vforkdone", false)
1208 
1209 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_kill_spawner, "spawn", true)
1210 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_kill_forker, "fork", true)
1211 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforker, "vfork", true)
1212 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforkerdone, "vforkdone", true)
1213 #endif
1214 
1215 /// ----------------------------------------------------------------------------
1216 
1217 static void
traceme_vfork_fork_body(pid_t (* fn)(void))1218 traceme_vfork_fork_body(pid_t (*fn)(void))
1219 {
1220 	const int exitval = 5;
1221 	const int exitval2 = 15;
1222 	pid_t child, child2 = 0, wpid;
1223 #if defined(TWAIT_HAVE_STATUS)
1224 	int status;
1225 #endif
1226 
1227 	DPRINTF("Before forking process PID=%d\n", getpid());
1228 	SYSCALL_REQUIRE((child = vfork()) != -1);
1229 	if (child == 0) {
1230 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1231 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1232 
1233 		FORKEE_ASSERT((child2 = (fn)()) != -1);
1234 
1235 		if (child2 == 0)
1236 			_exit(exitval2);
1237 
1238 		FORKEE_REQUIRE_SUCCESS
1239 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1240 
1241 		forkee_status_exited(status, exitval2);
1242 
1243 		DPRINTF("Before exiting of the child process\n");
1244 		_exit(exitval);
1245 	}
1246 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1247 
1248 	DPRINTF("Before calling %s() for the child - expected exited\n",
1249 	    TWAIT_FNAME);
1250 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1251 
1252 	validate_status_exited(status, exitval);
1253 
1254 	DPRINTF("Before calling %s() for the child - expected no process\n",
1255 	    TWAIT_FNAME);
1256 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1257 }
1258 
1259 #define TRACEME_VFORK_FORK_TEST(name,fun)				\
1260 ATF_TC(name);								\
1261 ATF_TC_HEAD(name, tc)							\
1262 {									\
1263 	atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) "		\
1264 	    "called from vfork(2)ed child");				\
1265 }									\
1266 									\
1267 ATF_TC_BODY(name, tc)							\
1268 {									\
1269 									\
1270 	traceme_vfork_fork_body(fun);					\
1271 }
1272 
TRACEME_VFORK_FORK_TEST(traceme_vfork_fork,fork)1273 TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork)
1274 TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork)
1275 
1276 /// ----------------------------------------------------------------------------
1277 
1278 #if defined(TWAIT_HAVE_PID)
1279 static void
1280 fork2_body(const char *fn, bool masked, bool ignored)
1281 {
1282 	const int exitval = 5;
1283 	const int exitval2 = 0; /* Match exit status from /bin/echo */
1284 	const int sigval = SIGSTOP;
1285 	pid_t child, child2 = 0, wpid;
1286 #if defined(TWAIT_HAVE_STATUS)
1287 	int status;
1288 #endif
1289 	ptrace_state_t state;
1290 	const int slen = sizeof(state);
1291 	ptrace_event_t event;
1292 	const int elen = sizeof(event);
1293 	struct sigaction sa;
1294 	struct ptrace_siginfo info;
1295 	sigset_t intmask;
1296 	struct kinfo_proc2 kp;
1297 	size_t len = sizeof(kp);
1298 
1299 	int name[6];
1300 	const size_t namelen = __arraycount(name);
1301 	sigset_t set;
1302 	ki_sigset_t kp_sigmask;
1303 	ki_sigset_t kp_sigignore;
1304 
1305 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
1306 
1307 	DPRINTF("Before forking process PID=%d\n", getpid());
1308 	SYSCALL_REQUIRE((child = fork()) != -1);
1309 	if (child == 0) {
1310 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1311 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1312 
1313 		if (masked) {
1314 			sigemptyset(&intmask);
1315 			sigaddset(&intmask, SIGTRAP);
1316 			sigprocmask(SIG_BLOCK, &intmask, NULL);
1317 		}
1318 
1319 		if (ignored) {
1320 			memset(&sa, 0, sizeof(sa));
1321 			sa.sa_handler = SIG_IGN;
1322 			sigemptyset(&sa.sa_mask);
1323 			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
1324 		}
1325 
1326 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1327 		FORKEE_ASSERT(raise(sigval) == 0);
1328 
1329 		if (strcmp(fn, "spawn") == 0) {
1330 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
1331 			    arg[0], NULL, NULL, arg, NULL), 0);
1332 		} else  {
1333 			if (strcmp(fn, "fork") == 0) {
1334 				FORKEE_ASSERT((child2 = fork()) != -1);
1335 			} else {
1336 				FORKEE_ASSERT((child2 = vfork()) != -1);
1337 			}
1338 			if (child2 == 0)
1339 				_exit(exitval2);
1340 		}
1341 
1342 		FORKEE_REQUIRE_SUCCESS
1343 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1344 
1345 		forkee_status_exited(status, exitval2);
1346 
1347 		DPRINTF("Before exiting of the child process\n");
1348 		_exit(exitval);
1349 	}
1350 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1351 
1352 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1353 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1354 
1355 	validate_status_stopped(status, sigval);
1356 
1357 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1358 	SYSCALL_REQUIRE(
1359 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1360 
1361 	DPRINTF("Before checking siginfo_t\n");
1362 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1363 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1364 
1365 	name[0] = CTL_KERN,
1366 	name[1] = KERN_PROC2,
1367 	name[2] = KERN_PROC_PID;
1368 	name[3] = child;
1369 	name[4] = sizeof(kp);
1370 	name[5] = 1;
1371 
1372 	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1373 
1374 	kp_sigmask = kp.p_sigmask;
1375 	kp_sigignore = kp.p_sigignore;
1376 
1377 	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
1378 	    strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "",
1379 	    strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "",
1380 	    strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "",
1381 	    strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child);
1382 	event.pe_set_event = 0;
1383 	if (strcmp(fn, "spawn") == 0)
1384 		event.pe_set_event |= PTRACE_POSIX_SPAWN;
1385 	if (strcmp(fn, "fork") == 0)
1386 		event.pe_set_event |= PTRACE_FORK;
1387 	if (strcmp(fn, "vfork") == 0)
1388 		event.pe_set_event |= PTRACE_VFORK;
1389 	if (strcmp(fn, "vforkdone") == 0)
1390 		event.pe_set_event |= PTRACE_VFORK_DONE;
1391 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1392 
1393 	/*
1394 	 * Ignore interception of the SIGCHLD signals.
1395 	 *
1396 	 * SIGCHLD once blocked is discarded by the kernel as it has the
1397 	 * SA_IGNORE property. During the fork(2) operation all signals can be
1398 	 * shortly blocked and missed (unless there is a registered signal
1399 	 * handler in the traced child). This leads to a race in this test if
1400 	 * there would be an intention to catch SIGCHLD.
1401 	 */
1402 	sigemptyset(&set);
1403 	sigaddset(&set, SIGCHLD);
1404 	SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1);
1405 
1406 	DPRINTF("Before resuming the child process where it left off and "
1407 	    "without signal to be sent\n");
1408 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1409 
1410 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
1411 	    strcmp(fn, "vfork") == 0) {
1412 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
1413 		    child);
1414 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1415 		    child);
1416 
1417 		validate_status_stopped(status, SIGTRAP);
1418 
1419 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1420 
1421 		if (masked) {
1422 			DPRINTF("kp_sigmask="
1423 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1424 			    PRIx32 "\n",
1425 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1426 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1427 
1428 			DPRINTF("kp.p_sigmask="
1429 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1430 			    PRIx32 "\n",
1431 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1432 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1433 
1434 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
1435 			    SIGTRAP));
1436 		}
1437 
1438 		if (ignored) {
1439 			DPRINTF("kp_sigignore="
1440 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1441 			    PRIx32 "\n",
1442 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1443 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1444 
1445 			DPRINTF("kp.p_sigignore="
1446 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1447 			    PRIx32 "\n",
1448 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1449 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1450 
1451 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
1452 			    SIGTRAP));
1453 		}
1454 
1455 		SYSCALL_REQUIRE(
1456 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1457 		if (strcmp(fn, "spawn") == 0) {
1458 			ATF_REQUIRE_EQ(
1459 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
1460 			       PTRACE_POSIX_SPAWN);
1461 		}
1462 		if (strcmp(fn, "fork") == 0) {
1463 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
1464 			       PTRACE_FORK);
1465 		}
1466 		if (strcmp(fn, "vfork") == 0) {
1467 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
1468 			       PTRACE_VFORK);
1469 		}
1470 
1471 		child2 = state.pe_other_pid;
1472 		DPRINTF("Reported ptrace event with forkee %d\n", child2);
1473 
1474 		DPRINTF("Before calling %s() for the forkee %d of the child "
1475 		    "%d\n", TWAIT_FNAME, child2, child);
1476 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1477 		    child2);
1478 
1479 		validate_status_stopped(status, SIGTRAP);
1480 
1481 		name[3] = child2;
1482 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1483 
1484 		if (masked) {
1485 			DPRINTF("kp_sigmask="
1486 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1487 			    PRIx32 "\n",
1488 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1489 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1490 
1491 			DPRINTF("kp.p_sigmask="
1492 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1493 			    PRIx32 "\n",
1494 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1495 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1496 
1497 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
1498 			    SIGTRAP));
1499 		}
1500 
1501 		if (ignored) {
1502 			DPRINTF("kp_sigignore="
1503 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1504 			    PRIx32 "\n",
1505 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1506 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1507 
1508 			DPRINTF("kp.p_sigignore="
1509 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1510 			    PRIx32 "\n",
1511 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1512 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1513 
1514 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
1515 			    SIGTRAP));
1516 		}
1517 
1518 		SYSCALL_REQUIRE(
1519 		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
1520 		if (strcmp(fn, "spawn") == 0) {
1521 			ATF_REQUIRE_EQ(
1522 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
1523 			       PTRACE_POSIX_SPAWN);
1524 		}
1525 		if (strcmp(fn, "fork") == 0) {
1526 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
1527 			       PTRACE_FORK);
1528 		}
1529 		if (strcmp(fn, "vfork") == 0) {
1530 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
1531 			       PTRACE_VFORK);
1532 		}
1533 
1534 		ATF_REQUIRE_EQ(state.pe_other_pid, child);
1535 
1536 		DPRINTF("Before resuming the forkee process where it left off "
1537 		    "and without signal to be sent\n");
1538 		SYSCALL_REQUIRE(
1539 		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
1540 
1541 		DPRINTF("Before resuming the child process where it left off "
1542 		    "and without signal to be sent\n");
1543 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1544 	}
1545 
1546 	if (strcmp(fn, "vforkdone") == 0) {
1547 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
1548 		    child);
1549 		TWAIT_REQUIRE_SUCCESS(
1550 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
1551 
1552 		validate_status_stopped(status, SIGTRAP);
1553 
1554 		name[3] = child;
1555 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1556 
1557 		/*
1558 		 * SIGCHLD is now pending in the signal queue and
1559 		 * the kernel presents it to userland as a masked signal.
1560 		 */
1561 		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
1562 
1563 		if (masked) {
1564 			DPRINTF("kp_sigmask="
1565 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1566 			    PRIx32 "\n",
1567 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1568 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1569 
1570 			DPRINTF("kp.p_sigmask="
1571 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1572 			    PRIx32 "\n",
1573 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1574 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1575 
1576 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
1577 			    SIGTRAP));
1578 		}
1579 
1580 		if (ignored) {
1581 			DPRINTF("kp_sigignore="
1582 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1583 			    PRIx32 "\n",
1584 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1585 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1586 
1587 			DPRINTF("kp.p_sigignore="
1588 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1589 			    PRIx32 "\n",
1590 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1591 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1592 
1593 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
1594 			    SIGTRAP));
1595 		}
1596 
1597 		SYSCALL_REQUIRE(
1598 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1599 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
1600 
1601 		child2 = state.pe_other_pid;
1602 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
1603 		    child2);
1604 
1605 		DPRINTF("Before resuming the child process where it left off "
1606 		    "and without signal to be sent\n");
1607 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1608 	}
1609 
1610 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
1611 	    strcmp(fn, "vfork") == 0) {
1612 		DPRINTF("Before calling %s() for the forkee - expected exited"
1613 		    "\n", TWAIT_FNAME);
1614 		TWAIT_REQUIRE_SUCCESS(
1615 		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1616 
1617 		validate_status_exited(status, exitval2);
1618 
1619 		DPRINTF("Before calling %s() for the forkee - expected no "
1620 		    "process\n", TWAIT_FNAME);
1621 		TWAIT_REQUIRE_FAILURE(ECHILD,
1622 		    wpid = TWAIT_GENERIC(child2, &status, 0));
1623 	}
1624 
1625 	DPRINTF("Before calling %s() for the child - expected exited\n",
1626 	    TWAIT_FNAME);
1627 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1628 
1629 	validate_status_exited(status, exitval);
1630 
1631 	DPRINTF("Before calling %s() for the child - expected no process\n",
1632 	    TWAIT_FNAME);
1633 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1634 }
1635 
1636 #define FORK2_TEST(name,fn,masked,ignored)				\
1637 ATF_TC(name);								\
1638 ATF_TC_HEAD(name, tc)							\
1639 {									\
1640 	atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught "	\
1641 	    "regardless of signal %s%s", 				\
1642 	    masked ? "masked" : "", ignored ? "ignored" : "");		\
1643 }									\
1644 									\
1645 ATF_TC_BODY(name, tc)							\
1646 {									\
1647 									\
1648 	fork2_body(fn, masked, ignored);				\
1649 }
1650 
1651 FORK2_TEST(posix_spawn_signalmasked, "spawn", true, false)
1652 FORK2_TEST(posix_spawn_signalignored, "spawn", false, true)
1653 FORK2_TEST(fork_signalmasked, "fork", true, false)
1654 FORK2_TEST(fork_signalignored, "fork", false, true)
1655 FORK2_TEST(vfork_signalmasked, "vfork", true, false)
1656 FORK2_TEST(vfork_signalignored, "vfork", false, true)
1657 FORK2_TEST(vforkdone_signalmasked, "vforkdone", true, false)
1658 FORK2_TEST(vforkdone_signalignored, "vforkdone", false, true)
1659 #endif
1660 
1661 #define ATF_TP_ADD_TCS_PTRACE_WAIT_FORK() \
1662 	ATF_TP_ADD_TC(tp, fork1); \
1663 	ATF_TP_ADD_TC_HAVE_PID(tp, fork2); \
1664 	ATF_TP_ADD_TC_HAVE_PID(tp, fork3); \
1665 	ATF_TP_ADD_TC_HAVE_PID(tp, fork4); \
1666 	ATF_TP_ADD_TC(tp, fork5); \
1667 	ATF_TP_ADD_TC_HAVE_PID(tp, fork6); \
1668 	ATF_TP_ADD_TC_HAVE_PID(tp, fork7); \
1669 	ATF_TP_ADD_TC_HAVE_PID(tp, fork8); \
1670 	ATF_TP_ADD_TC(tp, fork9); \
1671 	ATF_TP_ADD_TC_HAVE_PID(tp, fork10); \
1672 	ATF_TP_ADD_TC_HAVE_PID(tp, fork11); \
1673 	ATF_TP_ADD_TC_HAVE_PID(tp, fork12); \
1674 	ATF_TP_ADD_TC(tp, fork13); \
1675 	ATF_TP_ADD_TC_HAVE_PID(tp, fork14); \
1676 	ATF_TP_ADD_TC_HAVE_PID(tp, fork15); \
1677 	ATF_TP_ADD_TC_HAVE_PID(tp, fork16); \
1678 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_setpgid); \
1679 	ATF_TP_ADD_TC(tp, vfork1); \
1680 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); \
1681 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); \
1682 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); \
1683 	ATF_TP_ADD_TC(tp, vfork5); \
1684 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); \
1685 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); \
1686 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); \
1687 	ATF_TP_ADD_TC(tp, vfork9); \
1688 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); \
1689 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); \
1690 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); \
1691 	ATF_TP_ADD_TC(tp, vfork13); \
1692 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); \
1693 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); \
1694 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); \
1695 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_setpgid); \
1696 	ATF_TP_ADD_TC(tp, posix_spawn1); \
1697 	ATF_TP_ADD_TC(tp, posix_spawn2); \
1698 	ATF_TP_ADD_TC(tp, posix_spawn3); \
1699 	ATF_TP_ADD_TC(tp, posix_spawn4); \
1700 	ATF_TP_ADD_TC(tp, posix_spawn5); \
1701 	ATF_TP_ADD_TC(tp, posix_spawn6); \
1702 	ATF_TP_ADD_TC(tp, posix_spawn7); \
1703 	ATF_TP_ADD_TC(tp, posix_spawn8); \
1704 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); \
1705 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); \
1706 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); \
1707 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); \
1708 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); \
1709 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); \
1710 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); \
1711 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); \
1712 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_setpgid); \
1713 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1); \
1714 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2); \
1715 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3); \
1716 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4); \
1717 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5); \
1718 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6); \
1719 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7); \
1720 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8); \
1721 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9); \
1722 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10); \
1723 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11); \
1724 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12); \
1725 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13); \
1726 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14); \
1727 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15); \
1728 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16); \
1729 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_setpgid); \
1730 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1); \
1731 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2); \
1732 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3); \
1733 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4); \
1734 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5); \
1735 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6); \
1736 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7); \
1737 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8); \
1738 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9); \
1739 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10); \
1740 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11); \
1741 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12); \
1742 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13); \
1743 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14); \
1744 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15); \
1745 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16); \
1746 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_setpgid); \
1747 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1); \
1748 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2); \
1749 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3); \
1750 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4); \
1751 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5); \
1752 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6); \
1753 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7); \
1754 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8); \
1755 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9); \
1756 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10); \
1757 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11); \
1758 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12); \
1759 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13); \
1760 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14); \
1761 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15); \
1762 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16); \
1763 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_setpgid); \
1764 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); \
1765 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); \
1766 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); \
1767 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); \
1768 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); \
1769 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); \
1770 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); \
1771 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); \
1772 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner); \
1773 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker); \
1774 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker); \
1775 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone); \
1776 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner); \
1777 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker); \
1778 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker); \
1779 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone); \
1780 	ATF_TP_ADD_TC(tp, traceme_vfork_fork); \
1781 	ATF_TP_ADD_TC(tp, traceme_vfork_vfork); \
1782 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalmasked); \
1783 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalignored); \
1784 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalmasked); \
1785 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalignored); \
1786 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalmasked); \
1787 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalignored); \
1788 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalmasked); \
1789 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalignored);
1790