t_ptrace_wait.c revision 1.127
1/*	$NetBSD: t_ptrace_wait.c,v 1.127 2019/06/13 20:26:06 kamil Exp $	*/
2
3/*-
4 * Copyright (c) 2016, 2017, 2018, 2019 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#include <sys/cdefs.h>
30__RCSID("$NetBSD: t_ptrace_wait.c,v 1.127 2019/06/13 20:26:06 kamil Exp $");
31
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/mman.h>
35#include <sys/ptrace.h>
36#include <sys/resource.h>
37#include <sys/stat.h>
38#include <sys/syscall.h>
39#include <sys/sysctl.h>
40#include <sys/wait.h>
41#include <machine/reg.h>
42#include <elf.h>
43#include <err.h>
44#include <errno.h>
45#include <lwp.h>
46#include <pthread.h>
47#include <sched.h>
48#include <signal.h>
49#include <spawn.h>
50#include <stdint.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <strings.h>
54#include <time.h>
55#include <unistd.h>
56
57#include <fenv.h>
58#if (__arm__ && !__SOFTFP__) || __aarch64__
59#include <ieeefp.h> /* only need for ARM Cortex/Neon hack */
60#endif
61
62#if defined(__i386__) || defined(__x86_64__)
63#include <cpuid.h>
64#include <x86/cpu_extended_state.h>
65#endif
66
67#include <atf-c.h>
68
69#include "h_macros.h"
70
71#include "t_ptrace_wait.h"
72#include "msg.h"
73
74#define PARENT_TO_CHILD(info, fds, msg) \
75    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, \
76	sizeof(msg)) == 0)
77
78#define CHILD_FROM_PARENT(info, fds, msg) \
79    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, \
80	sizeof(msg)) == 0)
81
82#define CHILD_TO_PARENT(info, fds, msg) \
83    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, \
84	sizeof(msg)) == 0)
85
86#define PARENT_FROM_CHILD(info, fds, msg) \
87    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, \
88	sizeof(msg)) == 0)
89
90#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
91    strerror(errno))
92#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
93    "%d(%s) != %d", res, strerror(res), exp)
94
95static int debug = 0;
96
97#define DPRINTF(a, ...)	do  \
98	if (debug) \
99	printf("%s() %s:%d " a, __func__, __FILE__, __LINE__,  ##__VA_ARGS__); \
100    while (/*CONSTCOND*/0)
101
102#ifndef TEST_VFORK_ENABLED
103#define TEST_VFORK_ENABLED 1
104#endif
105
106/// ----------------------------------------------------------------------------
107
108static void
109traceme_raise(int sigval)
110{
111	const int exitval = 5;
112	pid_t child, wpid;
113#if defined(TWAIT_HAVE_STATUS)
114	int status;
115#endif
116
117	struct ptrace_siginfo info;
118	memset(&info, 0, sizeof(info));
119
120	DPRINTF("Before forking process PID=%d\n", getpid());
121	SYSCALL_REQUIRE((child = fork()) != -1);
122	if (child == 0) {
123		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
124		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
125
126		DPRINTF("Before raising %s from child\n", strsignal(sigval));
127		FORKEE_ASSERT(raise(sigval) == 0);
128
129		switch (sigval) {
130		case SIGKILL:
131			/* NOTREACHED */
132			FORKEE_ASSERTX(0 && "This shall not be reached");
133			__unreachable();
134		default:
135			DPRINTF("Before exiting of the child process\n");
136			_exit(exitval);
137		}
138	}
139	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
140
141	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
142	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
143
144	switch (sigval) {
145	case SIGKILL:
146		validate_status_signaled(status, sigval, 0);
147		break;
148	default:
149		validate_status_stopped(status, sigval);
150
151		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
152			"child\n");
153		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
154			sizeof(info)) != -1);
155
156		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
157		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
158			"si_errno=%#x\n",
159			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
160			info.psi_siginfo.si_errno);
161
162		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
163		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
164
165		DPRINTF("Before resuming the child process where it left off "
166		    "and without signal to be sent\n");
167		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
168
169		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
170		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
171		    child);
172		break;
173	}
174
175	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
176	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
177}
178
179#define TRACEME_RAISE(test, sig)					\
180ATF_TC(test);								\
181ATF_TC_HEAD(test, tc)							\
182{									\
183	atf_tc_set_md_var(tc, "descr",					\
184	    "Verify " #sig " followed by _exit(2) in a child");		\
185}									\
186									\
187ATF_TC_BODY(test, tc)							\
188{									\
189									\
190	traceme_raise(sig);						\
191}
192
193TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
194TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
195TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
196TRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
197TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
198TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */
199TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */
200TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */
201TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */
202TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */
203
204/// ----------------------------------------------------------------------------
205
206static void
207traceme_raisesignal_ignored(int sigignored)
208{
209	const int exitval = 5;
210	const int sigval = SIGSTOP;
211	pid_t child, wpid;
212	struct sigaction sa;
213#if defined(TWAIT_HAVE_STATUS)
214	int status;
215#endif
216	struct ptrace_siginfo info;
217
218	memset(&info, 0, sizeof(info));
219
220	DPRINTF("Before forking process PID=%d\n", getpid());
221	SYSCALL_REQUIRE((child = fork()) != -1);
222	if (child == 0) {
223		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
224		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
225
226		memset(&sa, 0, sizeof(sa));
227		sa.sa_handler = SIG_IGN;
228		sigemptyset(&sa.sa_mask);
229		FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1);
230
231		DPRINTF("Before raising %s from child\n", strsignal(sigval));
232		FORKEE_ASSERT(raise(sigval) == 0);
233
234		DPRINTF("Before raising %s from child\n",
235		    strsignal(sigignored));
236		FORKEE_ASSERT(raise(sigignored) == 0);
237
238		DPRINTF("Before exiting of the child process\n");
239		_exit(exitval);
240	}
241	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
242
243	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
244	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
245
246	validate_status_stopped(status, sigval);
247
248	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
249	SYSCALL_REQUIRE(
250	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
251
252	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
253	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
254	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
255	    info.psi_siginfo.si_errno);
256
257	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
258	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
259
260	DPRINTF("Before resuming the child process where it left off and "
261	    "without signal to be sent\n");
262	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
263
264	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
265	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
266
267	validate_status_stopped(status, sigignored);
268
269	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
270	SYSCALL_REQUIRE(
271	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
272
273	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
274	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
275	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
276	    info.psi_siginfo.si_errno);
277
278	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored);
279	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
280
281	DPRINTF("Before resuming the child process where it left off and "
282	    "without signal to be sent\n");
283	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
284
285	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
286	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
287
288	validate_status_exited(status, exitval);
289
290	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
291	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
292}
293
294#define TRACEME_RAISESIGNAL_IGNORED(test, sig)				\
295ATF_TC(test);								\
296ATF_TC_HEAD(test, tc)							\
297{									\
298	atf_tc_set_md_var(tc, "descr",					\
299	    "Verify that ignoring (with SIG_IGN) " #sig " in tracee "	\
300	    "does not stop tracer from catching this raised signal");	\
301}									\
302									\
303ATF_TC_BODY(test, tc)							\
304{									\
305									\
306	traceme_raisesignal_ignored(sig);				\
307}
308
309// A signal handler for SIGKILL and SIGSTOP cannot be ignored.
310TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */
311TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP)  /* hangup */
312TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */
313TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */
314TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */
315TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */
316TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */
317TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */
318
319/// ----------------------------------------------------------------------------
320
321static void
322traceme_raisesignal_masked(int sigmasked)
323{
324	const int exitval = 5;
325	const int sigval = SIGSTOP;
326	pid_t child, wpid;
327#if defined(TWAIT_HAVE_STATUS)
328	int status;
329#endif
330	sigset_t intmask;
331	struct ptrace_siginfo info;
332
333	memset(&info, 0, sizeof(info));
334
335	DPRINTF("Before forking process PID=%d\n", getpid());
336	SYSCALL_REQUIRE((child = fork()) != -1);
337	if (child == 0) {
338		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
339		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
340
341		sigemptyset(&intmask);
342		sigaddset(&intmask, sigmasked);
343		sigprocmask(SIG_BLOCK, &intmask, NULL);
344
345		DPRINTF("Before raising %s from child\n", strsignal(sigval));
346		FORKEE_ASSERT(raise(sigval) == 0);
347
348		DPRINTF("Before raising %s breakpoint from child\n",
349		    strsignal(sigmasked));
350		FORKEE_ASSERT(raise(sigmasked) == 0);
351
352		DPRINTF("Before exiting of the child process\n");
353		_exit(exitval);
354	}
355	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
356
357	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
358	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
359
360	validate_status_stopped(status, sigval);
361
362	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
363	SYSCALL_REQUIRE(
364	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
365
366	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
367	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
368	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
369	    info.psi_siginfo.si_errno);
370
371	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
372	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
373
374	DPRINTF("Before resuming the child process where it left off and "
375	    "without signal to be sent\n");
376	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
377
378	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
379	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
380
381	validate_status_exited(status, exitval);
382
383	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
384	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
385}
386
387#define TRACEME_RAISESIGNAL_MASKED(test, sig)				\
388ATF_TC(test);								\
389ATF_TC_HEAD(test, tc)							\
390{									\
391	atf_tc_set_md_var(tc, "descr",					\
392	    "Verify that masking (with SIG_BLOCK) " #sig " in tracee "	\
393	    "stops tracer from catching this raised signal");		\
394}									\
395									\
396ATF_TC_BODY(test, tc)							\
397{									\
398									\
399	traceme_raisesignal_masked(sig);				\
400}
401
402// A signal handler for SIGKILL and SIGSTOP cannot be masked.
403TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */
404TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP)  /* hangup */
405TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */
406TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */
407TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */
408TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */
409TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */
410TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */
411
412/// ----------------------------------------------------------------------------
413
414static void
415traceme_crash(int sig)
416{
417	pid_t child, wpid;
418#if defined(TWAIT_HAVE_STATUS)
419	int status;
420#endif
421	struct ptrace_siginfo info;
422
423#ifndef PTRACE_ILLEGAL_ASM
424	if (sig == SIGILL)
425		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
426#endif
427
428	if (sig == SIGFPE && !are_fpu_exceptions_supported())
429		atf_tc_skip("FP exceptions are not supported");
430
431	memset(&info, 0, sizeof(info));
432
433	DPRINTF("Before forking process PID=%d\n", getpid());
434	SYSCALL_REQUIRE((child = fork()) != -1);
435	if (child == 0) {
436		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
437		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
438
439		DPRINTF("Before executing a trap\n");
440		switch (sig) {
441		case SIGTRAP:
442			trigger_trap();
443			break;
444		case SIGSEGV:
445			trigger_segv();
446			break;
447		case SIGILL:
448			trigger_ill();
449			break;
450		case SIGFPE:
451			trigger_fpe();
452			break;
453		case SIGBUS:
454			trigger_bus();
455			break;
456		default:
457			/* NOTREACHED */
458			FORKEE_ASSERTX(0 && "This shall not be reached");
459		}
460
461		/* NOTREACHED */
462		FORKEE_ASSERTX(0 && "This shall not be reached");
463	}
464	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
465
466	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
467	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
468
469	validate_status_stopped(status, sig);
470
471	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
472	SYSCALL_REQUIRE(
473	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
474
475	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
476	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
477	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
478	    info.psi_siginfo.si_errno);
479
480	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
481	switch (sig) {
482	case SIGTRAP:
483		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
484		break;
485	case SIGSEGV:
486		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
487		break;
488	case SIGILL:
489		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
490		            info.psi_siginfo.si_code <= ILL_BADSTK);
491		break;
492	case SIGFPE:
493		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
494		break;
495	case SIGBUS:
496		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
497		break;
498	}
499
500	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
501
502	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
503	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
504
505	validate_status_signaled(status, SIGKILL, 0);
506
507	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
508	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
509}
510
511#define TRACEME_CRASH(test, sig)					\
512ATF_TC(test);								\
513ATF_TC_HEAD(test, tc)							\
514{									\
515	atf_tc_set_md_var(tc, "descr",					\
516	    "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \
517}									\
518									\
519ATF_TC_BODY(test, tc)							\
520{									\
521									\
522	traceme_crash(sig);						\
523}
524
525TRACEME_CRASH(traceme_crash_trap, SIGTRAP)
526TRACEME_CRASH(traceme_crash_segv, SIGSEGV)
527TRACEME_CRASH(traceme_crash_ill, SIGILL)
528TRACEME_CRASH(traceme_crash_fpe, SIGFPE)
529TRACEME_CRASH(traceme_crash_bus, SIGBUS)
530
531/// ----------------------------------------------------------------------------
532
533static void
534traceme_signalmasked_crash(int sig)
535{
536	const int sigval = SIGSTOP;
537	pid_t child, wpid;
538#if defined(TWAIT_HAVE_STATUS)
539	int status;
540#endif
541	struct ptrace_siginfo info;
542	sigset_t intmask;
543	struct kinfo_proc2 kp;
544	size_t len = sizeof(kp);
545
546	int name[6];
547	const size_t namelen = __arraycount(name);
548	ki_sigset_t kp_sigmask;
549
550#ifndef PTRACE_ILLEGAL_ASM
551	if (sig == SIGILL)
552		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
553#endif
554
555	if (sig == SIGFPE && !are_fpu_exceptions_supported())
556		atf_tc_skip("FP exceptions are not supported");
557
558	memset(&info, 0, sizeof(info));
559
560	DPRINTF("Before forking process PID=%d\n", getpid());
561	SYSCALL_REQUIRE((child = fork()) != -1);
562	if (child == 0) {
563		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
564		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
565
566		sigemptyset(&intmask);
567		sigaddset(&intmask, sig);
568		sigprocmask(SIG_BLOCK, &intmask, NULL);
569
570		DPRINTF("Before raising %s from child\n", strsignal(sigval));
571		FORKEE_ASSERT(raise(sigval) == 0);
572
573		DPRINTF("Before executing a trap\n");
574		switch (sig) {
575		case SIGTRAP:
576			trigger_trap();
577			break;
578		case SIGSEGV:
579			trigger_segv();
580			break;
581		case SIGILL:
582			trigger_ill();
583			break;
584		case SIGFPE:
585			trigger_fpe();
586			break;
587		case SIGBUS:
588			trigger_bus();
589			break;
590		default:
591			/* NOTREACHED */
592			FORKEE_ASSERTX(0 && "This shall not be reached");
593		}
594
595		/* NOTREACHED */
596		FORKEE_ASSERTX(0 && "This shall not be reached");
597	}
598	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
599
600	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
601	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
602
603	validate_status_stopped(status, sigval);
604
605	name[0] = CTL_KERN,
606	name[1] = KERN_PROC2,
607	name[2] = KERN_PROC_PID;
608	name[3] = child;
609	name[4] = sizeof(kp);
610	name[5] = 1;
611
612	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
613
614	kp_sigmask = kp.p_sigmask;
615
616	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
617	SYSCALL_REQUIRE(
618	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
619
620	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
621	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
622	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
623	    info.psi_siginfo.si_errno);
624
625	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
626	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
627
628	DPRINTF("Before resuming the child process where it left off and "
629	    "without signal to be sent\n");
630	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
631
632	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
633	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
634
635	validate_status_stopped(status, sig);
636
637	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
638	SYSCALL_REQUIRE(
639	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
640
641	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
642	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
643	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
644	    info.psi_siginfo.si_errno);
645
646	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
647
648	DPRINTF("kp_sigmask="
649	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
650	    kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2],
651	    kp_sigmask.__bits[3]);
652
653	DPRINTF("kp.p_sigmask="
654	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
655	    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
656	    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
657
658	ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask)));
659
660	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
661	switch (sig) {
662	case SIGTRAP:
663		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
664		break;
665	case SIGSEGV:
666		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
667		break;
668	case SIGILL:
669		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
670		            info.psi_siginfo.si_code <= ILL_BADSTK);
671		break;
672	case SIGFPE:
673		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
674		break;
675	case SIGBUS:
676		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
677		break;
678	}
679
680	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
681
682	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
683	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
684
685	validate_status_signaled(status, SIGKILL, 0);
686
687	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
688	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
689}
690
691#define TRACEME_SIGNALMASKED_CRASH(test, sig)				\
692ATF_TC(test);								\
693ATF_TC_HEAD(test, tc)							\
694{									\
695	atf_tc_set_md_var(tc, "descr",					\
696	    "Verify masked crash signal " #sig " in a child after "	\
697	    "PT_TRACE_ME is delivered to its tracer");			\
698}									\
699									\
700ATF_TC_BODY(test, tc)							\
701{									\
702									\
703	traceme_signalmasked_crash(sig);				\
704}
705
706TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP)
707TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV)
708TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL)
709TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE)
710TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS)
711
712/// ----------------------------------------------------------------------------
713
714static void
715traceme_signalignored_crash(int sig)
716{
717	const int sigval = SIGSTOP;
718	pid_t child, wpid;
719#if defined(TWAIT_HAVE_STATUS)
720	int status;
721#endif
722	struct sigaction sa;
723	struct ptrace_siginfo info;
724	struct kinfo_proc2 kp;
725	size_t len = sizeof(kp);
726
727	int name[6];
728	const size_t namelen = __arraycount(name);
729	ki_sigset_t kp_sigignore;
730
731#ifndef PTRACE_ILLEGAL_ASM
732	if (sig == SIGILL)
733		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
734#endif
735
736	if (sig == SIGFPE && !are_fpu_exceptions_supported())
737		atf_tc_skip("FP exceptions are not supported");
738
739	memset(&info, 0, sizeof(info));
740
741	DPRINTF("Before forking process PID=%d\n", getpid());
742	SYSCALL_REQUIRE((child = fork()) != -1);
743	if (child == 0) {
744		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
745		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
746
747		memset(&sa, 0, sizeof(sa));
748		sa.sa_handler = SIG_IGN;
749		sigemptyset(&sa.sa_mask);
750
751		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
752
753		DPRINTF("Before raising %s from child\n", strsignal(sigval));
754		FORKEE_ASSERT(raise(sigval) == 0);
755
756		DPRINTF("Before executing a trap\n");
757		switch (sig) {
758		case SIGTRAP:
759			trigger_trap();
760			break;
761		case SIGSEGV:
762			trigger_segv();
763			break;
764		case SIGILL:
765			trigger_ill();
766			break;
767		case SIGFPE:
768			trigger_fpe();
769			break;
770		case SIGBUS:
771			trigger_bus();
772			break;
773		default:
774			/* NOTREACHED */
775			FORKEE_ASSERTX(0 && "This shall not be reached");
776		}
777
778		/* NOTREACHED */
779		FORKEE_ASSERTX(0 && "This shall not be reached");
780	}
781	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
782
783	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
784	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
785
786	validate_status_stopped(status, sigval);
787
788	name[0] = CTL_KERN,
789	name[1] = KERN_PROC2,
790	name[2] = KERN_PROC_PID;
791	name[3] = child;
792	name[4] = sizeof(kp);
793	name[5] = 1;
794
795	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
796
797	kp_sigignore = kp.p_sigignore;
798
799	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
800	SYSCALL_REQUIRE(
801	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
802
803	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
804	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
805	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
806	    info.psi_siginfo.si_errno);
807
808	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
809	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
810
811	DPRINTF("Before resuming the child process where it left off and "
812	    "without signal to be sent\n");
813	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
814
815	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
816	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
817
818	validate_status_stopped(status, sig);
819
820	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
821	SYSCALL_REQUIRE(
822	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
823
824	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
825	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
826	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
827	    info.psi_siginfo.si_errno);
828
829	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
830
831	DPRINTF("kp_sigignore="
832	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
833	    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
834	    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
835
836	DPRINTF("kp.p_sigignore="
837	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
838	    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
839	    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
840
841	ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore)));
842
843	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
844	switch (sig) {
845	case SIGTRAP:
846		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
847		break;
848	case SIGSEGV:
849		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
850		break;
851	case SIGILL:
852		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
853		            info.psi_siginfo.si_code <= ILL_BADSTK);
854		break;
855	case SIGFPE:
856		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
857		break;
858	case SIGBUS:
859		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
860		break;
861	}
862
863	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
864
865	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
866	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
867
868	validate_status_signaled(status, SIGKILL, 0);
869
870	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
871	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
872}
873
874#define TRACEME_SIGNALIGNORED_CRASH(test, sig)				\
875ATF_TC(test);								\
876ATF_TC_HEAD(test, tc)							\
877{									\
878	atf_tc_set_md_var(tc, "descr",					\
879	    "Verify ignored crash signal " #sig " in a child after "	\
880	    "PT_TRACE_ME is delivered to its tracer"); 			\
881}									\
882									\
883ATF_TC_BODY(test, tc)							\
884{									\
885									\
886	traceme_signalignored_crash(sig);				\
887}
888
889TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP)
890TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV)
891TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL)
892TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE)
893TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS)
894
895/// ----------------------------------------------------------------------------
896
897static void
898traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught)
899{
900	const int exitval = 5;
901	const int sigval = SIGSTOP;
902	pid_t child, wpid;
903	struct sigaction sa;
904#if defined(TWAIT_HAVE_STATUS)
905	int status;
906#endif
907	struct ptrace_siginfo info;
908
909	memset(&info, 0, sizeof(info));
910
911	DPRINTF("Before forking process PID=%d\n", getpid());
912	SYSCALL_REQUIRE((child = fork()) != -1);
913	if (child == 0) {
914		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
915		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
916
917		sa.sa_handler = sah;
918		sa.sa_flags = SA_SIGINFO;
919		sigemptyset(&sa.sa_mask);
920
921		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
922
923		DPRINTF("Before raising %s from child\n", strsignal(sigval));
924		FORKEE_ASSERT(raise(sigval) == 0);
925
926		FORKEE_ASSERT_EQ(*traceme_caught, 1);
927
928		DPRINTF("Before exiting of the child process\n");
929		_exit(exitval);
930	}
931	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
932
933	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
934	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
935
936	validate_status_stopped(status, sigval);
937
938	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
939	SYSCALL_REQUIRE(
940	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
941
942	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
943	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
944	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
945	    info.psi_siginfo.si_errno);
946
947	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
948	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
949
950	DPRINTF("Before resuming the child process where it left off and with "
951	    "signal %s to be sent\n", strsignal(sigsent));
952	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
953
954	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
955	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
956
957	validate_status_exited(status, exitval);
958
959	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
960	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
961}
962
963#define TRACEME_SENDSIGNAL_HANDLE(test, sig)				\
964ATF_TC(test);								\
965ATF_TC_HEAD(test, tc)							\
966{									\
967	atf_tc_set_md_var(tc, "descr",					\
968	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
969	    "handled correctly and caught by a signal handler");	\
970}									\
971									\
972static int test##_caught = 0;						\
973									\
974static void								\
975test##_sighandler(int arg)						\
976{									\
977	FORKEE_ASSERT_EQ(arg, sig);					\
978									\
979	++ test##_caught;						\
980}									\
981									\
982ATF_TC_BODY(test, tc)							\
983{									\
984									\
985	traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \
986}
987
988// A signal handler for SIGKILL and SIGSTOP cannot be registered.
989TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */
990TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP)  /* hangup */
991TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */
992TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */
993TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */
994TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */
995TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */
996TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */
997
998/// ----------------------------------------------------------------------------
999
1000static void
1001traceme_sendsignal_masked(int sigsent)
1002{
1003	const int exitval = 5;
1004	const int sigval = SIGSTOP;
1005	pid_t child, wpid;
1006	sigset_t set;
1007#if defined(TWAIT_HAVE_STATUS)
1008	int status;
1009#endif
1010	struct ptrace_siginfo info;
1011
1012	memset(&info, 0, sizeof(info));
1013
1014	DPRINTF("Before forking process PID=%d\n", getpid());
1015	SYSCALL_REQUIRE((child = fork()) != -1);
1016	if (child == 0) {
1017		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1018		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1019
1020		sigemptyset(&set);
1021		sigaddset(&set, sigsent);
1022		FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
1023
1024		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1025		FORKEE_ASSERT(raise(sigval) == 0);
1026
1027		_exit(exitval);
1028	}
1029	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1030
1031	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1032	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1033
1034	validate_status_stopped(status, sigval);
1035
1036	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1037	SYSCALL_REQUIRE(
1038	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1039
1040	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1041	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1042	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1043	    info.psi_siginfo.si_errno);
1044
1045	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1046	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1047
1048	DPRINTF("Before resuming the child process where it left off and with "
1049	    "signal %s to be sent\n", strsignal(sigsent));
1050	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1051
1052	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1053	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1054
1055	validate_status_exited(status, exitval);
1056
1057	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1058	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1059}
1060
1061#define TRACEME_SENDSIGNAL_MASKED(test, sig)				\
1062ATF_TC(test);								\
1063ATF_TC_HEAD(test, tc)							\
1064{									\
1065	atf_tc_set_md_var(tc, "descr",					\
1066	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1067	    "handled correctly and the signal is masked by SIG_BLOCK");	\
1068}									\
1069									\
1070ATF_TC_BODY(test, tc)							\
1071{									\
1072									\
1073	traceme_sendsignal_masked(sig);					\
1074}
1075
1076// A signal handler for SIGKILL and SIGSTOP cannot be masked.
1077TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */
1078TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP)  /* hangup */
1079TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */
1080TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */
1081TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */
1082TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */
1083TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */
1084TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */
1085
1086/// ----------------------------------------------------------------------------
1087
1088static void
1089traceme_sendsignal_ignored(int sigsent)
1090{
1091	const int exitval = 5;
1092	const int sigval = SIGSTOP;
1093	pid_t child, wpid;
1094	struct sigaction sa;
1095#if defined(TWAIT_HAVE_STATUS)
1096	int status;
1097#endif
1098	struct ptrace_siginfo info;
1099
1100	memset(&info, 0, sizeof(info));
1101
1102	DPRINTF("Before forking process PID=%d\n", getpid());
1103	SYSCALL_REQUIRE((child = fork()) != -1);
1104	if (child == 0) {
1105		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1106
1107		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1108
1109		memset(&sa, 0, sizeof(sa));
1110		sa.sa_handler = SIG_IGN;
1111		sigemptyset(&sa.sa_mask);
1112		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1113
1114		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1115		FORKEE_ASSERT(raise(sigval) == 0);
1116
1117		_exit(exitval);
1118	}
1119	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1120
1121	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1122	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1123
1124	validate_status_stopped(status, sigval);
1125
1126	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1127	SYSCALL_REQUIRE(
1128	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1129
1130	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1131	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1132	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1133	    info.psi_siginfo.si_errno);
1134
1135	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1136	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1137
1138	DPRINTF("Before resuming the child process where it left off and with "
1139	    "signal %s to be sent\n", strsignal(sigsent));
1140	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1141
1142	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1143	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1144
1145	validate_status_exited(status, exitval);
1146
1147	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1148	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1149}
1150
1151#define TRACEME_SENDSIGNAL_IGNORED(test, sig)				\
1152ATF_TC(test);								\
1153ATF_TC_HEAD(test, tc)							\
1154{									\
1155	atf_tc_set_md_var(tc, "descr",					\
1156	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1157	    "handled correctly and the signal is masked by SIG_IGN");	\
1158}									\
1159									\
1160ATF_TC_BODY(test, tc)							\
1161{									\
1162									\
1163	traceme_sendsignal_ignored(sig);				\
1164}
1165
1166// A signal handler for SIGKILL and SIGSTOP cannot be ignored.
1167TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */
1168TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP)  /* hangup */
1169TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */
1170TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */
1171TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */
1172TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */
1173TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */
1174TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */
1175
1176/// ----------------------------------------------------------------------------
1177
1178static void
1179traceme_sendsignal_simple(int sigsent)
1180{
1181	const int sigval = SIGSTOP;
1182	int exitval = 0;
1183	pid_t child, wpid;
1184#if defined(TWAIT_HAVE_STATUS)
1185	int status;
1186	int expect_core;
1187
1188	switch (sigsent) {
1189	case SIGABRT:
1190	case SIGTRAP:
1191	case SIGBUS:
1192	case SIGILL:
1193	case SIGFPE:
1194	case SIGSEGV:
1195		expect_core = 1;
1196		break;
1197	default:
1198		expect_core = 0;
1199		break;
1200	}
1201#endif
1202	struct ptrace_siginfo info;
1203
1204	memset(&info, 0, sizeof(info));
1205
1206	DPRINTF("Before forking process PID=%d\n", getpid());
1207	SYSCALL_REQUIRE((child = fork()) != -1);
1208	if (child == 0) {
1209		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1210		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1211
1212		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1213		FORKEE_ASSERT(raise(sigval) == 0);
1214
1215		switch (sigsent) {
1216		case SIGCONT:
1217		case SIGSTOP:
1218			_exit(exitval);
1219		default:
1220			/* NOTREACHED */
1221			FORKEE_ASSERTX(0 && "This shall not be reached");
1222		}
1223	}
1224	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1225
1226	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1227	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1228
1229	validate_status_stopped(status, sigval);
1230
1231	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1232	SYSCALL_REQUIRE(
1233	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1234
1235	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1236	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1237	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1238	    info.psi_siginfo.si_errno);
1239
1240	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1241	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1242
1243	DPRINTF("Before resuming the child process where it left off and with "
1244	    "signal %s to be sent\n", strsignal(sigsent));
1245	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1246
1247	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1248	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1249
1250	switch (sigsent) {
1251	case SIGSTOP:
1252		validate_status_stopped(status, sigsent);
1253		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1254		    "child\n");
1255		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1256		    sizeof(info)) != -1);
1257
1258		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1259		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1260		    "si_errno=%#x\n",
1261		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1262		    info.psi_siginfo.si_errno);
1263
1264		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1265		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1266
1267		DPRINTF("Before resuming the child process where it left off "
1268		    "and with signal %s to be sent\n", strsignal(sigsent));
1269		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1270
1271		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1272		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1273		    child);
1274		/* FALLTHROUGH */
1275	case SIGCONT:
1276		validate_status_exited(status, exitval);
1277		break;
1278	default:
1279		validate_status_signaled(status, sigsent, expect_core);
1280		break;
1281	}
1282
1283	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1284	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1285}
1286
1287#define TRACEME_SENDSIGNAL_SIMPLE(test, sig)				\
1288ATF_TC(test);								\
1289ATF_TC_HEAD(test, tc)							\
1290{									\
1291	atf_tc_set_md_var(tc, "descr",					\
1292	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1293	    "handled correctly in a child without a signal handler");	\
1294}									\
1295									\
1296ATF_TC_BODY(test, tc)							\
1297{									\
1298									\
1299	traceme_sendsignal_simple(sig);					\
1300}
1301
1302TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/
1303TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/
1304TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */
1305TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP)  /* hangup */
1306TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */
1307TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */
1308TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */
1309TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */
1310TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */
1311TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */
1312
1313/// ----------------------------------------------------------------------------
1314
1315ATF_TC(traceme_pid1_parent);
1316ATF_TC_HEAD(traceme_pid1_parent, tc)
1317{
1318	atf_tc_set_md_var(tc, "descr",
1319	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
1320}
1321
1322ATF_TC_BODY(traceme_pid1_parent, tc)
1323{
1324	struct msg_fds parent_child;
1325	int exitval_child1 = 1, exitval_child2 = 2;
1326	pid_t child1, child2, wpid;
1327	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1328#if defined(TWAIT_HAVE_STATUS)
1329	int status;
1330#endif
1331
1332	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
1333
1334	DPRINTF("Before forking process PID=%d\n", getpid());
1335	SYSCALL_REQUIRE((child1 = fork()) != -1);
1336	if (child1 == 0) {
1337		DPRINTF("Before forking process PID=%d\n", getpid());
1338		SYSCALL_REQUIRE((child2 = fork()) != -1);
1339		if (child2 != 0) {
1340			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
1341			    getpid(), child2);
1342			_exit(exitval_child1);
1343		}
1344		CHILD_FROM_PARENT("exit child1", parent_child, msg);
1345
1346		DPRINTF("Assert that our parent is PID1 (initproc)\n");
1347		FORKEE_ASSERT_EQ(getppid(), 1);
1348
1349		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1350		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
1351		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
1352
1353		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
1354
1355		_exit(exitval_child2);
1356	}
1357	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
1358
1359	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1360	TWAIT_REQUIRE_SUCCESS(
1361	    wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1);
1362
1363	validate_status_exited(status, exitval_child1);
1364
1365	DPRINTF("Notify that child1 is dead\n");
1366	PARENT_TO_CHILD("exit child1", parent_child, msg);
1367
1368	DPRINTF("Wait for exiting of child2\n");
1369	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
1370}
1371
1372/// ----------------------------------------------------------------------------
1373
1374static void
1375traceme_vfork_raise(int sigval)
1376{
1377	const int exitval = 5, exitval_watcher = 10;
1378	pid_t child, parent, watcher, wpid;
1379	int rv;
1380#if defined(TWAIT_HAVE_STATUS)
1381	int status;
1382
1383	/* volatile workarounds GCC -Werror=clobbered */
1384	volatile int expect_core;
1385
1386	switch (sigval) {
1387	case SIGABRT:
1388	case SIGTRAP:
1389	case SIGBUS:
1390	case SIGILL:
1391	case SIGFPE:
1392	case SIGSEGV:
1393		expect_core = 1;
1394		break;
1395	default:
1396		expect_core = 0;
1397		break;
1398	}
1399#endif
1400
1401	/*
1402	 * Spawn a dedicated thread to watch for a stopped child and emit
1403	 * the SIGKILL signal to it.
1404	 *
1405	 * vfork(2) might clobber watcher, this means that it's safer and
1406	 * simpler to reparent this process to initproc and forget about it.
1407	 */
1408	if (sigval == SIGSTOP) {
1409		parent = getpid();
1410
1411		watcher = fork();
1412		ATF_REQUIRE(watcher != 1);
1413		if (watcher == 0) {
1414			/* Double fork(2) trick to reparent to initproc */
1415			watcher = fork();
1416			FORKEE_ASSERT_NEQ(watcher, -1);
1417			if (watcher != 0)
1418				_exit(exitval_watcher);
1419
1420			child = await_stopped_child(parent);
1421
1422			errno = 0;
1423			rv = kill(child, SIGKILL);
1424			FORKEE_ASSERT_EQ(rv, 0);
1425			FORKEE_ASSERT_EQ(errno, 0);
1426
1427			/* This exit value will be collected by initproc */
1428			_exit(0);
1429		}
1430		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1431		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
1432		    watcher);
1433
1434		validate_status_exited(status, exitval_watcher);
1435
1436		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1437		TWAIT_REQUIRE_FAILURE(ECHILD,
1438		    wpid = TWAIT_GENERIC(watcher, &status, 0));
1439	}
1440
1441	DPRINTF("Before forking process PID=%d\n", getpid());
1442	SYSCALL_REQUIRE((child = vfork()) != -1);
1443	if (child == 0) {
1444		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1445		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1446
1447		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1448		FORKEE_ASSERT(raise(sigval) == 0);
1449
1450		switch (sigval) {
1451		case SIGSTOP:
1452		case SIGKILL:
1453		case SIGABRT:
1454		case SIGHUP:
1455		case SIGTRAP:
1456		case SIGBUS:
1457		case SIGILL:
1458		case SIGFPE:
1459		case SIGSEGV:
1460			/* NOTREACHED */
1461			FORKEE_ASSERTX(0 && "This shall not be reached");
1462			__unreachable();
1463		default:
1464			DPRINTF("Before exiting of the child process\n");
1465			_exit(exitval);
1466		}
1467	}
1468	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1469
1470	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1471	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1472
1473	switch (sigval) {
1474	case SIGKILL:
1475	case SIGABRT:
1476	case SIGHUP:
1477	case SIGTRAP:
1478	case SIGBUS:
1479	case SIGILL:
1480	case SIGFPE:
1481	case SIGSEGV:
1482		validate_status_signaled(status, sigval, expect_core);
1483		break;
1484	case SIGSTOP:
1485		validate_status_signaled(status, SIGKILL, 0);
1486		break;
1487	case SIGCONT:
1488	case SIGTSTP:
1489	case SIGTTIN:
1490	case SIGTTOU:
1491		validate_status_exited(status, exitval);
1492		break;
1493	default:
1494		/* NOTREACHED */
1495		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
1496		break;
1497	}
1498
1499	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1500	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1501}
1502
1503#define TRACEME_VFORK_RAISE(test, sig)					\
1504ATF_TC(test);								\
1505ATF_TC_HEAD(test, tc)							\
1506{									\
1507	atf_tc_set_md_var(tc, "descr",					\
1508	    "Verify PT_TRACE_ME followed by raise of " #sig " in a "	\
1509	    "vfork(2)ed child");					\
1510}									\
1511									\
1512ATF_TC_BODY(test, tc)							\
1513{									\
1514									\
1515	traceme_vfork_raise(sig);					\
1516}
1517
1518TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
1519TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
1520TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
1521TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
1522TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
1523TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
1524TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
1525TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
1526TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */
1527TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */
1528TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */
1529TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */
1530TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */
1531
1532/// ----------------------------------------------------------------------------
1533
1534static void
1535traceme_vfork_crash(int sig)
1536{
1537	pid_t child, wpid;
1538#if defined(TWAIT_HAVE_STATUS)
1539	int status;
1540#endif
1541
1542#ifndef PTRACE_ILLEGAL_ASM
1543	if (sig == SIGILL)
1544		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1545#endif
1546
1547	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1548		atf_tc_skip("FP exceptions are not supported");
1549
1550	DPRINTF("Before forking process PID=%d\n", getpid());
1551	SYSCALL_REQUIRE((child = vfork()) != -1);
1552	if (child == 0) {
1553		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1554		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1555
1556		DPRINTF("Before executing a trap\n");
1557		switch (sig) {
1558		case SIGTRAP:
1559			trigger_trap();
1560			break;
1561		case SIGSEGV:
1562			trigger_segv();
1563			break;
1564		case SIGILL:
1565			trigger_ill();
1566			break;
1567		case SIGFPE:
1568			trigger_fpe();
1569			break;
1570		case SIGBUS:
1571			trigger_bus();
1572			break;
1573		default:
1574			/* NOTREACHED */
1575			FORKEE_ASSERTX(0 && "This shall not be reached");
1576		}
1577
1578		/* NOTREACHED */
1579		FORKEE_ASSERTX(0 && "This shall not be reached");
1580	}
1581	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1582
1583	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1584	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1585
1586	validate_status_signaled(status, sig, 1);
1587
1588	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1589	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1590}
1591
1592#define TRACEME_VFORK_CRASH(test, sig)					\
1593ATF_TC(test);								\
1594ATF_TC_HEAD(test, tc)							\
1595{									\
1596	atf_tc_set_md_var(tc, "descr",					\
1597	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1598	    "vfork(2)ed child");					\
1599}									\
1600									\
1601ATF_TC_BODY(test, tc)							\
1602{									\
1603									\
1604	traceme_vfork_crash(sig);					\
1605}
1606
1607TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP)
1608TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV)
1609TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL)
1610TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE)
1611TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS)
1612
1613/// ----------------------------------------------------------------------------
1614
1615static void
1616traceme_vfork_signalmasked_crash(int sig)
1617{
1618	pid_t child, wpid;
1619#if defined(TWAIT_HAVE_STATUS)
1620	int status;
1621#endif
1622	sigset_t intmask;
1623
1624#ifndef PTRACE_ILLEGAL_ASM
1625	if (sig == SIGILL)
1626		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1627#endif
1628
1629	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1630		atf_tc_skip("FP exceptions are not supported");
1631
1632	DPRINTF("Before forking process PID=%d\n", getpid());
1633	SYSCALL_REQUIRE((child = vfork()) != -1);
1634	if (child == 0) {
1635		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1636		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1637
1638		sigemptyset(&intmask);
1639		sigaddset(&intmask, sig);
1640		sigprocmask(SIG_BLOCK, &intmask, NULL);
1641
1642		DPRINTF("Before executing a trap\n");
1643		switch (sig) {
1644		case SIGTRAP:
1645			trigger_trap();
1646			break;
1647		case SIGSEGV:
1648			trigger_segv();
1649			break;
1650		case SIGILL:
1651			trigger_ill();
1652			break;
1653		case SIGFPE:
1654			trigger_fpe();
1655			break;
1656		case SIGBUS:
1657			trigger_bus();
1658			break;
1659		default:
1660			/* NOTREACHED */
1661			FORKEE_ASSERTX(0 && "This shall not be reached");
1662		}
1663
1664		/* NOTREACHED */
1665		FORKEE_ASSERTX(0 && "This shall not be reached");
1666	}
1667	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1668
1669	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1670	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1671
1672	validate_status_signaled(status, sig, 1);
1673
1674	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1675	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1676}
1677
1678#define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig)			\
1679ATF_TC(test);								\
1680ATF_TC_HEAD(test, tc)							\
1681{									\
1682	atf_tc_set_md_var(tc, "descr",					\
1683	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1684	    "vfork(2)ed child with a masked signal");			\
1685}									\
1686									\
1687ATF_TC_BODY(test, tc)							\
1688{									\
1689									\
1690	traceme_vfork_signalmasked_crash(sig);				\
1691}
1692
1693TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP)
1694TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV)
1695TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL)
1696TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE)
1697TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS)
1698
1699/// ----------------------------------------------------------------------------
1700
1701static void
1702traceme_vfork_signalignored_crash(int sig)
1703{
1704	pid_t child, wpid;
1705#if defined(TWAIT_HAVE_STATUS)
1706	int status;
1707#endif
1708	struct sigaction sa;
1709
1710#ifndef PTRACE_ILLEGAL_ASM
1711	if (sig == SIGILL)
1712		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1713#endif
1714
1715	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1716		atf_tc_skip("FP exceptions are not supported");
1717
1718	DPRINTF("Before forking process PID=%d\n", getpid());
1719	SYSCALL_REQUIRE((child = vfork()) != -1);
1720	if (child == 0) {
1721		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1722		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1723
1724		memset(&sa, 0, sizeof(sa));
1725		sa.sa_handler = SIG_IGN;
1726		sigemptyset(&sa.sa_mask);
1727
1728		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1729
1730		DPRINTF("Before executing a trap\n");
1731		switch (sig) {
1732		case SIGTRAP:
1733			trigger_trap();
1734			break;
1735		case SIGSEGV:
1736			trigger_segv();
1737			break;
1738		case SIGILL:
1739			trigger_ill();
1740			break;
1741		case SIGFPE:
1742			trigger_fpe();
1743			break;
1744		case SIGBUS:
1745			trigger_bus();
1746			break;
1747		default:
1748			/* NOTREACHED */
1749			FORKEE_ASSERTX(0 && "This shall not be reached");
1750		}
1751
1752		/* NOTREACHED */
1753		FORKEE_ASSERTX(0 && "This shall not be reached");
1754	}
1755	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1756
1757	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1758	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1759
1760	validate_status_signaled(status, sig, 1);
1761
1762	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1763	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1764}
1765
1766#define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig)			\
1767ATF_TC(test);								\
1768ATF_TC_HEAD(test, tc)							\
1769{									\
1770	atf_tc_set_md_var(tc, "descr",					\
1771	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1772	    "vfork(2)ed child with ignored signal");			\
1773}									\
1774									\
1775ATF_TC_BODY(test, tc)							\
1776{									\
1777									\
1778	traceme_vfork_signalignored_crash(sig);				\
1779}
1780
1781TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,
1782    SIGTRAP)
1783TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv,
1784    SIGSEGV)
1785TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill,
1786    SIGILL)
1787TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe,
1788    SIGFPE)
1789TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus,
1790    SIGBUS)
1791
1792/// ----------------------------------------------------------------------------
1793
1794static void
1795traceme_vfork_exec(bool masked, bool ignored)
1796{
1797	const int sigval = SIGTRAP;
1798	pid_t child, wpid;
1799#if defined(TWAIT_HAVE_STATUS)
1800	int status;
1801#endif
1802	struct sigaction sa;
1803	struct ptrace_siginfo info;
1804	sigset_t intmask;
1805	struct kinfo_proc2 kp;
1806	size_t len = sizeof(kp);
1807
1808	int name[6];
1809	const size_t namelen = __arraycount(name);
1810	ki_sigset_t kp_sigmask;
1811	ki_sigset_t kp_sigignore;
1812
1813	memset(&info, 0, sizeof(info));
1814
1815	DPRINTF("Before forking process PID=%d\n", getpid());
1816	SYSCALL_REQUIRE((child = vfork()) != -1);
1817	if (child == 0) {
1818		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1819		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1820
1821		if (masked) {
1822			sigemptyset(&intmask);
1823			sigaddset(&intmask, sigval);
1824			sigprocmask(SIG_BLOCK, &intmask, NULL);
1825		}
1826
1827		if (ignored) {
1828			memset(&sa, 0, sizeof(sa));
1829			sa.sa_handler = SIG_IGN;
1830			sigemptyset(&sa.sa_mask);
1831			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
1832		}
1833
1834		DPRINTF("Before calling execve(2) from child\n");
1835		execlp("/bin/echo", "/bin/echo", NULL);
1836
1837		/* NOTREACHED */
1838		FORKEE_ASSERTX(0 && "Not reached");
1839	}
1840	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1841
1842	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1843	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1844
1845	validate_status_stopped(status, sigval);
1846
1847	name[0] = CTL_KERN,
1848	name[1] = KERN_PROC2,
1849	name[2] = KERN_PROC_PID;
1850	name[3] = getpid();
1851	name[4] = sizeof(kp);
1852	name[5] = 1;
1853
1854	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1855
1856	if (masked)
1857		kp_sigmask = kp.p_sigmask;
1858
1859	if (ignored)
1860		kp_sigignore = kp.p_sigignore;
1861
1862	name[3] = getpid();
1863
1864	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1865
1866	if (masked) {
1867		DPRINTF("kp_sigmask="
1868		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1869		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1870		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1871
1872	        DPRINTF("kp.p_sigmask="
1873	            "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1874	            kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1875	            kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1876
1877		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
1878		    sizeof(kp_sigmask)));
1879	}
1880
1881	if (ignored) {
1882		DPRINTF("kp_sigignore="
1883		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1884		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1885		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1886
1887	        DPRINTF("kp.p_sigignore="
1888	            "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1889	            kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1890	            kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1891
1892		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
1893		    sizeof(kp_sigignore)));
1894	}
1895
1896	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1897	SYSCALL_REQUIRE(
1898	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1899
1900	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1901	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1902	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1903	    info.psi_siginfo.si_errno);
1904
1905	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1906	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
1907
1908	DPRINTF("Before resuming the child process where it left off and "
1909	    "without signal to be sent\n");
1910	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1911
1912	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1913	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1914
1915	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1916	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1917}
1918
1919#define TRACEME_VFORK_EXEC(test, masked, ignored)			\
1920ATF_TC(test);								\
1921ATF_TC_HEAD(test, tc)							\
1922{									\
1923	atf_tc_set_md_var(tc, "descr",					\
1924	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed "	\
1925	    "child%s%s", masked ? " with masked signal" : "",		\
1926	    masked ? " with ignored signal" : "");			\
1927}									\
1928									\
1929ATF_TC_BODY(test, tc)							\
1930{									\
1931									\
1932	traceme_vfork_exec(masked, ignored);				\
1933}
1934
1935TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false)
1936TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false)
1937TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true)
1938
1939/// ----------------------------------------------------------------------------
1940
1941#if defined(TWAIT_HAVE_PID)
1942static void
1943unrelated_tracer_sees_crash(int sig, bool masked, bool ignored)
1944{
1945	const int sigval = SIGSTOP;
1946	struct msg_fds parent_tracee, parent_tracer;
1947	const int exitval = 10;
1948	pid_t tracee, tracer, wpid;
1949	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1950#if defined(TWAIT_HAVE_STATUS)
1951	int status;
1952#endif
1953	struct sigaction sa;
1954	struct ptrace_siginfo info;
1955	sigset_t intmask;
1956	struct kinfo_proc2 kp;
1957	size_t len = sizeof(kp);
1958
1959	int name[6];
1960	const size_t namelen = __arraycount(name);
1961	ki_sigset_t kp_sigmask;
1962	ki_sigset_t kp_sigignore;
1963
1964#ifndef PTRACE_ILLEGAL_ASM
1965	if (sig == SIGILL)
1966		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1967#endif
1968
1969	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1970		atf_tc_skip("FP exceptions are not supported");
1971
1972	memset(&info, 0, sizeof(info));
1973
1974	DPRINTF("Spawn tracee\n");
1975	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1976	tracee = atf_utils_fork();
1977	if (tracee == 0) {
1978		// Wait for parent to let us crash
1979		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
1980
1981		if (masked) {
1982			sigemptyset(&intmask);
1983			sigaddset(&intmask, sig);
1984			sigprocmask(SIG_BLOCK, &intmask, NULL);
1985		}
1986
1987		if (ignored) {
1988			memset(&sa, 0, sizeof(sa));
1989			sa.sa_handler = SIG_IGN;
1990			sigemptyset(&sa.sa_mask);
1991			FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1992		}
1993
1994		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1995		FORKEE_ASSERT(raise(sigval) == 0);
1996
1997		DPRINTF("Before executing a trap\n");
1998		switch (sig) {
1999		case SIGTRAP:
2000			trigger_trap();
2001			break;
2002		case SIGSEGV:
2003			trigger_segv();
2004			break;
2005		case SIGILL:
2006			trigger_ill();
2007			break;
2008		case SIGFPE:
2009			trigger_fpe();
2010			break;
2011		case SIGBUS:
2012			trigger_bus();
2013			break;
2014		default:
2015			/* NOTREACHED */
2016			FORKEE_ASSERTX(0 && "This shall not be reached");
2017		}
2018
2019		/* NOTREACHED */
2020		FORKEE_ASSERTX(0 && "This shall not be reached");
2021	}
2022
2023	DPRINTF("Spawn debugger\n");
2024	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2025	tracer = atf_utils_fork();
2026	if (tracer == 0) {
2027		/* Fork again and drop parent to reattach to PID 1 */
2028		tracer = atf_utils_fork();
2029		if (tracer != 0)
2030			_exit(exitval);
2031
2032		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2033		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2034
2035		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2036		FORKEE_REQUIRE_SUCCESS(
2037		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2038
2039		forkee_status_stopped(status, SIGSTOP);
2040
2041		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
2042		    "traced process\n");
2043		SYSCALL_REQUIRE(
2044		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
2045
2046		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2047		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2048		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
2049		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
2050
2051		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
2052		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
2053
2054		/* Resume tracee with PT_CONTINUE */
2055		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2056
2057		/* Inform parent that tracer has attached to tracee */
2058		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2059
2060		/* Wait for parent to tell use that tracee should have exited */
2061		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2062
2063		/* Wait for tracee and assert that it exited */
2064		FORKEE_REQUIRE_SUCCESS(
2065		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2066
2067		forkee_status_stopped(status, sigval);
2068
2069		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
2070		    "traced process\n");
2071		SYSCALL_REQUIRE(
2072		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
2073
2074		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2075		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2076		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
2077		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
2078
2079		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
2080		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
2081
2082		name[0] = CTL_KERN,
2083		name[1] = KERN_PROC2,
2084		name[2] = KERN_PROC_PID;
2085		name[3] = tracee;
2086		name[4] = sizeof(kp);
2087		name[5] = 1;
2088
2089		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2090
2091		if (masked)
2092			kp_sigmask = kp.p_sigmask;
2093
2094		if (ignored)
2095			kp_sigignore = kp.p_sigignore;
2096
2097		/* Resume tracee with PT_CONTINUE */
2098		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2099
2100		/* Wait for tracee and assert that it exited */
2101		FORKEE_REQUIRE_SUCCESS(
2102		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2103
2104		forkee_status_stopped(status, sig);
2105
2106		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
2107		    "traced process\n");
2108		SYSCALL_REQUIRE(
2109		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
2110
2111		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2112		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2113		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
2114		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
2115
2116		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig);
2117
2118		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2119
2120		if (masked) {
2121			DPRINTF("kp_sigmask="
2122			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2123			    PRIx32 "\n",
2124			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
2125			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
2126
2127			DPRINTF("kp.p_sigmask="
2128			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2129			    PRIx32 "\n",
2130			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
2131			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
2132
2133			FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask,
2134			    sizeof(kp_sigmask)));
2135		}
2136
2137		if (ignored) {
2138			DPRINTF("kp_sigignore="
2139			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2140			    PRIx32 "\n",
2141			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
2142			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
2143
2144			DPRINTF("kp.p_sigignore="
2145			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2146			    PRIx32 "\n",
2147			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
2148			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
2149
2150			FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore,
2151			    sizeof(kp_sigignore)));
2152		}
2153
2154		switch (sig) {
2155		case SIGTRAP:
2156			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
2157			break;
2158		case SIGSEGV:
2159			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
2160			break;
2161		case SIGILL:
2162			FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC &&
2163			            info.psi_siginfo.si_code <= ILL_BADSTK);
2164			break;
2165		case SIGFPE:
2166			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
2167			break;
2168		case SIGBUS:
2169			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
2170			break;
2171		}
2172
2173		FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1);
2174		DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME);
2175		FORKEE_REQUIRE_SUCCESS(
2176		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2177
2178		forkee_status_signaled(status, SIGKILL, 0);
2179
2180		/* Inform parent that tracer is exiting normally */
2181		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
2182
2183		DPRINTF("Before exiting of the tracer process\n");
2184		_exit(0 /* collect by initproc */);
2185	}
2186
2187	DPRINTF("Wait for the tracer process (direct child) to exit "
2188	    "calling %s()\n", TWAIT_FNAME);
2189	TWAIT_REQUIRE_SUCCESS(
2190	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2191
2192	validate_status_exited(status, exitval);
2193
2194	DPRINTF("Wait for the non-exited tracee process with %s()\n",
2195	    TWAIT_FNAME);
2196	TWAIT_REQUIRE_SUCCESS(
2197	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
2198
2199	DPRINTF("Wait for the tracer to attach to the tracee\n");
2200	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
2201
2202	DPRINTF("Resume the tracee and let it crash\n");
2203	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
2204
2205	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
2206	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
2207
2208	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2209	    TWAIT_FNAME);
2210	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2211
2212	validate_status_signaled(status, SIGKILL, 0);
2213
2214	DPRINTF("Await normal exit of tracer\n");
2215	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
2216
2217	msg_close(&parent_tracer);
2218	msg_close(&parent_tracee);
2219}
2220
2221#define UNRELATED_TRACER_SEES_CRASH(test, sig)				\
2222ATF_TC(test);								\
2223ATF_TC_HEAD(test, tc)							\
2224{									\
2225	atf_tc_set_md_var(tc, "descr",					\
2226	    "Assert that an unrelated tracer sees crash signal from "	\
2227	    "the debuggee");						\
2228}									\
2229									\
2230ATF_TC_BODY(test, tc)							\
2231{									\
2232									\
2233	unrelated_tracer_sees_crash(sig, false, false);			\
2234}
2235
2236UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP)
2237UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV)
2238UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL)
2239UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE)
2240UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS)
2241
2242#define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig)		\
2243ATF_TC(test);								\
2244ATF_TC_HEAD(test, tc)							\
2245{									\
2246	atf_tc_set_md_var(tc, "descr",					\
2247	    "Assert that an unrelated tracer sees crash signal from "	\
2248	    "the debuggee with masked signal");				\
2249}									\
2250									\
2251ATF_TC_BODY(test, tc)							\
2252{									\
2253									\
2254	unrelated_tracer_sees_crash(sig, true, false);			\
2255}
2256
2257UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2258    unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP)
2259UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2260    unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV)
2261UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2262    unrelated_tracer_sees_signalmasked_crash_ill, SIGILL)
2263UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2264    unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE)
2265UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2266    unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS)
2267
2268#define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig)		\
2269ATF_TC(test);								\
2270ATF_TC_HEAD(test, tc)							\
2271{									\
2272	atf_tc_set_md_var(tc, "descr",					\
2273	    "Assert that an unrelated tracer sees crash signal from "	\
2274	    "the debuggee with signal ignored");			\
2275}									\
2276									\
2277ATF_TC_BODY(test, tc)							\
2278{									\
2279									\
2280	unrelated_tracer_sees_crash(sig, false, true);			\
2281}
2282
2283UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2284    unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP)
2285UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2286    unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV)
2287UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2288    unrelated_tracer_sees_signalignored_crash_ill, SIGILL)
2289UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2290    unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE)
2291UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2292    unrelated_tracer_sees_signalignored_crash_bus, SIGBUS)
2293#endif
2294
2295/// ----------------------------------------------------------------------------
2296
2297#if defined(TWAIT_HAVE_PID)
2298static void
2299tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated,
2300                                             bool stopped)
2301{
2302	/*
2303	 * notimeout - disable timeout in await zombie function
2304	 * unrelated - attach from unrelated tracer reparented to initproc
2305	 * stopped - attach to a stopped process
2306	 */
2307
2308	struct msg_fds parent_tracee, parent_tracer;
2309	const int exitval_tracee = 5;
2310	const int exitval_tracer = 10;
2311	pid_t tracee, tracer, wpid;
2312	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2313#if defined(TWAIT_HAVE_STATUS)
2314	int status;
2315#endif
2316
2317	/*
2318	 * Only a subset of options are supported.
2319	 */
2320	ATF_REQUIRE((!notimeout && !unrelated && !stopped) ||
2321	            (!notimeout && unrelated && !stopped) ||
2322	            (notimeout && !unrelated && !stopped) ||
2323	            (!notimeout && unrelated && stopped));
2324
2325	DPRINTF("Spawn tracee\n");
2326	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2327	tracee = atf_utils_fork();
2328	if (tracee == 0) {
2329		if (stopped) {
2330			DPRINTF("Stop self PID %d\n", getpid());
2331			raise(SIGSTOP);
2332		}
2333
2334		// Wait for parent to let us exit
2335		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2336		_exit(exitval_tracee);
2337	}
2338
2339	DPRINTF("Spawn debugger\n");
2340	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2341	tracer = atf_utils_fork();
2342	if (tracer == 0) {
2343		if(unrelated) {
2344			/* Fork again and drop parent to reattach to PID 1 */
2345			tracer = atf_utils_fork();
2346			if (tracer != 0)
2347				_exit(exitval_tracer);
2348		}
2349
2350		if (stopped) {
2351			DPRINTF("Await for a stopped parent PID %d\n", tracee);
2352			await_stopped(tracee);
2353		}
2354
2355		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2356		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2357
2358		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2359		FORKEE_REQUIRE_SUCCESS(
2360		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2361
2362		forkee_status_stopped(status, SIGSTOP);
2363
2364		/* Resume tracee with PT_CONTINUE */
2365		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2366
2367		/* Inform parent that tracer has attached to tracee */
2368		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2369
2370		/* Wait for parent to tell use that tracee should have exited */
2371		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2372
2373		/* Wait for tracee and assert that it exited */
2374		FORKEE_REQUIRE_SUCCESS(
2375		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2376
2377		forkee_status_exited(status, exitval_tracee);
2378		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
2379
2380		DPRINTF("Before exiting of the tracer process\n");
2381		_exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer);
2382	}
2383
2384	if (unrelated) {
2385		DPRINTF("Wait for the tracer process (direct child) to exit "
2386		    "calling %s()\n", TWAIT_FNAME);
2387		TWAIT_REQUIRE_SUCCESS(
2388		    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2389
2390		validate_status_exited(status, exitval_tracer);
2391
2392		DPRINTF("Wait for the non-exited tracee process with %s()\n",
2393		    TWAIT_FNAME);
2394		TWAIT_REQUIRE_SUCCESS(
2395		    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
2396	}
2397
2398	DPRINTF("Wait for the tracer to attach to the tracee\n");
2399	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
2400
2401	DPRINTF("Resume the tracee and let it exit\n");
2402	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
2403
2404	DPRINTF("Detect that tracee is zombie\n");
2405	if (notimeout)
2406		await_zombie_raw(tracee, 0);
2407	else
2408		await_zombie(tracee);
2409
2410	DPRINTF("Assert that there is no status about tracee %d - "
2411	    "Tracer must detect zombie first - calling %s()\n", tracee,
2412	    TWAIT_FNAME);
2413	TWAIT_REQUIRE_SUCCESS(
2414	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2415
2416	if (unrelated) {
2417		DPRINTF("Resume the tracer and let it detect exited tracee\n");
2418		PARENT_TO_CHILD("Message 2", parent_tracer, msg);
2419	} else {
2420		DPRINTF("Tell the tracer child should have exited\n");
2421		PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
2422		DPRINTF("Wait for tracer to finish its job and exit - calling "
2423			"%s()\n", TWAIT_FNAME);
2424
2425		DPRINTF("Wait from tracer child to complete waiting for "
2426			"tracee\n");
2427		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2428		    tracer);
2429
2430		validate_status_exited(status, exitval_tracer);
2431	}
2432
2433	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2434	    TWAIT_FNAME);
2435	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2436
2437	validate_status_exited(status, exitval_tracee);
2438
2439	msg_close(&parent_tracer);
2440	msg_close(&parent_tracee);
2441}
2442
2443ATF_TC(tracer_sees_terminaton_before_the_parent);
2444ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc)
2445{
2446	atf_tc_set_md_var(tc, "descr",
2447	    "Assert that tracer sees process termination before the parent");
2448}
2449
2450ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc)
2451{
2452
2453	tracer_sees_terminaton_before_the_parent_raw(false, false, false);
2454}
2455
2456ATF_TC(tracer_sysctl_lookup_without_duplicates);
2457ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc)
2458{
2459	atf_tc_set_md_var(tc, "descr",
2460	    "Assert that await_zombie() in attach1 always finds a single "
2461	    "process and no other error is reported");
2462}
2463
2464ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc)
2465{
2466	time_t start, end;
2467	double diff;
2468	unsigned long N = 0;
2469
2470	/*
2471	 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw().
2472	 * This test body isn't specific to this race, however it's just good
2473	 * enough for this purposes, no need to invent a dedicated code flow.
2474	 */
2475
2476	start = time(NULL);
2477	while (true) {
2478		DPRINTF("Step: %lu\n", N);
2479		tracer_sees_terminaton_before_the_parent_raw(true, false,
2480		                                             false);
2481		end = time(NULL);
2482		diff = difftime(end, start);
2483		if (diff >= 5.0)
2484			break;
2485		++N;
2486	}
2487	DPRINTF("Iterations: %lu\n", N);
2488}
2489
2490ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent);
2491ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2492{
2493	atf_tc_set_md_var(tc, "descr",
2494	    "Assert that tracer sees process termination before the parent");
2495}
2496
2497ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2498{
2499
2500	tracer_sees_terminaton_before_the_parent_raw(false, true, false);
2501}
2502
2503ATF_TC(tracer_attach_to_unrelated_stopped_process);
2504ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc)
2505{
2506	atf_tc_set_md_var(tc, "descr",
2507	    "Assert that tracer can attach to an unrelated stopped process");
2508}
2509
2510ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc)
2511{
2512
2513	tracer_sees_terminaton_before_the_parent_raw(false, true, true);
2514}
2515#endif
2516
2517/// ----------------------------------------------------------------------------
2518
2519static void
2520parent_attach_to_its_child(bool stopped)
2521{
2522	struct msg_fds parent_tracee;
2523	const int exitval_tracee = 5;
2524	pid_t tracee, wpid;
2525	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2526#if defined(TWAIT_HAVE_STATUS)
2527	int status;
2528#endif
2529
2530	DPRINTF("Spawn tracee\n");
2531	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2532	tracee = atf_utils_fork();
2533	if (tracee == 0) {
2534		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2535		DPRINTF("Parent should now attach to tracee\n");
2536
2537		if (stopped) {
2538			DPRINTF("Stop self PID %d\n", getpid());
2539			SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2540		}
2541
2542		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
2543		/* Wait for message from the parent */
2544		_exit(exitval_tracee);
2545	}
2546	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2547
2548	if (stopped) {
2549		DPRINTF("Await for a stopped tracee PID %d\n", tracee);
2550		await_stopped(tracee);
2551	}
2552
2553	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
2554	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2555
2556	DPRINTF("Wait for the stopped tracee process with %s()\n",
2557	    TWAIT_FNAME);
2558	TWAIT_REQUIRE_SUCCESS(
2559	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2560
2561	validate_status_stopped(status, SIGSTOP);
2562
2563	DPRINTF("Resume tracee with PT_CONTINUE\n");
2564	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2565
2566	DPRINTF("Let the tracee exit now\n");
2567	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
2568
2569	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
2570	TWAIT_REQUIRE_SUCCESS(
2571	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2572
2573	validate_status_exited(status, exitval_tracee);
2574
2575	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
2576	TWAIT_REQUIRE_FAILURE(ECHILD,
2577	    wpid = TWAIT_GENERIC(tracee, &status, 0));
2578
2579	msg_close(&parent_tracee);
2580}
2581
2582ATF_TC(parent_attach_to_its_child);
2583ATF_TC_HEAD(parent_attach_to_its_child, tc)
2584{
2585	atf_tc_set_md_var(tc, "descr",
2586	    "Assert that tracer parent can PT_ATTACH to its child");
2587}
2588
2589ATF_TC_BODY(parent_attach_to_its_child, tc)
2590{
2591
2592	parent_attach_to_its_child(false);
2593}
2594
2595ATF_TC(parent_attach_to_its_stopped_child);
2596ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc)
2597{
2598	atf_tc_set_md_var(tc, "descr",
2599	    "Assert that tracer parent can PT_ATTACH to its stopped child");
2600}
2601
2602ATF_TC_BODY(parent_attach_to_its_stopped_child, tc)
2603{
2604
2605	parent_attach_to_its_child(true);
2606}
2607
2608/// ----------------------------------------------------------------------------
2609
2610static void
2611child_attach_to_its_parent(bool stopped)
2612{
2613	struct msg_fds parent_tracee;
2614	const int exitval_tracer = 5;
2615	pid_t tracer, wpid;
2616	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2617#if defined(TWAIT_HAVE_STATUS)
2618	int status;
2619#endif
2620
2621	DPRINTF("Spawn tracer\n");
2622	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2623	tracer = atf_utils_fork();
2624	if (tracer == 0) {
2625		/* Wait for message from the parent */
2626		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2627
2628		if (stopped) {
2629			DPRINTF("Await for a stopped parent PID %d\n",
2630			        getppid());
2631			await_stopped(getppid());
2632		}
2633
2634		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
2635		    getppid());
2636		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
2637
2638		DPRINTF("Wait for the stopped parent process with %s()\n",
2639		    TWAIT_FNAME);
2640		FORKEE_REQUIRE_SUCCESS(
2641		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
2642
2643		forkee_status_stopped(status, SIGSTOP);
2644
2645		DPRINTF("Resume parent with PT_DETACH\n");
2646		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
2647		    != -1);
2648
2649		/* Tell parent we are ready */
2650		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
2651
2652		_exit(exitval_tracer);
2653	}
2654
2655	DPRINTF("Wait for the tracer to become ready\n");
2656	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2657
2658	if (stopped) {
2659		DPRINTF("Stop self PID %d\n", getpid());
2660		SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2661	}
2662
2663	DPRINTF("Allow the tracer to exit now\n");
2664	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
2665
2666	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
2667	TWAIT_REQUIRE_SUCCESS(
2668	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2669
2670	validate_status_exited(status, exitval_tracer);
2671
2672	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
2673	TWAIT_REQUIRE_FAILURE(ECHILD,
2674	    wpid = TWAIT_GENERIC(tracer, &status, 0));
2675
2676	msg_close(&parent_tracee);
2677}
2678
2679ATF_TC(child_attach_to_its_parent);
2680ATF_TC_HEAD(child_attach_to_its_parent, tc)
2681{
2682	atf_tc_set_md_var(tc, "descr",
2683	    "Assert that tracer child can PT_ATTACH to its parent");
2684}
2685
2686ATF_TC_BODY(child_attach_to_its_parent, tc)
2687{
2688
2689	child_attach_to_its_parent(false);
2690}
2691
2692ATF_TC(child_attach_to_its_stopped_parent);
2693ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc)
2694{
2695	atf_tc_set_md_var(tc, "descr",
2696	    "Assert that tracer child can PT_ATTACH to its stopped parent");
2697}
2698
2699ATF_TC_BODY(child_attach_to_its_stopped_parent, tc)
2700{
2701	/*
2702	 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as
2703	 * this causes a pipe (established from atf-run) to be broken.
2704	 * atf-run uses this mechanism to monitor whether a test is alive.
2705	 *
2706	 * As a workaround spawn this test as a subprocess.
2707	 */
2708
2709	const int exitval = 15;
2710	pid_t child, wpid;
2711#if defined(TWAIT_HAVE_STATUS)
2712	int status;
2713#endif
2714
2715	SYSCALL_REQUIRE((child = fork()) != -1);
2716	if (child == 0) {
2717		child_attach_to_its_parent(true);
2718		_exit(exitval);
2719	} else {
2720		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2721		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2722
2723		validate_status_exited(status, exitval);
2724
2725		DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2726		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2727	}
2728}
2729
2730/// ----------------------------------------------------------------------------
2731
2732#if defined(TWAIT_HAVE_PID)
2733
2734enum tracee_sees_its_original_parent_type {
2735	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2736	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2737	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS
2738};
2739
2740static void
2741tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type)
2742{
2743	struct msg_fds parent_tracer, parent_tracee;
2744	const int exitval_tracee = 5;
2745	const int exitval_tracer = 10;
2746	pid_t parent, tracee, tracer, wpid;
2747	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2748#if defined(TWAIT_HAVE_STATUS)
2749	int status;
2750#endif
2751	/* sysctl(3) - kinfo_proc2 */
2752	int name[CTL_MAXNAME];
2753	struct kinfo_proc2 kp;
2754	size_t len = sizeof(kp);
2755	unsigned int namelen;
2756
2757	/* procfs - status  */
2758	FILE *fp;
2759	struct stat st;
2760	const char *fname = "/proc/curproc/status";
2761	char s_executable[MAXPATHLEN];
2762	int s_pid, s_ppid;
2763	int rv;
2764
2765	if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) {
2766		SYSCALL_REQUIRE(
2767		    (rv = stat(fname, &st)) == 0 || (errno == ENOENT));
2768		if (rv != 0)
2769			atf_tc_skip("/proc/curproc/status not found");
2770	}
2771
2772	DPRINTF("Spawn tracee\n");
2773	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2774	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2775	tracee = atf_utils_fork();
2776	if (tracee == 0) {
2777		parent = getppid();
2778
2779		/* Emit message to the parent */
2780		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
2781		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2782
2783		switch (type) {
2784		case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID:
2785			FORKEE_ASSERT_EQ(parent, getppid());
2786			break;
2787		case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2:
2788			namelen = 0;
2789			name[namelen++] = CTL_KERN;
2790			name[namelen++] = KERN_PROC2;
2791			name[namelen++] = KERN_PROC_PID;
2792			name[namelen++] = getpid();
2793			name[namelen++] = len;
2794			name[namelen++] = 1;
2795
2796			FORKEE_ASSERT_EQ(
2797			    sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2798			FORKEE_ASSERT_EQ(parent, kp.p_ppid);
2799			break;
2800		case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS:
2801			/*
2802			 * Format:
2803			 *  EXECUTABLE PID PPID ...
2804			 */
2805			FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
2806			fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
2807			FORKEE_ASSERT_EQ(fclose(fp), 0);
2808			FORKEE_ASSERT_EQ(parent, s_ppid);
2809			break;
2810		}
2811
2812		_exit(exitval_tracee);
2813	}
2814	DPRINTF("Wait for child to record its parent identifier (pid)\n");
2815	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
2816
2817	DPRINTF("Spawn debugger\n");
2818	tracer = atf_utils_fork();
2819	if (tracer == 0) {
2820		/* No IPC to communicate with the child */
2821		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2822		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2823
2824		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2825		FORKEE_REQUIRE_SUCCESS(
2826		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2827
2828		forkee_status_stopped(status, SIGSTOP);
2829
2830		/* Resume tracee with PT_CONTINUE */
2831		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2832
2833		/* Inform parent that tracer has attached to tracee */
2834		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2835
2836		/* Wait for parent to tell use that tracee should have exited */
2837		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2838
2839		/* Wait for tracee and assert that it exited */
2840		FORKEE_REQUIRE_SUCCESS(
2841		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2842
2843		forkee_status_exited(status, exitval_tracee);
2844
2845		DPRINTF("Before exiting of the tracer process\n");
2846		_exit(exitval_tracer);
2847	}
2848
2849	DPRINTF("Wait for the tracer to attach to the tracee\n");
2850	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
2851
2852	DPRINTF("Resume the tracee and let it exit\n");
2853	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
2854
2855	DPRINTF("Detect that tracee is zombie\n");
2856	await_zombie(tracee);
2857
2858	DPRINTF("Assert that there is no status about tracee - "
2859	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
2860	TWAIT_REQUIRE_SUCCESS(
2861	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2862
2863	DPRINTF("Tell the tracer child should have exited\n");
2864	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
2865
2866	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
2867	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2868	    tracer);
2869
2870	validate_status_exited(status, exitval_tracer);
2871
2872	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2873	    TWAIT_FNAME);
2874	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
2875	    tracee);
2876
2877	validate_status_exited(status, exitval_tracee);
2878
2879	msg_close(&parent_tracer);
2880	msg_close(&parent_tracee);
2881}
2882
2883#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr)		\
2884ATF_TC(test);								\
2885ATF_TC_HEAD(test, tc)							\
2886{									\
2887	atf_tc_set_md_var(tc, "descr",					\
2888	    "Assert that tracee sees its original parent when being traced " \
2889	    "(check " descr ")");					\
2890}									\
2891									\
2892ATF_TC_BODY(test, tc)							\
2893{									\
2894									\
2895	tracee_sees_its_original_parent(type);				\
2896}
2897
2898TRACEE_SEES_ITS_ORIGINAL_PARENT(
2899	tracee_sees_its_original_parent_getppid,
2900	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2901	"getppid(2)");
2902TRACEE_SEES_ITS_ORIGINAL_PARENT(
2903	tracee_sees_its_original_parent_sysctl_kinfo_proc2,
2904	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2905	"sysctl(3) and kinfo_proc2");
2906TRACEE_SEES_ITS_ORIGINAL_PARENT(
2907	tracee_sees_its_original_parent_procfs_status,
2908	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS,
2909	"the status file in procfs");
2910#endif
2911
2912/// ----------------------------------------------------------------------------
2913
2914static void
2915eventmask_preserved(int event)
2916{
2917	const int exitval = 5;
2918	const int sigval = SIGSTOP;
2919	pid_t child, wpid;
2920#if defined(TWAIT_HAVE_STATUS)
2921	int status;
2922#endif
2923	ptrace_event_t set_event, get_event;
2924	const int len = sizeof(ptrace_event_t);
2925
2926	DPRINTF("Before forking process PID=%d\n", getpid());
2927	SYSCALL_REQUIRE((child = fork()) != -1);
2928	if (child == 0) {
2929		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2930		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2931
2932		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2933		FORKEE_ASSERT(raise(sigval) == 0);
2934
2935		DPRINTF("Before exiting of the child process\n");
2936		_exit(exitval);
2937	}
2938	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2939
2940	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2941	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2942
2943	validate_status_stopped(status, sigval);
2944
2945	set_event.pe_set_event = event;
2946	SYSCALL_REQUIRE(
2947	    ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
2948	SYSCALL_REQUIRE(
2949	    ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
2950	DPRINTF("set_event=%#x get_event=%#x\n", set_event.pe_set_event,
2951	    get_event.pe_set_event);
2952	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
2953
2954	DPRINTF("Before resuming the child process where it left off and "
2955	    "without signal to be sent\n");
2956	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2957
2958	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2959	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2960
2961	validate_status_exited(status, exitval);
2962
2963	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2964	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2965}
2966
2967#define EVENTMASK_PRESERVED(test, event)				\
2968ATF_TC(test);								\
2969ATF_TC_HEAD(test, tc)							\
2970{									\
2971	atf_tc_set_md_var(tc, "descr",					\
2972	    "Verify that eventmask " #event " is preserved");		\
2973}									\
2974									\
2975ATF_TC_BODY(test, tc)							\
2976{									\
2977									\
2978	eventmask_preserved(event);					\
2979}
2980
2981EVENTMASK_PRESERVED(eventmask_preserved_empty, 0)
2982EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK)
2983EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK)
2984EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE)
2985EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE)
2986EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT)
2987EVENTMASK_PRESERVED(eventmask_preserved_posix_spawn, PTRACE_POSIX_SPAWN)
2988
2989/// ----------------------------------------------------------------------------
2990
2991static void
2992fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork,
2993    bool trackvforkdone)
2994{
2995	const int exitval = 5;
2996	const int exitval2 = 0; /* This matched exit status from /bin/echo */
2997	const int sigval = SIGSTOP;
2998	pid_t child, child2 = 0, wpid;
2999#if defined(TWAIT_HAVE_STATUS)
3000	int status;
3001#endif
3002	ptrace_state_t state;
3003	const int slen = sizeof(state);
3004	ptrace_event_t event;
3005	const int elen = sizeof(event);
3006
3007	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
3008
3009	DPRINTF("Before forking process PID=%d\n", getpid());
3010	SYSCALL_REQUIRE((child = fork()) != -1);
3011	if (child == 0) {
3012		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3013		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3014
3015		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3016		FORKEE_ASSERT(raise(sigval) == 0);
3017
3018		if (strcmp(fn, "spawn") == 0) {
3019			FORKEE_ASSERT_EQ(posix_spawn(&child2,
3020			    arg[0], NULL, NULL, arg, NULL), 0);
3021		} else {
3022			if (strcmp(fn, "fork") == 0) {
3023				FORKEE_ASSERT((child2 = fork()) != -1);
3024			} else if (strcmp(fn, "vfork") == 0) {
3025				FORKEE_ASSERT((child2 = vfork()) != -1);
3026			}
3027
3028			if (child2 == 0)
3029				_exit(exitval2);
3030		}
3031		FORKEE_REQUIRE_SUCCESS
3032		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3033
3034		forkee_status_exited(status, exitval2);
3035
3036		DPRINTF("Before exiting of the child process\n");
3037		_exit(exitval);
3038	}
3039	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3040
3041	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3042	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3043
3044	validate_status_stopped(status, sigval);
3045
3046	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
3047	    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
3048	    trackfork ? "|PTRACE_FORK" : "",
3049	    trackvfork ? "|PTRACE_VFORK" : "",
3050	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
3051	event.pe_set_event = 0;
3052	if (trackspawn)
3053		event.pe_set_event |= PTRACE_POSIX_SPAWN;
3054	if (trackfork)
3055		event.pe_set_event |= PTRACE_FORK;
3056	if (trackvfork)
3057		event.pe_set_event |= PTRACE_VFORK;
3058	if (trackvforkdone)
3059		event.pe_set_event |= PTRACE_VFORK_DONE;
3060	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
3061
3062	DPRINTF("Before resuming the child process where it left off and "
3063	    "without signal to be sent\n");
3064	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3065
3066#if defined(TWAIT_HAVE_PID)
3067	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
3068	    (trackfork && strcmp(fn, "fork") == 0) ||
3069	    (trackvfork && strcmp(fn, "vfork") == 0)) {
3070		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
3071		    child);
3072		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3073		    child);
3074
3075		validate_status_stopped(status, SIGTRAP);
3076
3077		SYSCALL_REQUIRE(
3078		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3079		if (trackspawn && strcmp(fn, "spawn") == 0) {
3080			ATF_REQUIRE_EQ(
3081			    state.pe_report_event & PTRACE_POSIX_SPAWN,
3082			       PTRACE_POSIX_SPAWN);
3083		}
3084		if (trackfork && strcmp(fn, "fork") == 0) {
3085			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
3086			       PTRACE_FORK);
3087		}
3088		if (trackvfork && strcmp(fn, "vfork") == 0) {
3089			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
3090			       PTRACE_VFORK);
3091		}
3092
3093		child2 = state.pe_other_pid;
3094		DPRINTF("Reported ptrace event with forkee %d\n", child2);
3095
3096		DPRINTF("Before calling %s() for the forkee %d of the child "
3097		    "%d\n", TWAIT_FNAME, child2, child);
3098		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
3099		    child2);
3100
3101		validate_status_stopped(status, SIGTRAP);
3102
3103		SYSCALL_REQUIRE(
3104		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
3105		if (trackspawn && strcmp(fn, "spawn") == 0) {
3106			ATF_REQUIRE_EQ(
3107			    state.pe_report_event & PTRACE_POSIX_SPAWN,
3108			       PTRACE_POSIX_SPAWN);
3109		}
3110		if (trackfork && strcmp(fn, "fork") == 0) {
3111			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
3112			       PTRACE_FORK);
3113		}
3114		if (trackvfork && strcmp(fn, "vfork") == 0) {
3115			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
3116			       PTRACE_VFORK);
3117		}
3118
3119		ATF_REQUIRE_EQ(state.pe_other_pid, child);
3120
3121		DPRINTF("Before resuming the forkee process where it left off "
3122		    "and without signal to be sent\n");
3123		SYSCALL_REQUIRE(
3124		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
3125
3126		DPRINTF("Before resuming the child process where it left off "
3127		    "and without signal to be sent\n");
3128		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3129	}
3130#endif
3131
3132	if (trackvforkdone && strcmp(fn, "vfork") == 0) {
3133		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
3134		    child);
3135		TWAIT_REQUIRE_SUCCESS(
3136		    wpid = TWAIT_GENERIC(child, &status, 0), child);
3137
3138		validate_status_stopped(status, SIGTRAP);
3139
3140		SYSCALL_REQUIRE(
3141		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3142		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
3143
3144		child2 = state.pe_other_pid;
3145		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
3146		    child2);
3147
3148		DPRINTF("Before resuming the child process where it left off "
3149		    "and without signal to be sent\n");
3150		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3151	}
3152
3153#if defined(TWAIT_HAVE_PID)
3154	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
3155	    (trackfork && strcmp(fn, "fork") == 0) ||
3156	    (trackvfork && strcmp(fn, "vfork") == 0)) {
3157		DPRINTF("Before calling %s() for the forkee - expected exited"
3158		    "\n", TWAIT_FNAME);
3159		TWAIT_REQUIRE_SUCCESS(
3160		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3161
3162		validate_status_exited(status, exitval2);
3163
3164		DPRINTF("Before calling %s() for the forkee - expected no "
3165		    "process\n", TWAIT_FNAME);
3166		TWAIT_REQUIRE_FAILURE(ECHILD,
3167		    wpid = TWAIT_GENERIC(child2, &status, 0));
3168	}
3169#endif
3170
3171	DPRINTF("Before calling %s() for the child - expected stopped "
3172	    "SIGCHLD\n", TWAIT_FNAME);
3173	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3174
3175	validate_status_stopped(status, SIGCHLD);
3176
3177	DPRINTF("Before resuming the child process where it left off and "
3178	    "without signal to be sent\n");
3179	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3180
3181	DPRINTF("Before calling %s() for the child - expected exited\n",
3182	    TWAIT_FNAME);
3183	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3184
3185	validate_status_exited(status, exitval);
3186
3187	DPRINTF("Before calling %s() for the child - expected no process\n",
3188	    TWAIT_FNAME);
3189	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3190}
3191
3192#define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)		\
3193ATF_TC(name);								\
3194ATF_TC_HEAD(name, tc)							\
3195{									\
3196	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
3197	    "called with 0%s%s%s%s in EVENT_MASK",			\
3198	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
3199	    tfork ? "|PTRACE_FORK" : "",				\
3200	    tvfork ? "|PTRACE_VFORK" : "",				\
3201	    tvforkdone ? "|PTRACE_VFORK_DONE" : "");			\
3202}									\
3203									\
3204ATF_TC_BODY(name, tc)							\
3205{									\
3206									\
3207	fork_body(fun, tspawn, tfork, tvfork, tvforkdone);		\
3208}
3209
3210FORK_TEST(fork1, "fork", false, false, false, false)
3211#if defined(TWAIT_HAVE_PID)
3212FORK_TEST(fork2, "fork", false, true, false, false)
3213FORK_TEST(fork3, "fork", false, false, true, false)
3214FORK_TEST(fork4, "fork", false, true, true, false)
3215#endif
3216FORK_TEST(fork5, "fork", false, false, false, true)
3217#if defined(TWAIT_HAVE_PID)
3218FORK_TEST(fork6, "fork", false, true, false, true)
3219FORK_TEST(fork7, "fork", false, false, true, true)
3220FORK_TEST(fork8, "fork", false, true, true, true)
3221#endif
3222FORK_TEST(fork9, "fork", true, false, false, false)
3223#if defined(TWAIT_HAVE_PID)
3224FORK_TEST(fork10, "fork", true, true, false, false)
3225FORK_TEST(fork11, "fork", true, false, true, false)
3226FORK_TEST(fork12, "fork", true, true, true, false)
3227#endif
3228FORK_TEST(fork13, "fork", true, false, false, true)
3229#if defined(TWAIT_HAVE_PID)
3230FORK_TEST(fork14, "fork", true, true, false, true)
3231FORK_TEST(fork15, "fork", true, false, true, true)
3232FORK_TEST(fork16, "fork", true, true, true, true)
3233#endif
3234
3235#if TEST_VFORK_ENABLED
3236FORK_TEST(vfork1, "vfork", false, false, false, false)
3237#if defined(TWAIT_HAVE_PID)
3238FORK_TEST(vfork2, "vfork", false, true, false, false)
3239FORK_TEST(vfork3, "vfork", false, false, true, false)
3240FORK_TEST(vfork4, "vfork", false, true, true, false)
3241#endif
3242FORK_TEST(vfork5, "vfork", false, false, false, true)
3243#if defined(TWAIT_HAVE_PID)
3244FORK_TEST(vfork6, "vfork", false, true, false, true)
3245FORK_TEST(vfork7, "vfork", false, false, true, true)
3246FORK_TEST(vfork8, "vfork", false, true, true, true)
3247#endif
3248FORK_TEST(vfork9, "vfork", true, false, false, false)
3249#if defined(TWAIT_HAVE_PID)
3250FORK_TEST(vfork10, "vfork", true, true, false, false)
3251FORK_TEST(vfork11, "vfork", true, false, true, false)
3252FORK_TEST(vfork12, "vfork", true, true, true, false)
3253#endif
3254FORK_TEST(vfork13, "vfork", true, false, false, true)
3255#if defined(TWAIT_HAVE_PID)
3256FORK_TEST(vfork14, "vfork", true, true, false, true)
3257FORK_TEST(vfork15, "vfork", true, false, true, true)
3258FORK_TEST(vfork16, "vfork", true, true, true, true)
3259#endif
3260#endif
3261
3262FORK_TEST(posix_spawn1, "spawn", false, false, false, false)
3263FORK_TEST(posix_spawn2, "spawn", false, true, false, false)
3264FORK_TEST(posix_spawn3, "spawn", false, false, true, false)
3265FORK_TEST(posix_spawn4, "spawn", false, true, true, false)
3266FORK_TEST(posix_spawn5, "spawn", false, false, false, true)
3267FORK_TEST(posix_spawn6, "spawn", false, true, false, true)
3268FORK_TEST(posix_spawn7, "spawn", false, false, true, true)
3269FORK_TEST(posix_spawn8, "spawn", false, true, true, true)
3270#if defined(TWAIT_HAVE_PID)
3271FORK_TEST(posix_spawn9, "spawn", true, false, false, false)
3272FORK_TEST(posix_spawn10, "spawn", true, true, false, false)
3273FORK_TEST(posix_spawn11, "spawn", true, false, true, false)
3274FORK_TEST(posix_spawn12, "spawn", true, true, true, false)
3275FORK_TEST(posix_spawn13, "spawn", true, false, false, true)
3276FORK_TEST(posix_spawn14, "spawn", true, true, false, true)
3277FORK_TEST(posix_spawn15, "spawn", true, false, true, true)
3278FORK_TEST(posix_spawn16, "spawn", true, true, true, true)
3279#endif
3280
3281/// ----------------------------------------------------------------------------
3282
3283#if defined(TWAIT_HAVE_PID)
3284static void
3285fork_detach_forker_body(const char *fn, bool kill_process)
3286{
3287	const int exitval = 5;
3288	const int exitval2 = 0; /* Matches exit value from /bin/echo */
3289	const int sigval = SIGSTOP;
3290	pid_t child, child2 = 0, wpid;
3291#if defined(TWAIT_HAVE_STATUS)
3292	int status;
3293#endif
3294	ptrace_state_t state;
3295	const int slen = sizeof(state);
3296	ptrace_event_t event;
3297	const int elen = sizeof(event);
3298
3299	int op;
3300
3301	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
3302
3303	DPRINTF("Before forking process PID=%d\n", getpid());
3304	SYSCALL_REQUIRE((child = fork()) != -1);
3305	if (child == 0) {
3306		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3307		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3308
3309		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3310		FORKEE_ASSERT(raise(sigval) == 0);
3311
3312		if (strcmp(fn, "spawn") == 0) {
3313			FORKEE_ASSERT_EQ(posix_spawn(&child2,
3314			    arg[0], NULL, NULL, arg, NULL), 0);
3315		} else  {
3316			if (strcmp(fn, "fork") == 0) {
3317				FORKEE_ASSERT((child2 = fork()) != -1);
3318			} else {
3319				FORKEE_ASSERT((child2 = vfork()) != -1);
3320			}
3321
3322			if (child2 == 0)
3323				_exit(exitval2);
3324		}
3325
3326		FORKEE_REQUIRE_SUCCESS
3327		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3328
3329		forkee_status_exited(status, exitval2);
3330
3331		DPRINTF("Before exiting of the child process\n");
3332		_exit(exitval);
3333	}
3334	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3335
3336	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3337	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3338
3339	validate_status_stopped(status, sigval);
3340
3341	DPRINTF("Set EVENT_MASK for the child %d\n", child);
3342	event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
3343		| PTRACE_VFORK_DONE;
3344	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
3345
3346	DPRINTF("Before resuming the child process where it left off and "
3347	    "without signal to be sent\n");
3348	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3349
3350	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
3351	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3352
3353	validate_status_stopped(status, SIGTRAP);
3354
3355	SYSCALL_REQUIRE(
3356	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3357
3358	if (strcmp(fn, "spawn") == 0)
3359		op = PTRACE_POSIX_SPAWN;
3360	else if (strcmp(fn, "fork") == 0)
3361		op = PTRACE_FORK;
3362	else
3363		op = PTRACE_VFORK;
3364
3365	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
3366
3367	child2 = state.pe_other_pid;
3368	DPRINTF("Reported ptrace event with forkee %d\n", child2);
3369
3370	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
3371	    strcmp(fn, "vfork") == 0)
3372		op = kill_process ? PT_KILL : PT_DETACH;
3373	else
3374		op = PT_CONTINUE;
3375	SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
3376
3377	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
3378	    TWAIT_FNAME, child2, child);
3379	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3380
3381	validate_status_stopped(status, SIGTRAP);
3382
3383	SYSCALL_REQUIRE(
3384	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
3385	if (strcmp(fn, "spawn") == 0)
3386		op = PTRACE_POSIX_SPAWN;
3387	else if (strcmp(fn, "fork") == 0)
3388		op = PTRACE_FORK;
3389	else
3390		op = PTRACE_VFORK;
3391
3392	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
3393	ATF_REQUIRE_EQ(state.pe_other_pid, child);
3394
3395	DPRINTF("Before resuming the forkee process where it left off "
3396	    "and without signal to be sent\n");
3397 	SYSCALL_REQUIRE(
3398	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
3399
3400	if (strcmp(fn, "vforkdone") == 0) {
3401		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
3402		    child);
3403		TWAIT_REQUIRE_SUCCESS(
3404		    wpid = TWAIT_GENERIC(child, &status, 0), child);
3405
3406		validate_status_stopped(status, SIGTRAP);
3407
3408		SYSCALL_REQUIRE(
3409		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3410		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
3411
3412		child2 = state.pe_other_pid;
3413		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
3414		    child2);
3415
3416		op = kill_process ? PT_KILL : PT_DETACH;
3417		DPRINTF("Before resuming the child process where it left off "
3418		    "and without signal to be sent\n");
3419		SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
3420	}
3421
3422	DPRINTF("Before calling %s() for the forkee - expected exited\n",
3423	    TWAIT_FNAME);
3424	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3425
3426	validate_status_exited(status, exitval2);
3427
3428	DPRINTF("Before calling %s() for the forkee - expected no process\n",
3429	    TWAIT_FNAME);
3430	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0));
3431
3432	DPRINTF("Before calling %s() for the forkee - expected exited\n",
3433	    TWAIT_FNAME);
3434	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3435
3436	if (kill_process) {
3437		validate_status_signaled(status, SIGKILL, 0);
3438	} else {
3439		validate_status_exited(status, exitval);
3440	}
3441
3442	DPRINTF("Before calling %s() for the child - expected no process\n",
3443	    TWAIT_FNAME);
3444	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3445}
3446
3447#define FORK_DETACH_FORKER(name,event,kprocess)				\
3448ATF_TC(name);								\
3449ATF_TC_HEAD(name, tc)							\
3450{									\
3451	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
3452	    kprocess ? "killed" : "detached");				\
3453}									\
3454									\
3455ATF_TC_BODY(name, tc)							\
3456{									\
3457									\
3458	fork_detach_forker_body(event, kprocess);			\
3459}
3460
3461FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false)
3462FORK_DETACH_FORKER(fork_detach_forker, "fork", false)
3463#if TEST_VFORK_ENABLED
3464FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false)
3465FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false)
3466#endif
3467
3468FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true)
3469FORK_DETACH_FORKER(fork_kill_forker, "fork", true)
3470#if TEST_VFORK_ENABLED
3471FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true)
3472FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true)
3473#endif
3474#endif
3475
3476/// ----------------------------------------------------------------------------
3477
3478#if TEST_VFORK_ENABLED
3479static void
3480traceme_vfork_fork_body(pid_t (*fn)(void))
3481{
3482	const int exitval = 5;
3483	const int exitval2 = 15;
3484	pid_t child, child2 = 0, wpid;
3485#if defined(TWAIT_HAVE_STATUS)
3486	int status;
3487#endif
3488
3489	DPRINTF("Before forking process PID=%d\n", getpid());
3490	SYSCALL_REQUIRE((child = vfork()) != -1);
3491	if (child == 0) {
3492		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3493		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3494
3495		FORKEE_ASSERT((child2 = (fn)()) != -1);
3496
3497		if (child2 == 0)
3498			_exit(exitval2);
3499
3500		FORKEE_REQUIRE_SUCCESS
3501		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3502
3503		forkee_status_exited(status, exitval2);
3504
3505		DPRINTF("Before exiting of the child process\n");
3506		_exit(exitval);
3507	}
3508	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3509
3510	DPRINTF("Before calling %s() for the child - expected exited\n",
3511	    TWAIT_FNAME);
3512	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3513
3514	validate_status_exited(status, exitval);
3515
3516	DPRINTF("Before calling %s() for the child - expected no process\n",
3517	    TWAIT_FNAME);
3518	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3519}
3520
3521#define TRACEME_VFORK_FORK_TEST(name,fun)				\
3522ATF_TC(name);								\
3523ATF_TC_HEAD(name, tc)							\
3524{									\
3525	atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) "		\
3526	    "called from vfork(2)ed child");				\
3527}									\
3528									\
3529ATF_TC_BODY(name, tc)							\
3530{									\
3531									\
3532	traceme_vfork_fork_body(fun);					\
3533}
3534
3535TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork)
3536TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork)
3537#endif
3538
3539/// ----------------------------------------------------------------------------
3540
3541enum bytes_transfer_type {
3542	BYTES_TRANSFER_DATA,
3543	BYTES_TRANSFER_DATAIO,
3544	BYTES_TRANSFER_TEXT,
3545	BYTES_TRANSFER_TEXTIO,
3546	BYTES_TRANSFER_AUXV
3547};
3548
3549static int __used
3550bytes_transfer_dummy(int a, int b, int c, int d)
3551{
3552	int e, f, g, h;
3553
3554	a *= 4;
3555	b += 3;
3556	c -= 2;
3557	d /= 1;
3558
3559	e = strtol("10", NULL, 10);
3560	f = strtol("20", NULL, 10);
3561	g = strtol("30", NULL, 10);
3562	h = strtol("40", NULL, 10);
3563
3564	return (a + b * c - d) + (e * f - g / h);
3565}
3566
3567static void
3568bytes_transfer(int operation, size_t size, enum bytes_transfer_type type)
3569{
3570	const int exitval = 5;
3571	const int sigval = SIGSTOP;
3572	pid_t child, wpid;
3573	bool skip = false;
3574
3575	int lookup_me = 0;
3576	uint8_t lookup_me8 = 0;
3577	uint16_t lookup_me16 = 0;
3578	uint32_t lookup_me32 = 0;
3579	uint64_t lookup_me64 = 0;
3580
3581	int magic = 0x13579246;
3582	uint8_t magic8 = 0xab;
3583	uint16_t magic16 = 0x1234;
3584	uint32_t magic32 = 0x98765432;
3585	uint64_t magic64 = 0xabcdef0123456789;
3586
3587	struct ptrace_io_desc io;
3588#if defined(TWAIT_HAVE_STATUS)
3589	int status;
3590#endif
3591	/* 513 is just enough, for the purposes of ATF it's good enough */
3592	AuxInfo ai[513], *aip;
3593
3594	ATF_REQUIRE(size < sizeof(ai));
3595
3596	/* Prepare variables for .TEXT transfers */
3597	switch (type) {
3598	case BYTES_TRANSFER_TEXT:
3599		memcpy(&magic, bytes_transfer_dummy, sizeof(magic));
3600		break;
3601	case BYTES_TRANSFER_TEXTIO:
3602		switch (size) {
3603		case 8:
3604			memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8));
3605			break;
3606		case 16:
3607			memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16));
3608			break;
3609		case 32:
3610			memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32));
3611			break;
3612		case 64:
3613			memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64));
3614			break;
3615		}
3616		break;
3617	default:
3618		break;
3619	}
3620
3621	/* Prepare variables for PIOD and AUXV transfers */
3622	switch (type) {
3623	case BYTES_TRANSFER_TEXTIO:
3624	case BYTES_TRANSFER_DATAIO:
3625		io.piod_op = operation;
3626		switch (size) {
3627		case 8:
3628			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3629			               (void *)bytes_transfer_dummy :
3630			               &lookup_me8;
3631			io.piod_addr = &lookup_me8;
3632			io.piod_len = sizeof(lookup_me8);
3633			break;
3634		case 16:
3635			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3636			               (void *)bytes_transfer_dummy :
3637			               &lookup_me16;
3638			io.piod_addr = &lookup_me16;
3639			io.piod_len = sizeof(lookup_me16);
3640			break;
3641		case 32:
3642			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3643			               (void *)bytes_transfer_dummy :
3644			               &lookup_me32;
3645			io.piod_addr = &lookup_me32;
3646			io.piod_len = sizeof(lookup_me32);
3647			break;
3648		case 64:
3649			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3650			               (void *)bytes_transfer_dummy :
3651			               &lookup_me64;
3652			io.piod_addr = &lookup_me64;
3653			io.piod_len = sizeof(lookup_me64);
3654			break;
3655		default:
3656			break;
3657		}
3658		break;
3659	case BYTES_TRANSFER_AUXV:
3660		io.piod_op = operation;
3661		io.piod_offs = 0;
3662		io.piod_addr = ai;
3663		io.piod_len = size;
3664		break;
3665	default:
3666		break;
3667	}
3668
3669	DPRINTF("Before forking process PID=%d\n", getpid());
3670	SYSCALL_REQUIRE((child = fork()) != -1);
3671	if (child == 0) {
3672		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3673		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3674
3675		switch (type) {
3676		case BYTES_TRANSFER_DATA:
3677			switch (operation) {
3678			case PT_READ_D:
3679			case PT_READ_I:
3680				lookup_me = magic;
3681				break;
3682			default:
3683				break;
3684			}
3685			break;
3686		case BYTES_TRANSFER_DATAIO:
3687			switch (operation) {
3688			case PIOD_READ_D:
3689			case PIOD_READ_I:
3690				switch (size) {
3691				case 8:
3692					lookup_me8 = magic8;
3693					break;
3694				case 16:
3695					lookup_me16 = magic16;
3696					break;
3697				case 32:
3698					lookup_me32 = magic32;
3699					break;
3700				case 64:
3701					lookup_me64 = magic64;
3702					break;
3703				default:
3704					break;
3705				}
3706				break;
3707			default:
3708				break;
3709			}
3710		default:
3711			break;
3712		}
3713
3714		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3715		FORKEE_ASSERT(raise(sigval) == 0);
3716
3717		/* Handle PIOD and PT separately as operation values overlap */
3718		switch (type) {
3719		case BYTES_TRANSFER_DATA:
3720			switch (operation) {
3721			case PT_WRITE_D:
3722			case PT_WRITE_I:
3723				FORKEE_ASSERT_EQ(lookup_me, magic);
3724				break;
3725			default:
3726				break;
3727			}
3728			break;
3729		case BYTES_TRANSFER_DATAIO:
3730			switch (operation) {
3731			case PIOD_WRITE_D:
3732			case PIOD_WRITE_I:
3733				switch (size) {
3734				case 8:
3735					FORKEE_ASSERT_EQ(lookup_me8, magic8);
3736					break;
3737				case 16:
3738					FORKEE_ASSERT_EQ(lookup_me16, magic16);
3739					break;
3740				case 32:
3741					FORKEE_ASSERT_EQ(lookup_me32, magic32);
3742					break;
3743				case 64:
3744					FORKEE_ASSERT_EQ(lookup_me64, magic64);
3745					break;
3746				default:
3747					break;
3748				}
3749				break;
3750			default:
3751				break;
3752			}
3753			break;
3754		case BYTES_TRANSFER_TEXT:
3755			FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy,
3756			                     sizeof(magic)) == 0);
3757			break;
3758		case BYTES_TRANSFER_TEXTIO:
3759			switch (size) {
3760			case 8:
3761				FORKEE_ASSERT(memcmp(&magic8,
3762				                     bytes_transfer_dummy,
3763				                     sizeof(magic8)) == 0);
3764				break;
3765			case 16:
3766				FORKEE_ASSERT(memcmp(&magic16,
3767				                     bytes_transfer_dummy,
3768				                     sizeof(magic16)) == 0);
3769				break;
3770			case 32:
3771				FORKEE_ASSERT(memcmp(&magic32,
3772				                     bytes_transfer_dummy,
3773				                     sizeof(magic32)) == 0);
3774				break;
3775			case 64:
3776				FORKEE_ASSERT(memcmp(&magic64,
3777				                     bytes_transfer_dummy,
3778				                     sizeof(magic64)) == 0);
3779				break;
3780			}
3781			break;
3782		default:
3783			break;
3784		}
3785
3786		DPRINTF("Before exiting of the child process\n");
3787		_exit(exitval);
3788	}
3789	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3790
3791	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3792	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3793
3794	validate_status_stopped(status, sigval);
3795
3796	/* Check PaX MPROTECT */
3797	if (!can_we_write_to_text(child)) {
3798		switch (type) {
3799		case BYTES_TRANSFER_TEXTIO:
3800			switch (operation) {
3801			case PIOD_WRITE_D:
3802			case PIOD_WRITE_I:
3803				skip = true;
3804				break;
3805			default:
3806				break;
3807			}
3808			break;
3809		case BYTES_TRANSFER_TEXT:
3810			switch (operation) {
3811			case PT_WRITE_D:
3812			case PT_WRITE_I:
3813				skip = true;
3814				break;
3815			default:
3816				break;
3817			}
3818			break;
3819		default:
3820			break;
3821		}
3822	}
3823
3824	/* Bailout cleanly killing the child process */
3825	if (skip) {
3826		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
3827		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3828		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3829		                      child);
3830
3831		validate_status_signaled(status, SIGKILL, 0);
3832
3833		atf_tc_skip("PaX MPROTECT setup prevents writes to .text");
3834	}
3835
3836	DPRINTF("Calling operation to transfer bytes between child=%d and "
3837	       "parent=%d\n", child, getpid());
3838
3839	switch (type) {
3840	case BYTES_TRANSFER_TEXTIO:
3841	case BYTES_TRANSFER_DATAIO:
3842	case BYTES_TRANSFER_AUXV:
3843		switch (operation) {
3844		case PIOD_WRITE_D:
3845		case PIOD_WRITE_I:
3846			switch (size) {
3847			case 8:
3848				lookup_me8 = magic8;
3849				break;
3850			case 16:
3851				lookup_me16 = magic16;
3852				break;
3853			case 32:
3854				lookup_me32 = magic32;
3855				break;
3856			case 64:
3857				lookup_me64 = magic64;
3858				break;
3859			default:
3860				break;
3861			}
3862			break;
3863		default:
3864			break;
3865		}
3866		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3867		switch (operation) {
3868		case PIOD_READ_D:
3869		case PIOD_READ_I:
3870			switch (size) {
3871			case 8:
3872				ATF_REQUIRE_EQ(lookup_me8, magic8);
3873				break;
3874			case 16:
3875				ATF_REQUIRE_EQ(lookup_me16, magic16);
3876				break;
3877			case 32:
3878				ATF_REQUIRE_EQ(lookup_me32, magic32);
3879				break;
3880			case 64:
3881				ATF_REQUIRE_EQ(lookup_me64, magic64);
3882				break;
3883			default:
3884				break;
3885			}
3886			break;
3887		case PIOD_READ_AUXV:
3888			DPRINTF("Asserting that AUXV length (%zu) is > 0\n",
3889			        io.piod_len);
3890			ATF_REQUIRE(io.piod_len > 0);
3891			for (aip = ai; aip->a_type != AT_NULL; aip++)
3892				DPRINTF("a_type=%#llx a_v=%#llx\n",
3893				    (long long int)aip->a_type,
3894				    (long long int)aip->a_v);
3895			break;
3896		default:
3897			break;
3898		}
3899		break;
3900	case BYTES_TRANSFER_TEXT:
3901		switch (operation) {
3902		case PT_READ_D:
3903		case PT_READ_I:
3904			errno = 0;
3905			lookup_me = ptrace(operation, child,
3906			                   bytes_transfer_dummy, 0);
3907			ATF_REQUIRE_EQ(lookup_me, magic);
3908			SYSCALL_REQUIRE_ERRNO(errno, 0);
3909			break;
3910		case PT_WRITE_D:
3911		case PT_WRITE_I:
3912			SYSCALL_REQUIRE(ptrace(operation, child,
3913			                       bytes_transfer_dummy, magic)
3914			                != -1);
3915			break;
3916		default:
3917			break;
3918		}
3919		break;
3920	case BYTES_TRANSFER_DATA:
3921		switch (operation) {
3922		case PT_READ_D:
3923		case PT_READ_I:
3924			errno = 0;
3925			lookup_me = ptrace(operation, child, &lookup_me, 0);
3926			ATF_REQUIRE_EQ(lookup_me, magic);
3927			SYSCALL_REQUIRE_ERRNO(errno, 0);
3928			break;
3929		case PT_WRITE_D:
3930		case PT_WRITE_I:
3931			lookup_me = magic;
3932			SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me,
3933			                       magic) != -1);
3934			break;
3935		default:
3936			break;
3937		}
3938		break;
3939	default:
3940		break;
3941	}
3942
3943	DPRINTF("Before resuming the child process where it left off and "
3944	    "without signal to be sent\n");
3945	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3946
3947	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3948	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3949
3950	validate_status_exited(status, exitval);
3951
3952	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3953	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3954}
3955
3956#define BYTES_TRANSFER(test, operation, size, type)			\
3957ATF_TC(test);								\
3958ATF_TC_HEAD(test, tc)							\
3959{									\
3960	atf_tc_set_md_var(tc, "descr",					\
3961	    "Verify bytes transfer operation" #operation " and size " #size \
3962	    " of type " #type);						\
3963}									\
3964									\
3965ATF_TC_BODY(test, tc)							\
3966{									\
3967									\
3968	bytes_transfer(operation, size, BYTES_TRANSFER_##type);		\
3969}
3970
3971// DATA
3972
3973BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO)
3974BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO)
3975BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO)
3976BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO)
3977
3978BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO)
3979BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO)
3980BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO)
3981BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO)
3982
3983BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO)
3984BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO)
3985BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO)
3986BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO)
3987
3988BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO)
3989BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO)
3990BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO)
3991BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO)
3992
3993BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA)
3994BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA)
3995BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA)
3996BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA)
3997
3998// TEXT
3999
4000BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO)
4001BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO)
4002BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO)
4003BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO)
4004
4005BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO)
4006BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO)
4007BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO)
4008BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO)
4009
4010BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO)
4011BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO)
4012BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO)
4013BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO)
4014
4015BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO)
4016BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO)
4017BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO)
4018BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO)
4019
4020BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT)
4021BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT)
4022BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT)
4023BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT)
4024
4025// AUXV
4026
4027BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV)
4028
4029/// ----------------------------------------------------------------------------
4030
4031static void
4032bytes_transfer_alignment(const char *operation)
4033{
4034	const int exitval = 5;
4035	const int sigval = SIGSTOP;
4036	pid_t child, wpid;
4037#if defined(TWAIT_HAVE_STATUS)
4038	int status;
4039#endif
4040	char *buffer;
4041	int vector;
4042	size_t len;
4043	size_t i;
4044	int op;
4045
4046	struct ptrace_io_desc io;
4047	struct ptrace_siginfo info;
4048
4049	memset(&io, 0, sizeof(io));
4050	memset(&info, 0, sizeof(info));
4051
4052	/* Testing misaligned byte transfer crossing page boundaries */
4053	len = sysconf(_SC_PAGESIZE) * 2;
4054	buffer = malloc(len);
4055	ATF_REQUIRE(buffer != NULL);
4056
4057	/* Initialize the buffer with random data */
4058	for (i = 0; i < len; i++)
4059		buffer[i] = i & 0xff;
4060
4061	DPRINTF("Before forking process PID=%d\n", getpid());
4062	SYSCALL_REQUIRE((child = fork()) != -1);
4063	if (child == 0) {
4064		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4065		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4066
4067		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4068		FORKEE_ASSERT(raise(sigval) == 0);
4069
4070		DPRINTF("Before exiting of the child process\n");
4071		_exit(exitval);
4072	}
4073	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4074
4075	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4076	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4077
4078	validate_status_stopped(status, sigval);
4079
4080	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4081	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
4082		!= -1);
4083
4084	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4085	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4086		"si_errno=%#x\n",
4087		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4088		info.psi_siginfo.si_errno);
4089
4090	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4091	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4092
4093	if (strcmp(operation, "PT_READ_I") == 0 ||
4094	    strcmp(operation, "PT_READ_D") == 0) {
4095		if (strcmp(operation, "PT_READ_I"))
4096			op = PT_READ_I;
4097		else
4098			op = PT_READ_D;
4099
4100		for (i = 0; i <= (len - sizeof(int)); i++) {
4101			errno = 0;
4102			vector = ptrace(op, child, buffer + i, 0);
4103			ATF_REQUIRE_EQ(errno, 0);
4104			ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
4105		}
4106	} else if (strcmp(operation, "PT_WRITE_I") == 0 ||
4107	           strcmp(operation, "PT_WRITE_D") == 0) {
4108		if (strcmp(operation, "PT_WRITE_I"))
4109			op = PT_WRITE_I;
4110		else
4111			op = PT_WRITE_D;
4112
4113		for (i = 0; i <= (len - sizeof(int)); i++) {
4114			memcpy(&vector, buffer + i, sizeof(int));
4115			SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector)
4116			    != -1);
4117		}
4118	} else if (strcmp(operation, "PIOD_READ_I") == 0 ||
4119	           strcmp(operation, "PIOD_READ_D") == 0) {
4120		if (strcmp(operation, "PIOD_READ_I"))
4121			op = PIOD_READ_I;
4122		else
4123			op = PIOD_READ_D;
4124
4125		io.piod_op = op;
4126		io.piod_addr = &vector;
4127		io.piod_len = sizeof(int);
4128
4129		for (i = 0; i <= (len - sizeof(int)); i++) {
4130			io.piod_offs = buffer + i;
4131
4132			SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
4133			                != -1);
4134			ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
4135		}
4136	} else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
4137	           strcmp(operation, "PIOD_WRITE_D") == 0) {
4138		if (strcmp(operation, "PIOD_WRITE_I"))
4139			op = PIOD_WRITE_I;
4140		else
4141			op = PIOD_WRITE_D;
4142
4143		io.piod_op = op;
4144		io.piod_addr = &vector;
4145		io.piod_len = sizeof(int);
4146
4147		for (i = 0; i <= (len - sizeof(int)); i++) {
4148			io.piod_offs = buffer + i;
4149
4150			SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
4151			                != -1);
4152		}
4153	} else if (strcmp(operation, "PIOD_READ_AUXV") == 0) {
4154		io.piod_op = PIOD_READ_AUXV;
4155		io.piod_addr = &vector;
4156		io.piod_len = sizeof(int);
4157
4158		errno = 0;
4159		i = 0;
4160		/* Read the whole AUXV vector, it has no clear length */
4161		while (io.piod_len > 0) {
4162			io.piod_offs = (void *)(intptr_t)i;
4163			SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
4164			                != -1 || (io.piod_len == 0 && i > 0));
4165			++i;
4166		}
4167	}
4168
4169	DPRINTF("Before resuming the child process where it left off "
4170	    "and without signal to be sent\n");
4171	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4172
4173	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4174	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4175	    child);
4176
4177	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4178	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4179}
4180
4181#define BYTES_TRANSFER_ALIGNMENT(test, operation)			\
4182ATF_TC(test);								\
4183ATF_TC_HEAD(test, tc)							\
4184{									\
4185	atf_tc_set_md_var(tc, "descr",					\
4186	    "Verify bytes transfer for potentially misaligned "		\
4187	    "operation " operation);					\
4188}									\
4189									\
4190ATF_TC_BODY(test, tc)							\
4191{									\
4192									\
4193	bytes_transfer_alignment(operation);				\
4194}
4195
4196BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I")
4197BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D")
4198BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I")
4199BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D")
4200
4201BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I")
4202BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D")
4203BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I")
4204BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D")
4205
4206BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV")
4207
4208/// ----------------------------------------------------------------------------
4209
4210static void
4211bytes_transfer_eof(const char *operation)
4212{
4213	const int exitval = 5;
4214	const int sigval = SIGSTOP;
4215	pid_t child, wpid;
4216#if defined(TWAIT_HAVE_STATUS)
4217	int status;
4218#endif
4219	FILE *fp;
4220	char *p;
4221	int vector;
4222	int op;
4223
4224	struct ptrace_io_desc io;
4225	struct ptrace_siginfo info;
4226
4227	memset(&io, 0, sizeof(io));
4228	memset(&info, 0, sizeof(info));
4229
4230	vector = 0;
4231
4232	fp = tmpfile();
4233	ATF_REQUIRE(fp != NULL);
4234
4235	p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0);
4236	ATF_REQUIRE(p != MAP_FAILED);
4237
4238	DPRINTF("Before forking process PID=%d\n", getpid());
4239	SYSCALL_REQUIRE((child = fork()) != -1);
4240	if (child == 0) {
4241		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4242		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4243
4244		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4245		FORKEE_ASSERT(raise(sigval) == 0);
4246
4247		DPRINTF("Before exiting of the child process\n");
4248		_exit(exitval);
4249	}
4250	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4251
4252	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4253	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4254
4255	validate_status_stopped(status, sigval);
4256
4257	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4258	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
4259		!= -1);
4260
4261	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4262	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4263		"si_errno=%#x\n",
4264		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4265		info.psi_siginfo.si_errno);
4266
4267	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4268	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4269
4270	if (strcmp(operation, "PT_READ_I") == 0 ||
4271	    strcmp(operation, "PT_READ_D") == 0) {
4272		if (strcmp(operation, "PT_READ_I"))
4273			op = PT_READ_I;
4274		else
4275			op = PT_READ_D;
4276
4277		errno = 0;
4278		SYSCALL_REQUIRE(ptrace(op, child, p, 0) == -1);
4279		ATF_REQUIRE_EQ(errno, EINVAL);
4280	} else if (strcmp(operation, "PT_WRITE_I") == 0 ||
4281	           strcmp(operation, "PT_WRITE_D") == 0) {
4282		if (strcmp(operation, "PT_WRITE_I"))
4283			op = PT_WRITE_I;
4284		else
4285			op = PT_WRITE_D;
4286
4287		errno = 0;
4288		SYSCALL_REQUIRE(ptrace(op, child, p, vector) == -1);
4289		ATF_REQUIRE_EQ(errno, EINVAL);
4290	} else if (strcmp(operation, "PIOD_READ_I") == 0 ||
4291	           strcmp(operation, "PIOD_READ_D") == 0) {
4292		if (strcmp(operation, "PIOD_READ_I"))
4293			op = PIOD_READ_I;
4294		else
4295			op = PIOD_READ_D;
4296
4297		io.piod_op = op;
4298		io.piod_addr = &vector;
4299		io.piod_len = sizeof(int);
4300		io.piod_offs = p;
4301
4302		errno = 0;
4303		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
4304		ATF_REQUIRE_EQ(errno, EINVAL);
4305	} else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
4306	           strcmp(operation, "PIOD_WRITE_D") == 0) {
4307		if (strcmp(operation, "PIOD_WRITE_I"))
4308			op = PIOD_WRITE_I;
4309		else
4310			op = PIOD_WRITE_D;
4311
4312		io.piod_op = op;
4313		io.piod_addr = &vector;
4314		io.piod_len = sizeof(int);
4315		io.piod_offs = p;
4316
4317		errno = 0;
4318		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
4319		ATF_REQUIRE_EQ(errno, EINVAL);
4320	}
4321
4322	DPRINTF("Before resuming the child process where it left off "
4323	    "and without signal to be sent\n");
4324	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4325
4326	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4327	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4328	    child);
4329
4330	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4331	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4332}
4333
4334#define BYTES_TRANSFER_EOF(test, operation)				\
4335ATF_TC(test);								\
4336ATF_TC_HEAD(test, tc)							\
4337{									\
4338	atf_tc_set_md_var(tc, "descr",					\
4339	    "Verify bytes EOF byte transfer for the " operation		\
4340	    " operation");						\
4341}									\
4342									\
4343ATF_TC_BODY(test, tc)							\
4344{									\
4345									\
4346	bytes_transfer_eof(operation);					\
4347}
4348
4349BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_i, "PT_READ_I")
4350BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_d, "PT_READ_D")
4351BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_i, "PT_WRITE_I")
4352BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_d, "PT_WRITE_D")
4353
4354BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_i, "PIOD_READ_I")
4355BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_d, "PIOD_READ_D")
4356BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_i, "PIOD_WRITE_I")
4357BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_d, "PIOD_WRITE_D")
4358
4359/// ----------------------------------------------------------------------------
4360
4361#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS)
4362static void
4363access_regs(const char *regset, const char *aux)
4364{
4365	const int exitval = 5;
4366	const int sigval = SIGSTOP;
4367	pid_t child, wpid;
4368#if defined(TWAIT_HAVE_STATUS)
4369	int status;
4370#endif
4371#if defined(HAVE_GPREGS)
4372	struct reg gpr;
4373	register_t rgstr;
4374#endif
4375#if defined(HAVE_FPREGS)
4376	struct fpreg fpr;
4377#endif
4378
4379#if !defined(HAVE_GPREGS)
4380	if (strcmp(regset, "regs") == 0)
4381		atf_tc_fail("Impossible test scenario!");
4382#endif
4383
4384#if !defined(HAVE_FPREGS)
4385	if (strcmp(regset, "fpregs") == 0)
4386		atf_tc_fail("Impossible test scenario!");
4387#endif
4388
4389	DPRINTF("Before forking process PID=%d\n", getpid());
4390	SYSCALL_REQUIRE((child = fork()) != -1);
4391	if (child == 0) {
4392		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4393		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4394
4395		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4396		FORKEE_ASSERT(raise(sigval) == 0);
4397
4398		DPRINTF("Before exiting of the child process\n");
4399		_exit(exitval);
4400	}
4401	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4402
4403	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4404	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4405
4406	validate_status_stopped(status, sigval);
4407
4408#if defined(HAVE_GPREGS)
4409	if (strcmp(regset, "regs") == 0) {
4410		DPRINTF("Call GETREGS for the child process\n");
4411		SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1);
4412
4413		if (strcmp(aux, "none") == 0) {
4414			DPRINTF("Retrieved registers\n");
4415		} else if (strcmp(aux, "pc") == 0) {
4416			rgstr = PTRACE_REG_PC(&gpr);
4417			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
4418		} else if (strcmp(aux, "set_pc") == 0) {
4419			rgstr = PTRACE_REG_PC(&gpr);
4420			PTRACE_REG_SET_PC(&gpr, rgstr);
4421		} else if (strcmp(aux, "sp") == 0) {
4422			rgstr = PTRACE_REG_SP(&gpr);
4423			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
4424		} else if (strcmp(aux, "intrv") == 0) {
4425			rgstr = PTRACE_REG_INTRV(&gpr);
4426			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
4427		} else if (strcmp(aux, "setregs") == 0) {
4428			DPRINTF("Call SETREGS for the child process\n");
4429			SYSCALL_REQUIRE(
4430			    ptrace(PT_GETREGS, child, &gpr, 0) != -1);
4431		}
4432	}
4433#endif
4434
4435#if defined(HAVE_FPREGS)
4436	if (strcmp(regset, "fpregs") == 0) {
4437		DPRINTF("Call GETFPREGS for the child process\n");
4438		SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1);
4439
4440		if (strcmp(aux, "getfpregs") == 0) {
4441			DPRINTF("Retrieved FP registers\n");
4442		} else if (strcmp(aux, "setfpregs") == 0) {
4443			DPRINTF("Call SETFPREGS for the child\n");
4444			SYSCALL_REQUIRE(
4445			    ptrace(PT_SETFPREGS, child, &fpr, 0) != -1);
4446		}
4447	}
4448#endif
4449
4450	DPRINTF("Before resuming the child process where it left off and "
4451	    "without signal to be sent\n");
4452	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4453
4454	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4455	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4456
4457	validate_status_exited(status, exitval);
4458
4459	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4460	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4461}
4462
4463#define ACCESS_REGS(test, regset, aux)					\
4464ATF_TC(test);								\
4465ATF_TC_HEAD(test, tc)							\
4466{									\
4467        atf_tc_set_md_var(tc, "descr",					\
4468            "Verify " regset " with auxiliary operation: " aux);	\
4469}									\
4470									\
4471ATF_TC_BODY(test, tc)							\
4472{									\
4473									\
4474        access_regs(regset, aux);					\
4475}
4476#endif
4477
4478#if defined(HAVE_GPREGS)
4479ACCESS_REGS(access_regs1, "regs", "none")
4480ACCESS_REGS(access_regs2, "regs", "pc")
4481ACCESS_REGS(access_regs3, "regs", "set_pc")
4482ACCESS_REGS(access_regs4, "regs", "sp")
4483ACCESS_REGS(access_regs5, "regs", "intrv")
4484ACCESS_REGS(access_regs6, "regs", "setregs")
4485#endif
4486#if defined(HAVE_FPREGS)
4487ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs")
4488ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs")
4489#endif
4490
4491/// ----------------------------------------------------------------------------
4492
4493#if defined(PT_STEP)
4494static void
4495ptrace_step(int N, int setstep, bool masked, bool ignored)
4496{
4497	const int exitval = 5;
4498	const int sigval = SIGSTOP;
4499	pid_t child, wpid;
4500#if defined(TWAIT_HAVE_STATUS)
4501	int status;
4502#endif
4503	int happy;
4504	struct sigaction sa;
4505	struct ptrace_siginfo info;
4506	sigset_t intmask;
4507	struct kinfo_proc2 kp;
4508	size_t len = sizeof(kp);
4509
4510	int name[6];
4511	const size_t namelen = __arraycount(name);
4512	ki_sigset_t kp_sigmask;
4513	ki_sigset_t kp_sigignore;
4514
4515#if defined(__arm__)
4516	/* PT_STEP not supported on arm 32-bit */
4517	atf_tc_expect_fail("PR kern/52119");
4518#endif
4519
4520	DPRINTF("Before forking process PID=%d\n", getpid());
4521	SYSCALL_REQUIRE((child = fork()) != -1);
4522	if (child == 0) {
4523		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4524		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4525
4526		if (masked) {
4527			sigemptyset(&intmask);
4528			sigaddset(&intmask, SIGTRAP);
4529			sigprocmask(SIG_BLOCK, &intmask, NULL);
4530		}
4531
4532		if (ignored) {
4533			memset(&sa, 0, sizeof(sa));
4534			sa.sa_handler = SIG_IGN;
4535			sigemptyset(&sa.sa_mask);
4536			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
4537		}
4538
4539		happy = check_happy(999);
4540
4541		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4542		FORKEE_ASSERT(raise(sigval) == 0);
4543
4544		FORKEE_ASSERT_EQ(happy, check_happy(999));
4545
4546		DPRINTF("Before exiting of the child process\n");
4547		_exit(exitval);
4548	}
4549	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4550
4551	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4552	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4553
4554	validate_status_stopped(status, sigval);
4555
4556	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4557	SYSCALL_REQUIRE(
4558	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4559
4560	DPRINTF("Before checking siginfo_t\n");
4561	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4562	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4563
4564	name[0] = CTL_KERN,
4565	name[1] = KERN_PROC2,
4566	name[2] = KERN_PROC_PID;
4567	name[3] = child;
4568	name[4] = sizeof(kp);
4569	name[5] = 1;
4570
4571	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
4572
4573	if (masked)
4574		kp_sigmask = kp.p_sigmask;
4575
4576	if (ignored)
4577		kp_sigignore = kp.p_sigignore;
4578
4579	while (N --> 0) {
4580		if (setstep) {
4581			DPRINTF("Before resuming the child process where it "
4582			    "left off and without signal to be sent (use "
4583			    "PT_SETSTEP and PT_CONTINUE)\n");
4584			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
4585			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
4586			    != -1);
4587		} else {
4588			DPRINTF("Before resuming the child process where it "
4589			    "left off and without signal to be sent (use "
4590			    "PT_STEP)\n");
4591			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
4592			    != -1);
4593		}
4594
4595		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4596		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4597		    child);
4598
4599		validate_status_stopped(status, SIGTRAP);
4600
4601		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4602		SYSCALL_REQUIRE(
4603		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4604
4605		DPRINTF("Before checking siginfo_t\n");
4606		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4607		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
4608
4609		if (setstep) {
4610			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
4611		}
4612
4613		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
4614
4615		if (masked) {
4616			DPRINTF("kp_sigmask="
4617			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
4618			    PRIx32 "\n",
4619			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
4620			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
4621
4622			DPRINTF("kp.p_sigmask="
4623			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
4624			    PRIx32 "\n",
4625			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
4626			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
4627
4628			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
4629			    sizeof(kp_sigmask)));
4630		}
4631
4632		if (ignored) {
4633			DPRINTF("kp_sigignore="
4634			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
4635			    PRIx32 "\n",
4636			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
4637			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
4638
4639			DPRINTF("kp.p_sigignore="
4640			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
4641			    PRIx32 "\n",
4642			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
4643			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
4644
4645			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
4646			    sizeof(kp_sigignore)));
4647		}
4648	}
4649
4650	DPRINTF("Before resuming the child process where it left off and "
4651	    "without signal to be sent\n");
4652	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4653
4654	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4655	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4656
4657	validate_status_exited(status, exitval);
4658
4659	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4660	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4661}
4662
4663#define PTRACE_STEP(test, N, setstep)					\
4664ATF_TC(test);								\
4665ATF_TC_HEAD(test, tc)							\
4666{									\
4667        atf_tc_set_md_var(tc, "descr",					\
4668            "Verify " #N " (PT_SETSTEP set to: " #setstep ")");		\
4669}									\
4670									\
4671ATF_TC_BODY(test, tc)							\
4672{									\
4673									\
4674        ptrace_step(N, setstep, false, false);				\
4675}
4676
4677PTRACE_STEP(step1, 1, 0)
4678PTRACE_STEP(step2, 2, 0)
4679PTRACE_STEP(step3, 3, 0)
4680PTRACE_STEP(step4, 4, 0)
4681PTRACE_STEP(setstep1, 1, 1)
4682PTRACE_STEP(setstep2, 2, 1)
4683PTRACE_STEP(setstep3, 3, 1)
4684PTRACE_STEP(setstep4, 4, 1)
4685
4686ATF_TC(step_signalmasked);
4687ATF_TC_HEAD(step_signalmasked, tc)
4688{
4689	atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with masked SIGTRAP");
4690}
4691
4692ATF_TC_BODY(step_signalmasked, tc)
4693{
4694
4695	ptrace_step(1, 0, true, false);
4696}
4697
4698ATF_TC(step_signalignored);
4699ATF_TC_HEAD(step_signalignored, tc)
4700{
4701	atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with ignored SIGTRAP");
4702}
4703
4704ATF_TC_BODY(step_signalignored, tc)
4705{
4706
4707	ptrace_step(1, 0, false, true);
4708}
4709#endif
4710
4711/// ----------------------------------------------------------------------------
4712
4713static void
4714ptrace_kill(const char *type)
4715{
4716	const int sigval = SIGSTOP;
4717	pid_t child, wpid;
4718#if defined(TWAIT_HAVE_STATUS)
4719	int status;
4720#endif
4721
4722	DPRINTF("Before forking process PID=%d\n", getpid());
4723	SYSCALL_REQUIRE((child = fork()) != -1);
4724	if (child == 0) {
4725		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4726		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4727
4728		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4729		FORKEE_ASSERT(raise(sigval) == 0);
4730
4731		/* NOTREACHED */
4732		FORKEE_ASSERTX(0 &&
4733		    "Child should be terminated by a signal from its parent");
4734	}
4735	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4736
4737	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4738	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4739
4740	validate_status_stopped(status, sigval);
4741
4742	DPRINTF("Before killing the child process with %s\n", type);
4743	if (strcmp(type, "ptrace(PT_KILL)") == 0) {
4744		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
4745	} else if (strcmp(type, "kill(SIGKILL)") == 0) {
4746		kill(child, SIGKILL);
4747	} else if (strcmp(type, "killpg(SIGKILL)") == 0) {
4748		setpgid(child, 0);
4749		killpg(getpgid(child), SIGKILL);
4750	}
4751
4752	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4753	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4754
4755	validate_status_signaled(status, SIGKILL, 0);
4756
4757	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4758	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4759}
4760
4761#define PTRACE_KILL(test, type)						\
4762ATF_TC(test);								\
4763ATF_TC_HEAD(test, tc)							\
4764{									\
4765        atf_tc_set_md_var(tc, "descr",					\
4766            "Verify killing the child with " type);			\
4767}									\
4768									\
4769ATF_TC_BODY(test, tc)							\
4770{									\
4771									\
4772        ptrace_kill(type);						\
4773}
4774
4775// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1
4776PTRACE_KILL(kill1, "ptrace(PT_KILL)")
4777PTRACE_KILL(kill2, "kill(SIGKILL)")
4778PTRACE_KILL(kill3, "killpg(SIGKILL)")
4779
4780/// ----------------------------------------------------------------------------
4781
4782static void
4783traceme_lwpinfo(const int threads)
4784{
4785	const int sigval = SIGSTOP;
4786	const int sigval2 = SIGINT;
4787	pid_t child, wpid;
4788#if defined(TWAIT_HAVE_STATUS)
4789	int status;
4790#endif
4791	struct ptrace_lwpinfo lwp = {0, 0};
4792	struct ptrace_siginfo info;
4793
4794	/* Maximum number of supported threads in this test */
4795	pthread_t t[3];
4796	int n, rv;
4797
4798	ATF_REQUIRE((int)__arraycount(t) >= threads);
4799
4800	DPRINTF("Before forking process PID=%d\n", getpid());
4801	SYSCALL_REQUIRE((child = fork()) != -1);
4802	if (child == 0) {
4803		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4804		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4805
4806		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4807		FORKEE_ASSERT(raise(sigval) == 0);
4808
4809		for (n = 0; n < threads; n++) {
4810			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
4811			FORKEE_ASSERT(rv == 0);
4812		}
4813
4814		DPRINTF("Before raising %s from child\n", strsignal(sigval2));
4815		FORKEE_ASSERT(raise(sigval2) == 0);
4816
4817		/* NOTREACHED */
4818		FORKEE_ASSERTX(0 && "Not reached");
4819	}
4820	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4821
4822	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4823	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4824
4825	validate_status_stopped(status, sigval);
4826
4827	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
4828	SYSCALL_REQUIRE(
4829	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4830
4831	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4832	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4833	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4834	    info.psi_siginfo.si_errno);
4835
4836	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4837	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4838
4839	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4840	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4841
4842	DPRINTF("Assert that there exists a single thread only\n");
4843	ATF_REQUIRE(lwp.pl_lwpid > 0);
4844
4845	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
4846	    lwp.pl_lwpid);
4847	FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
4848
4849	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4850	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4851
4852	DPRINTF("Assert that there exists a single thread only\n");
4853	ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
4854
4855	DPRINTF("Before resuming the child process where it left off and "
4856	    "without signal to be sent\n");
4857	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4858
4859	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4860	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4861
4862	validate_status_stopped(status, sigval2);
4863
4864	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
4865	SYSCALL_REQUIRE(
4866	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4867
4868	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4869	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4870	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4871	    info.psi_siginfo.si_errno);
4872
4873	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
4874	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4875
4876	memset(&lwp, 0, sizeof(lwp));
4877
4878	for (n = 0; n <= threads; n++) {
4879		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4880		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4881		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4882
4883		DPRINTF("Assert that the thread exists\n");
4884		ATF_REQUIRE(lwp.pl_lwpid > 0);
4885
4886		DPRINTF("Assert that lwp thread %d received expected event\n",
4887		    lwp.pl_lwpid);
4888		FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ?
4889		    PL_EVENT_SIGNAL : PL_EVENT_NONE);
4890	}
4891	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4892	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4893	DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4894
4895	DPRINTF("Assert that there are no more threads\n");
4896	ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
4897
4898	DPRINTF("Before resuming the child process where it left off and "
4899	    "without signal to be sent\n");
4900	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1);
4901
4902	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4903	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4904
4905	validate_status_signaled(status, SIGKILL, 0);
4906
4907	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4908	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4909}
4910
4911#define TRACEME_LWPINFO(test, threads)					\
4912ATF_TC(test);								\
4913ATF_TC_HEAD(test, tc)							\
4914{									\
4915	atf_tc_set_md_var(tc, "descr",					\
4916	    "Verify LWPINFO with the child with " #threads		\
4917	    " spawned extra threads");					\
4918}									\
4919									\
4920ATF_TC_BODY(test, tc)							\
4921{									\
4922									\
4923	traceme_lwpinfo(threads);					\
4924}
4925
4926TRACEME_LWPINFO(traceme_lwpinfo0, 0)
4927TRACEME_LWPINFO(traceme_lwpinfo1, 1)
4928TRACEME_LWPINFO(traceme_lwpinfo2, 2)
4929TRACEME_LWPINFO(traceme_lwpinfo3, 3)
4930
4931/// ----------------------------------------------------------------------------
4932
4933#if defined(TWAIT_HAVE_PID)
4934static void
4935attach_lwpinfo(const int threads)
4936{
4937	const int sigval = SIGINT;
4938	struct msg_fds parent_tracee, parent_tracer;
4939	const int exitval_tracer = 10;
4940	pid_t tracee, tracer, wpid;
4941	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4942#if defined(TWAIT_HAVE_STATUS)
4943	int status;
4944#endif
4945	struct ptrace_lwpinfo lwp = {0, 0};
4946	struct ptrace_siginfo info;
4947
4948	/* Maximum number of supported threads in this test */
4949	pthread_t t[3];
4950	int n, rv;
4951
4952	DPRINTF("Spawn tracee\n");
4953	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4954	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4955	tracee = atf_utils_fork();
4956	if (tracee == 0) {
4957		/* Wait for message from the parent */
4958		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
4959
4960		CHILD_FROM_PARENT("spawn threads", parent_tracee, msg);
4961
4962		for (n = 0; n < threads; n++) {
4963			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
4964			FORKEE_ASSERT(rv == 0);
4965		}
4966
4967		CHILD_TO_PARENT("tracee exit", parent_tracee, msg);
4968
4969		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4970		FORKEE_ASSERT(raise(sigval) == 0);
4971
4972		/* NOTREACHED */
4973		FORKEE_ASSERTX(0 && "Not reached");
4974	}
4975	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
4976
4977	DPRINTF("Spawn debugger\n");
4978	tracer = atf_utils_fork();
4979	if (tracer == 0) {
4980		/* No IPC to communicate with the child */
4981		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4982		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4983
4984		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4985		FORKEE_REQUIRE_SUCCESS(
4986		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4987
4988		forkee_status_stopped(status, SIGSTOP);
4989
4990		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4991		    "tracee");
4992		FORKEE_ASSERT(
4993		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
4994
4995		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4996		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4997		    "si_errno=%#x\n",
4998		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4999		    info.psi_siginfo.si_errno);
5000
5001		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
5002		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
5003
5004		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
5005		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5006		    != -1);
5007
5008		DPRINTF("Assert that there exists a thread\n");
5009		FORKEE_ASSERTX(lwp.pl_lwpid > 0);
5010
5011		DPRINTF("Assert that lwp thread %d received event "
5012		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
5013		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
5014
5015		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5016		    "tracee\n");
5017		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5018		    != -1);
5019
5020		DPRINTF("Assert that there are no more lwp threads in "
5021		    "tracee\n");
5022		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
5023
5024		/* Resume tracee with PT_CONTINUE */
5025		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5026
5027		/* Inform parent that tracer has attached to tracee */
5028		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
5029
5030		/* Wait for parent */
5031		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
5032
5033		/* Wait for tracee and assert that it raised a signal */
5034		FORKEE_REQUIRE_SUCCESS(
5035		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5036
5037		forkee_status_stopped(status, SIGINT);
5038
5039		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5040		    "child");
5041		FORKEE_ASSERT(
5042		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
5043
5044		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5045		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5046		    "si_errno=%#x\n",
5047		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5048		    info.psi_siginfo.si_errno);
5049
5050		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
5051		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
5052
5053		memset(&lwp, 0, sizeof(lwp));
5054
5055		for (n = 0; n <= threads; n++) {
5056			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5057			    "child\n");
5058			FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp,
5059			    sizeof(lwp)) != -1);
5060			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5061
5062			DPRINTF("Assert that the thread exists\n");
5063			FORKEE_ASSERT(lwp.pl_lwpid > 0);
5064
5065			DPRINTF("Assert that lwp thread %d received expected "
5066			    "event\n", lwp.pl_lwpid);
5067			FORKEE_ASSERT_EQ(lwp.pl_event,
5068			    info.psi_lwpid == lwp.pl_lwpid ?
5069			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
5070		}
5071		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5072		    "tracee\n");
5073		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5074		    != -1);
5075		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5076
5077		DPRINTF("Assert that there are no more threads\n");
5078		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
5079
5080		DPRINTF("Before resuming the child process where it left off "
5081		    "and without signal to be sent\n");
5082		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL)
5083		    != -1);
5084
5085		/* Wait for tracee and assert that it exited */
5086		FORKEE_REQUIRE_SUCCESS(
5087		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5088
5089		forkee_status_signaled(status, SIGKILL, 0);
5090
5091		DPRINTF("Before exiting of the tracer process\n");
5092		_exit(exitval_tracer);
5093	}
5094
5095	DPRINTF("Wait for the tracer to attach to the tracee\n");
5096	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
5097
5098	DPRINTF("Resume the tracee and spawn threads\n");
5099	PARENT_TO_CHILD("spawn threads", parent_tracee, msg);
5100
5101	DPRINTF("Resume the tracee and let it exit\n");
5102	PARENT_FROM_CHILD("tracee exit", parent_tracee, msg);
5103
5104	DPRINTF("Resume the tracer and let it detect multiple threads\n");
5105	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
5106
5107	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
5108	    TWAIT_FNAME);
5109	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
5110	    tracer);
5111
5112	validate_status_exited(status, exitval_tracer);
5113
5114	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5115	    TWAIT_FNAME);
5116	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
5117	    tracee);
5118
5119	validate_status_signaled(status, SIGKILL, 0);
5120
5121	msg_close(&parent_tracer);
5122	msg_close(&parent_tracee);
5123}
5124
5125#define ATTACH_LWPINFO(test, threads)					\
5126ATF_TC(test);								\
5127ATF_TC_HEAD(test, tc)							\
5128{									\
5129	atf_tc_set_md_var(tc, "descr",					\
5130	    "Verify LWPINFO with the child with " #threads		\
5131	    " spawned extra threads (tracer is not the original "	\
5132	    "parent)");							\
5133}									\
5134									\
5135ATF_TC_BODY(test, tc)							\
5136{									\
5137									\
5138	attach_lwpinfo(threads);					\
5139}
5140
5141ATTACH_LWPINFO(attach_lwpinfo0, 0)
5142ATTACH_LWPINFO(attach_lwpinfo1, 1)
5143ATTACH_LWPINFO(attach_lwpinfo2, 2)
5144ATTACH_LWPINFO(attach_lwpinfo3, 3)
5145#endif
5146
5147/// ----------------------------------------------------------------------------
5148
5149static void
5150ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
5151{
5152	const int exitval = 5;
5153	const int sigval = SIGINT;
5154	const int sigfaked = SIGTRAP;
5155	const int sicodefaked = TRAP_BRKPT;
5156	pid_t child, wpid;
5157	struct sigaction sa;
5158#if defined(TWAIT_HAVE_STATUS)
5159	int status;
5160#endif
5161	struct ptrace_siginfo info;
5162	memset(&info, 0, sizeof(info));
5163
5164	DPRINTF("Before forking process PID=%d\n", getpid());
5165	SYSCALL_REQUIRE((child = fork()) != -1);
5166	if (child == 0) {
5167		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5168		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5169
5170		sa.sa_sigaction = sah;
5171		sa.sa_flags = SA_SIGINFO;
5172		sigemptyset(&sa.sa_mask);
5173
5174		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
5175		    != -1);
5176
5177		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5178		FORKEE_ASSERT(raise(sigval) == 0);
5179
5180		FORKEE_ASSERT_EQ(*signal_caught, 1);
5181
5182		DPRINTF("Before exiting of the child process\n");
5183		_exit(exitval);
5184	}
5185	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5186
5187	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5188	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5189
5190	validate_status_stopped(status, sigval);
5191
5192	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5193	SYSCALL_REQUIRE(
5194	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5195
5196	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5197	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5198	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5199	    info.psi_siginfo.si_errno);
5200
5201	if (faked) {
5202		DPRINTF("Before setting new faked signal to signo=%d "
5203		    "si_code=%d\n", sigfaked, sicodefaked);
5204		info.psi_siginfo.si_signo = sigfaked;
5205		info.psi_siginfo.si_code = sicodefaked;
5206	}
5207
5208	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
5209	SYSCALL_REQUIRE(
5210	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
5211
5212	if (faked) {
5213		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5214		    "child\n");
5215		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
5216		    sizeof(info)) != -1);
5217
5218		DPRINTF("Before checking siginfo_t\n");
5219		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
5220		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
5221	}
5222
5223	DPRINTF("Before resuming the child process where it left off and "
5224	    "without signal to be sent\n");
5225	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
5226	    faked ? sigfaked : sigval) != -1);
5227
5228	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5229	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5230
5231	validate_status_exited(status, exitval);
5232
5233	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5234	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5235}
5236
5237#define PTRACE_SIGINFO(test, faked)					\
5238ATF_TC(test);								\
5239ATF_TC_HEAD(test, tc)							\
5240{									\
5241	atf_tc_set_md_var(tc, "descr",					\
5242	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
5243	    "with%s setting signal to new value", faked ? "" : "out");	\
5244}									\
5245									\
5246static int test##_caught = 0;						\
5247									\
5248static void								\
5249test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
5250{									\
5251	if (faked) {							\
5252		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
5253		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
5254		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
5255	} else {							\
5256		FORKEE_ASSERT_EQ(sig, SIGINT);				\
5257		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
5258		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
5259	}								\
5260									\
5261	++ test##_caught;						\
5262}									\
5263									\
5264ATF_TC_BODY(test, tc)							\
5265{									\
5266									\
5267	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
5268}
5269
5270PTRACE_SIGINFO(siginfo_set_unmodified, false)
5271PTRACE_SIGINFO(siginfo_set_faked, true)
5272
5273/// ----------------------------------------------------------------------------
5274
5275static void
5276traceme_exec(bool masked, bool ignored)
5277{
5278	const int sigval = SIGTRAP;
5279	pid_t child, wpid;
5280#if defined(TWAIT_HAVE_STATUS)
5281	int status;
5282#endif
5283	struct sigaction sa;
5284	struct ptrace_siginfo info;
5285	sigset_t intmask;
5286	struct kinfo_proc2 kp;
5287	size_t len = sizeof(kp);
5288
5289	int name[6];
5290	const size_t namelen = __arraycount(name);
5291	ki_sigset_t kp_sigmask;
5292	ki_sigset_t kp_sigignore;
5293
5294	memset(&info, 0, sizeof(info));
5295
5296	DPRINTF("Before forking process PID=%d\n", getpid());
5297	SYSCALL_REQUIRE((child = fork()) != -1);
5298	if (child == 0) {
5299		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5300		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5301
5302		if (masked) {
5303			sigemptyset(&intmask);
5304			sigaddset(&intmask, sigval);
5305			sigprocmask(SIG_BLOCK, &intmask, NULL);
5306		}
5307
5308		if (ignored) {
5309			memset(&sa, 0, sizeof(sa));
5310			sa.sa_handler = SIG_IGN;
5311			sigemptyset(&sa.sa_mask);
5312			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
5313		}
5314
5315		DPRINTF("Before calling execve(2) from child\n");
5316		execlp("/bin/echo", "/bin/echo", NULL);
5317
5318		FORKEE_ASSERT(0 && "Not reached");
5319	}
5320	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5321
5322	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5323	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5324
5325	validate_status_stopped(status, sigval);
5326
5327	name[0] = CTL_KERN,
5328	name[1] = KERN_PROC2,
5329	name[2] = KERN_PROC_PID;
5330	name[3] = getpid();
5331	name[4] = sizeof(kp);
5332	name[5] = 1;
5333
5334	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5335
5336	if (masked)
5337		kp_sigmask = kp.p_sigmask;
5338
5339	if (ignored)
5340		kp_sigignore = kp.p_sigignore;
5341
5342	name[3] = getpid();
5343
5344	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5345
5346	if (masked) {
5347		DPRINTF("kp_sigmask="
5348		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5349		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
5350		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
5351
5352		DPRINTF("kp.p_sigmask="
5353		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5354		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
5355		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
5356
5357		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
5358		    sizeof(kp_sigmask)));
5359	}
5360
5361	if (ignored) {
5362		DPRINTF("kp_sigignore="
5363		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5364		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
5365		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
5366
5367		DPRINTF("kp.p_sigignore="
5368		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5369		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
5370		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
5371
5372		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
5373		    sizeof(kp_sigignore)));
5374	}
5375
5376	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5377	SYSCALL_REQUIRE(
5378	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5379
5380	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5381	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5382	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5383	    info.psi_siginfo.si_errno);
5384
5385	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5386	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
5387
5388	DPRINTF("Before resuming the child process where it left off and "
5389	    "without signal to be sent\n");
5390	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5391
5392	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5393	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5394
5395	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5396	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5397}
5398
5399#define TRACEME_EXEC(test, masked, ignored)				\
5400ATF_TC(test);								\
5401ATF_TC_HEAD(test, tc)							\
5402{									\
5403       atf_tc_set_md_var(tc, "descr",					\
5404           "Detect SIGTRAP TRAP_EXEC from "				\
5405           "child%s%s", masked ? " with masked signal" : "",		\
5406           masked ? " with ignored signal" : "");			\
5407}									\
5408									\
5409ATF_TC_BODY(test, tc)							\
5410{									\
5411									\
5412       traceme_exec(masked, ignored);					\
5413}
5414
5415TRACEME_EXEC(traceme_exec, false, false)
5416TRACEME_EXEC(traceme_signalmasked_exec, true, false)
5417TRACEME_EXEC(traceme_signalignored_exec, false, true)
5418
5419/// ----------------------------------------------------------------------------
5420
5421static volatile int done;
5422
5423static void *
5424trace_threads_cb(void *arg __unused)
5425{
5426
5427	done++;
5428
5429	while (done < 3)
5430		continue;
5431
5432	return NULL;
5433}
5434
5435static void
5436trace_threads(bool trace_create, bool trace_exit)
5437{
5438	const int sigval = SIGSTOP;
5439	pid_t child, wpid;
5440#if defined(TWAIT_HAVE_STATUS)
5441	int status;
5442#endif
5443	ptrace_state_t state;
5444	const int slen = sizeof(state);
5445	ptrace_event_t event;
5446	const int elen = sizeof(event);
5447	struct ptrace_siginfo info;
5448
5449	pthread_t t[3];
5450	int rv;
5451	size_t n;
5452	lwpid_t lid;
5453
5454	/* Track created and exited threads */
5455	bool traced_lwps[__arraycount(t)];
5456
5457	if (trace_create || trace_exit)
5458		atf_tc_skip("PR kern/51995");
5459
5460	DPRINTF("Before forking process PID=%d\n", getpid());
5461	SYSCALL_REQUIRE((child = fork()) != -1);
5462	if (child == 0) {
5463		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5464		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5465
5466		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5467		FORKEE_ASSERT(raise(sigval) == 0);
5468
5469		for (n = 0; n < __arraycount(t); n++) {
5470			rv = pthread_create(&t[n], NULL, trace_threads_cb,
5471			    NULL);
5472			FORKEE_ASSERT(rv == 0);
5473		}
5474
5475		for (n = 0; n < __arraycount(t); n++) {
5476			rv = pthread_join(t[n], NULL);
5477			FORKEE_ASSERT(rv == 0);
5478		}
5479
5480		/*
5481		 * There is race between _exit() and pthread_join() detaching
5482		 * a thread. For simplicity kill the process after detecting
5483		 * LWP events.
5484		 */
5485		while (true)
5486			continue;
5487
5488		FORKEE_ASSERT(0 && "Not reached");
5489	}
5490	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5491
5492	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5493	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5494
5495	validate_status_stopped(status, sigval);
5496
5497	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5498	SYSCALL_REQUIRE(
5499	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5500
5501	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5502	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5503	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5504	    info.psi_siginfo.si_errno);
5505
5506	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5507	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5508
5509	DPRINTF("Set LWP event mask for the child %d\n", child);
5510	memset(&event, 0, sizeof(event));
5511	if (trace_create)
5512		event.pe_set_event |= PTRACE_LWP_CREATE;
5513	if (trace_exit)
5514		event.pe_set_event |= PTRACE_LWP_EXIT;
5515	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5516
5517	DPRINTF("Before resuming the child process where it left off and "
5518	    "without signal to be sent\n");
5519	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5520
5521	memset(traced_lwps, 0, sizeof(traced_lwps));
5522
5523	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
5524		DPRINTF("Before calling %s() for the child - expected stopped "
5525		    "SIGTRAP\n", TWAIT_FNAME);
5526		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
5527		    child);
5528
5529		validate_status_stopped(status, SIGTRAP);
5530
5531		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5532		    "child\n");
5533		SYSCALL_REQUIRE(
5534		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5535
5536		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5537		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5538		    "si_errno=%#x\n",
5539		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5540		    info.psi_siginfo.si_errno);
5541
5542		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5543		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
5544
5545		SYSCALL_REQUIRE(
5546		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5547
5548		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
5549		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
5550
5551		lid = state.pe_lwp;
5552		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
5553
5554		traced_lwps[lid - 1] = true;
5555
5556		DPRINTF("Before resuming the child process where it left off "
5557		    "and without signal to be sent\n");
5558		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5559	}
5560
5561	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
5562		DPRINTF("Before calling %s() for the child - expected stopped "
5563		    "SIGTRAP\n", TWAIT_FNAME);
5564		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
5565		    child);
5566
5567		validate_status_stopped(status, SIGTRAP);
5568
5569		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5570		    "child\n");
5571		SYSCALL_REQUIRE(
5572		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5573
5574		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5575		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5576		    "si_errno=%#x\n",
5577		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5578		    info.psi_siginfo.si_errno);
5579
5580		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5581		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
5582
5583		SYSCALL_REQUIRE(
5584		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5585
5586		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
5587		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
5588
5589		lid = state.pe_lwp;
5590		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
5591
5592		if (trace_create) {
5593			ATF_REQUIRE(traced_lwps[lid - 1] == true);
5594			traced_lwps[lid - 1] = false;
5595		}
5596
5597		DPRINTF("Before resuming the child process where it left off "
5598		    "and without signal to be sent\n");
5599		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5600	}
5601
5602	kill(child, SIGKILL);
5603
5604	DPRINTF("Before calling %s() for the child - expected exited\n",
5605	    TWAIT_FNAME);
5606	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5607
5608	validate_status_signaled(status, SIGKILL, 0);
5609
5610	DPRINTF("Before calling %s() for the child - expected no process\n",
5611	    TWAIT_FNAME);
5612	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5613}
5614
5615#define TRACE_THREADS(test, trace_create, trace_exit)			\
5616ATF_TC(test);								\
5617ATF_TC_HEAD(test, tc)							\
5618{									\
5619        atf_tc_set_md_var(tc, "descr",					\
5620            "Verify spawning threads with%s tracing LWP create and"	\
5621	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
5622	    trace_exit ? "" : "out");					\
5623}									\
5624									\
5625ATF_TC_BODY(test, tc)							\
5626{									\
5627									\
5628        trace_threads(trace_create, trace_exit);			\
5629}
5630
5631TRACE_THREADS(trace_thread_nolwpevents, false, false)
5632TRACE_THREADS(trace_thread_lwpexit, false, true)
5633TRACE_THREADS(trace_thread_lwpcreate, true, false)
5634TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true)
5635
5636/// ----------------------------------------------------------------------------
5637
5638ATF_TC(signal_mask_unrelated);
5639ATF_TC_HEAD(signal_mask_unrelated, tc)
5640{
5641	atf_tc_set_md_var(tc, "descr",
5642	    "Verify that masking single unrelated signal does not stop tracer "
5643	    "from catching other signals");
5644}
5645
5646ATF_TC_BODY(signal_mask_unrelated, tc)
5647{
5648	const int exitval = 5;
5649	const int sigval = SIGSTOP;
5650	const int sigmasked = SIGTRAP;
5651	const int signotmasked = SIGINT;
5652	pid_t child, wpid;
5653#if defined(TWAIT_HAVE_STATUS)
5654	int status;
5655#endif
5656	sigset_t intmask;
5657
5658	DPRINTF("Before forking process PID=%d\n", getpid());
5659	SYSCALL_REQUIRE((child = fork()) != -1);
5660	if (child == 0) {
5661		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5662		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5663
5664		sigemptyset(&intmask);
5665		sigaddset(&intmask, sigmasked);
5666		sigprocmask(SIG_BLOCK, &intmask, NULL);
5667
5668		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5669		FORKEE_ASSERT(raise(sigval) == 0);
5670
5671		DPRINTF("Before raising %s from child\n",
5672		    strsignal(signotmasked));
5673		FORKEE_ASSERT(raise(signotmasked) == 0);
5674
5675		DPRINTF("Before exiting of the child process\n");
5676		_exit(exitval);
5677	}
5678	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5679
5680	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5681	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5682
5683	validate_status_stopped(status, sigval);
5684
5685	DPRINTF("Before resuming the child process where it left off and "
5686	    "without signal to be sent\n");
5687	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5688
5689	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5690	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5691
5692	validate_status_stopped(status, signotmasked);
5693
5694	DPRINTF("Before resuming the child process where it left off and "
5695	    "without signal to be sent\n");
5696	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5697
5698	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5699	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5700
5701	validate_status_exited(status, exitval);
5702
5703	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5704	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5705}
5706
5707/// ----------------------------------------------------------------------------
5708
5709#if defined(TWAIT_HAVE_PID)
5710static void
5711fork2_body(const char *fn, bool masked, bool ignored)
5712{
5713	const int exitval = 5;
5714	const int exitval2 = 0; /* Match exit status from /bin/echo */
5715	const int sigval = SIGSTOP;
5716	pid_t child, child2 = 0, wpid;
5717#if defined(TWAIT_HAVE_STATUS)
5718	int status;
5719#endif
5720	ptrace_state_t state;
5721	const int slen = sizeof(state);
5722	ptrace_event_t event;
5723	const int elen = sizeof(event);
5724	struct sigaction sa;
5725	struct ptrace_siginfo info;
5726	sigset_t intmask;
5727	struct kinfo_proc2 kp;
5728	size_t len = sizeof(kp);
5729
5730	int name[6];
5731	const size_t namelen = __arraycount(name);
5732	ki_sigset_t kp_sigmask;
5733	ki_sigset_t kp_sigignore;
5734
5735	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
5736
5737	DPRINTF("Before forking process PID=%d\n", getpid());
5738	SYSCALL_REQUIRE((child = fork()) != -1);
5739	if (child == 0) {
5740		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5741		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5742
5743		if (masked) {
5744			sigemptyset(&intmask);
5745			sigaddset(&intmask, SIGTRAP);
5746			sigprocmask(SIG_BLOCK, &intmask, NULL);
5747		}
5748
5749		if (ignored) {
5750			memset(&sa, 0, sizeof(sa));
5751			sa.sa_handler = SIG_IGN;
5752			sigemptyset(&sa.sa_mask);
5753			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
5754		}
5755
5756		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5757		FORKEE_ASSERT(raise(sigval) == 0);
5758
5759		if (strcmp(fn, "spawn") == 0) {
5760			FORKEE_ASSERT_EQ(posix_spawn(&child2,
5761			    arg[0], NULL, NULL, arg, NULL), 0);
5762		} else  {
5763			if (strcmp(fn, "fork") == 0) {
5764				FORKEE_ASSERT((child2 = fork()) != -1);
5765			} else {
5766				FORKEE_ASSERT((child2 = vfork()) != -1);
5767			}
5768			if (child2 == 0)
5769				_exit(exitval2);
5770		}
5771
5772		FORKEE_REQUIRE_SUCCESS
5773		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
5774
5775		forkee_status_exited(status, exitval2);
5776
5777		DPRINTF("Before exiting of the child process\n");
5778		_exit(exitval);
5779	}
5780	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5781
5782	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5783	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5784
5785	validate_status_stopped(status, sigval);
5786
5787	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5788	SYSCALL_REQUIRE(
5789	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5790
5791	DPRINTF("Before checking siginfo_t\n");
5792	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5793	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5794
5795	name[0] = CTL_KERN,
5796	name[1] = KERN_PROC2,
5797	name[2] = KERN_PROC_PID;
5798	name[3] = child;
5799	name[4] = sizeof(kp);
5800	name[5] = 1;
5801
5802	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5803
5804	if (masked)
5805		kp_sigmask = kp.p_sigmask;
5806
5807	if (ignored)
5808		kp_sigignore = kp.p_sigignore;
5809
5810	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
5811	    strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "",
5812	    strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "",
5813	    strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "",
5814	    strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child);
5815	event.pe_set_event = 0;
5816	if (strcmp(fn, "spawn") == 0)
5817		event.pe_set_event |= PTRACE_POSIX_SPAWN;
5818	if (strcmp(fn, "fork") == 0)
5819		event.pe_set_event |= PTRACE_FORK;
5820	if (strcmp(fn, "vfork") == 0)
5821		event.pe_set_event |= PTRACE_VFORK;
5822	if (strcmp(fn, "vforkdone") == 0)
5823		event.pe_set_event |= PTRACE_VFORK_DONE;
5824	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5825
5826	DPRINTF("Before resuming the child process where it left off and "
5827	    "without signal to be sent\n");
5828	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5829
5830	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
5831	    strcmp(fn, "vfork") == 0) {
5832		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
5833		    child);
5834		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
5835		    child);
5836
5837		validate_status_stopped(status, SIGTRAP);
5838
5839		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5840
5841		if (masked) {
5842			DPRINTF("kp_sigmask="
5843			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5844			    PRIx32 "\n",
5845			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
5846			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
5847
5848			DPRINTF("kp.p_sigmask="
5849			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5850			    PRIx32 "\n",
5851			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
5852			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
5853
5854			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
5855			    sizeof(kp_sigmask)));
5856		}
5857
5858		if (ignored) {
5859			DPRINTF("kp_sigignore="
5860			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5861			    PRIx32 "\n",
5862			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
5863			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
5864
5865			DPRINTF("kp.p_sigignore="
5866			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5867			    PRIx32 "\n",
5868			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
5869			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
5870
5871			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
5872			    sizeof(kp_sigignore)));
5873		}
5874
5875		SYSCALL_REQUIRE(
5876		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5877		if (strcmp(fn, "spawn") == 0) {
5878			ATF_REQUIRE_EQ(
5879			    state.pe_report_event & PTRACE_POSIX_SPAWN,
5880			       PTRACE_POSIX_SPAWN);
5881		}
5882		if (strcmp(fn, "fork") == 0) {
5883			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
5884			       PTRACE_FORK);
5885		}
5886		if (strcmp(fn, "vfork") == 0) {
5887			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
5888			       PTRACE_VFORK);
5889		}
5890
5891		child2 = state.pe_other_pid;
5892		DPRINTF("Reported ptrace event with forkee %d\n", child2);
5893
5894		DPRINTF("Before calling %s() for the forkee %d of the child "
5895		    "%d\n", TWAIT_FNAME, child2, child);
5896		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5897		    child2);
5898
5899		validate_status_stopped(status, SIGTRAP);
5900
5901		name[3] = child2;
5902		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5903
5904		if (masked) {
5905			DPRINTF("kp_sigmask="
5906			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5907			    PRIx32 "\n",
5908			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
5909			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
5910
5911			DPRINTF("kp.p_sigmask="
5912			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5913			    PRIx32 "\n",
5914			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
5915			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
5916
5917			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
5918			    sizeof(kp_sigmask)));
5919		}
5920
5921		if (ignored) {
5922			DPRINTF("kp_sigignore="
5923			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5924			    PRIx32 "\n",
5925			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
5926			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
5927
5928			DPRINTF("kp.p_sigignore="
5929			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5930			    PRIx32 "\n",
5931			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
5932			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
5933
5934			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
5935			    sizeof(kp_sigignore)));
5936		}
5937
5938		SYSCALL_REQUIRE(
5939		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
5940		if (strcmp(fn, "spawn") == 0) {
5941			ATF_REQUIRE_EQ(
5942			    state.pe_report_event & PTRACE_POSIX_SPAWN,
5943			       PTRACE_POSIX_SPAWN);
5944		}
5945		if (strcmp(fn, "fork") == 0) {
5946			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
5947			       PTRACE_FORK);
5948		}
5949		if (strcmp(fn, "vfork") == 0) {
5950			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
5951			       PTRACE_VFORK);
5952		}
5953
5954		ATF_REQUIRE_EQ(state.pe_other_pid, child);
5955
5956		DPRINTF("Before resuming the forkee process where it left off "
5957		    "and without signal to be sent\n");
5958		SYSCALL_REQUIRE(
5959		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
5960
5961		DPRINTF("Before resuming the child process where it left off "
5962		    "and without signal to be sent\n");
5963		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5964	}
5965
5966	if (strcmp(fn, "vforkdone") == 0) {
5967		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
5968		    child);
5969		TWAIT_REQUIRE_SUCCESS(
5970		    wpid = TWAIT_GENERIC(child, &status, 0), child);
5971
5972		validate_status_stopped(status, SIGTRAP);
5973
5974		name[3] = child;
5975		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5976
5977		/*
5978		 * SIGCHLD is now pending in the signal queue and
5979		 * the kernel presents it to userland as a masked signal.
5980		 */
5981		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
5982
5983		if (masked) {
5984			DPRINTF("kp_sigmask="
5985			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5986			    PRIx32 "\n",
5987			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
5988			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
5989
5990			DPRINTF("kp.p_sigmask="
5991			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
5992			    PRIx32 "\n",
5993			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
5994			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
5995
5996			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
5997			    sizeof(kp_sigmask)));
5998		}
5999
6000		if (ignored) {
6001			DPRINTF("kp_sigignore="
6002			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6003			    PRIx32 "\n",
6004			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
6005			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
6006
6007			DPRINTF("kp.p_sigignore="
6008			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6009			    PRIx32 "\n",
6010			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
6011			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
6012
6013			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
6014			    sizeof(kp_sigignore)));
6015		}
6016
6017		SYSCALL_REQUIRE(
6018		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6019		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
6020
6021		child2 = state.pe_other_pid;
6022		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
6023		    child2);
6024
6025		DPRINTF("Before resuming the child process where it left off "
6026		    "and without signal to be sent\n");
6027		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6028	}
6029
6030	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
6031	    strcmp(fn, "vfork") == 0) {
6032		DPRINTF("Before calling %s() for the forkee - expected exited"
6033		    "\n", TWAIT_FNAME);
6034		TWAIT_REQUIRE_SUCCESS(
6035		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6036
6037		validate_status_exited(status, exitval2);
6038
6039		DPRINTF("Before calling %s() for the forkee - expected no "
6040		    "process\n", TWAIT_FNAME);
6041		TWAIT_REQUIRE_FAILURE(ECHILD,
6042		    wpid = TWAIT_GENERIC(child2, &status, 0));
6043	}
6044
6045	DPRINTF("Before calling %s() for the child - expected stopped "
6046	    "SIGCHLD\n", TWAIT_FNAME);
6047	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6048
6049	validate_status_stopped(status, SIGCHLD);
6050
6051	DPRINTF("Before resuming the child process where it left off and "
6052	    "without signal to be sent\n");
6053	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6054
6055	DPRINTF("Before calling %s() for the child - expected exited\n",
6056	    TWAIT_FNAME);
6057	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6058
6059	validate_status_exited(status, exitval);
6060
6061	DPRINTF("Before calling %s() for the child - expected no process\n",
6062	    TWAIT_FNAME);
6063	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6064}
6065
6066#define FORK2_TEST(name,fn,masked,ignored)				\
6067ATF_TC(name);								\
6068ATF_TC_HEAD(name, tc)							\
6069{									\
6070	atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught "	\
6071	    "regardless of signal %s%s", 				\
6072	    masked ? "masked" : "", ignored ? "ignored" : "");		\
6073}									\
6074									\
6075ATF_TC_BODY(name, tc)							\
6076{									\
6077									\
6078	fork2_body(fn, masked, ignored);				\
6079}
6080
6081FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false)
6082FORK2_TEST(posix_spawn_singalignored, "spawn", false, true)
6083FORK2_TEST(fork_singalmasked, "fork", true, false)
6084FORK2_TEST(fork_singalignored, "fork", false, true)
6085#if TEST_VFORK_ENABLED
6086FORK2_TEST(vfork_singalmasked, "vfork", true, false)
6087FORK2_TEST(vfork_singalignored, "vfork", false, true)
6088FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false)
6089FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true)
6090#endif
6091#endif
6092
6093/// ----------------------------------------------------------------------------
6094
6095volatile lwpid_t the_lwp_id = 0;
6096
6097static void
6098lwp_main_func(void *arg)
6099{
6100	the_lwp_id = _lwp_self();
6101	_lwp_exit();
6102}
6103
6104ATF_TC(signal9);
6105ATF_TC_HEAD(signal9, tc)
6106{
6107	atf_tc_set_md_var(tc, "descr",
6108	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
6109	    "catching PTRACE_LWP_CREATE breakpoint");
6110}
6111
6112ATF_TC_BODY(signal9, tc)
6113{
6114	const int exitval = 5;
6115	const int sigval = SIGSTOP;
6116	const int sigmasked = SIGTRAP;
6117	pid_t child, wpid;
6118#if defined(TWAIT_HAVE_STATUS)
6119	int status;
6120#endif
6121	sigset_t intmask;
6122	ptrace_state_t state;
6123	const int slen = sizeof(state);
6124	ptrace_event_t event;
6125	const int elen = sizeof(event);
6126	ucontext_t uc;
6127	lwpid_t lid;
6128	static const size_t ssize = 16*1024;
6129	void *stack;
6130
6131	DPRINTF("Before forking process PID=%d\n", getpid());
6132	SYSCALL_REQUIRE((child = fork()) != -1);
6133	if (child == 0) {
6134		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6135		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6136
6137		sigemptyset(&intmask);
6138		sigaddset(&intmask, sigmasked);
6139		sigprocmask(SIG_BLOCK, &intmask, NULL);
6140
6141		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6142		FORKEE_ASSERT(raise(sigval) == 0);
6143
6144		DPRINTF("Before allocating memory for stack in child\n");
6145		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6146
6147		DPRINTF("Before making context for new lwp in child\n");
6148		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
6149
6150		DPRINTF("Before creating new in child\n");
6151		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6152
6153		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6154		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6155
6156		DPRINTF("Before verifying that reported %d and running lid %d "
6157		    "are the same\n", lid, the_lwp_id);
6158		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6159
6160		DPRINTF("Before exiting of the child process\n");
6161		_exit(exitval);
6162	}
6163	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6164
6165	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6166	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6167
6168	validate_status_stopped(status, sigval);
6169
6170	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
6171	event.pe_set_event = PTRACE_LWP_CREATE;
6172	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6173
6174	DPRINTF("Before resuming the child process where it left off and "
6175	    "without signal to be sent\n");
6176	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6177
6178	DPRINTF("Before calling %s() for the child - expected stopped "
6179	    "SIGTRAP\n", TWAIT_FNAME);
6180	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6181
6182	validate_status_stopped(status, sigmasked);
6183
6184	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6185
6186	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
6187
6188	lid = state.pe_lwp;
6189	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
6190
6191	DPRINTF("Before resuming the child process where it left off and "
6192	    "without signal to be sent\n");
6193	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6194
6195	DPRINTF("Before calling %s() for the child - expected exited\n",
6196	    TWAIT_FNAME);
6197	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6198
6199	validate_status_exited(status, exitval);
6200
6201	DPRINTF("Before calling %s() for the child - expected no process\n",
6202	    TWAIT_FNAME);
6203	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6204}
6205
6206ATF_TC(signal10);
6207ATF_TC_HEAD(signal10, tc)
6208{
6209	atf_tc_set_md_var(tc, "descr",
6210	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
6211	    "catching PTRACE_LWP_EXIT breakpoint");
6212}
6213
6214ATF_TC_BODY(signal10, tc)
6215{
6216	const int exitval = 5;
6217	const int sigval = SIGSTOP;
6218	const int sigmasked = SIGTRAP;
6219	pid_t child, wpid;
6220#if defined(TWAIT_HAVE_STATUS)
6221	int status;
6222#endif
6223	sigset_t intmask;
6224	ptrace_state_t state;
6225	const int slen = sizeof(state);
6226	ptrace_event_t event;
6227	const int elen = sizeof(event);
6228	ucontext_t uc;
6229	lwpid_t lid;
6230	static const size_t ssize = 16*1024;
6231	void *stack;
6232
6233	DPRINTF("Before forking process PID=%d\n", getpid());
6234	SYSCALL_REQUIRE((child = fork()) != -1);
6235	if (child == 0) {
6236		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6237		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6238
6239		sigemptyset(&intmask);
6240		sigaddset(&intmask, sigmasked);
6241		sigprocmask(SIG_BLOCK, &intmask, NULL);
6242
6243		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6244		FORKEE_ASSERT(raise(sigval) == 0);
6245
6246		DPRINTF("Before allocating memory for stack in child\n");
6247		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6248
6249		DPRINTF("Before making context for new lwp in child\n");
6250		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
6251
6252		DPRINTF("Before creating new in child\n");
6253		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6254
6255		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6256		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6257
6258		DPRINTF("Before verifying that reported %d and running lid %d "
6259		    "are the same\n", lid, the_lwp_id);
6260		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6261
6262		DPRINTF("Before exiting of the child process\n");
6263		_exit(exitval);
6264	}
6265	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6266
6267	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6268	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6269
6270	validate_status_stopped(status, sigval);
6271
6272	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
6273	event.pe_set_event = PTRACE_LWP_EXIT;
6274	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6275
6276	DPRINTF("Before resuming the child process where it left off and "
6277	    "without signal to be sent\n");
6278	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6279
6280	DPRINTF("Before calling %s() for the child - expected stopped "
6281	    "SIGTRAP\n", TWAIT_FNAME);
6282	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6283
6284	validate_status_stopped(status, sigmasked);
6285
6286	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6287
6288	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
6289
6290	lid = state.pe_lwp;
6291	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
6292
6293	DPRINTF("Before resuming the child process where it left off and "
6294	    "without signal to be sent\n");
6295	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6296
6297	DPRINTF("Before calling %s() for the child - expected exited\n",
6298	    TWAIT_FNAME);
6299	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6300
6301	validate_status_exited(status, exitval);
6302
6303	DPRINTF("Before calling %s() for the child - expected no process\n",
6304	    TWAIT_FNAME);
6305	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6306}
6307
6308static void
6309lwp_main_stop(void *arg)
6310{
6311	the_lwp_id = _lwp_self();
6312
6313	raise(SIGTRAP);
6314
6315	_lwp_exit();
6316}
6317
6318ATF_TC(suspend1);
6319ATF_TC_HEAD(suspend1, tc)
6320{
6321	atf_tc_set_md_var(tc, "descr",
6322	    "Verify that a thread can be suspended by a debugger and later "
6323	    "resumed by a tracee");
6324}
6325
6326ATF_TC_BODY(suspend1, tc)
6327{
6328	const int exitval = 5;
6329	const int sigval = SIGSTOP;
6330	pid_t child, wpid;
6331#if defined(TWAIT_HAVE_STATUS)
6332	int status;
6333#endif
6334	ucontext_t uc;
6335	lwpid_t lid;
6336	static const size_t ssize = 16*1024;
6337	void *stack;
6338	struct ptrace_lwpinfo pl;
6339	struct ptrace_siginfo psi;
6340	volatile int go = 0;
6341
6342	DPRINTF("Before forking process PID=%d\n", getpid());
6343	SYSCALL_REQUIRE((child = fork()) != -1);
6344	if (child == 0) {
6345		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6346		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6347
6348		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6349		FORKEE_ASSERT(raise(sigval) == 0);
6350
6351		DPRINTF("Before allocating memory for stack in child\n");
6352		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6353
6354		DPRINTF("Before making context for new lwp in child\n");
6355		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
6356
6357		DPRINTF("Before creating new in child\n");
6358		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6359
6360		while (go == 0)
6361			continue;
6362
6363		raise(SIGINT);
6364
6365		FORKEE_ASSERT(_lwp_continue(lid) == 0);
6366
6367		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6368		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6369
6370		DPRINTF("Before verifying that reported %d and running lid %d "
6371		    "are the same\n", lid, the_lwp_id);
6372		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6373
6374		DPRINTF("Before exiting of the child process\n");
6375		_exit(exitval);
6376	}
6377	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6378
6379	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6380	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6381
6382	validate_status_stopped(status, sigval);
6383
6384	DPRINTF("Before resuming the child process where it left off and "
6385	    "without signal to be sent\n");
6386	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6387
6388	DPRINTF("Before calling %s() for the child - expected stopped "
6389	    "SIGTRAP\n", TWAIT_FNAME);
6390	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6391
6392	validate_status_stopped(status, SIGTRAP);
6393
6394	DPRINTF("Before reading siginfo and lwpid_t\n");
6395	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6396
6397	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6398	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6399
6400        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
6401	    child, getpid());
6402	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
6403
6404	DPRINTF("Before resuming the child process where it left off and "
6405	    "without signal to be sent\n");
6406	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6407
6408	DPRINTF("Before calling %s() for the child - expected stopped "
6409	    "SIGINT\n", TWAIT_FNAME);
6410	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6411
6412	validate_status_stopped(status, SIGINT);
6413
6414	pl.pl_lwpid = 0;
6415
6416	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6417	while (pl.pl_lwpid != 0) {
6418
6419		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6420		switch (pl.pl_lwpid) {
6421		case 1:
6422			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
6423			break;
6424		case 2:
6425			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
6426			break;
6427		}
6428	}
6429
6430	DPRINTF("Before resuming the child process where it left off and "
6431	    "without signal to be sent\n");
6432	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6433
6434	DPRINTF("Before calling %s() for the child - expected exited\n",
6435	    TWAIT_FNAME);
6436	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6437
6438	validate_status_exited(status, exitval);
6439
6440	DPRINTF("Before calling %s() for the child - expected no process\n",
6441	    TWAIT_FNAME);
6442	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6443}
6444
6445ATF_TC(suspend2);
6446ATF_TC_HEAD(suspend2, tc)
6447{
6448	atf_tc_set_md_var(tc, "descr",
6449	    "Verify that the while the only thread within a process is "
6450	    "suspended, the whole process cannot be unstopped");
6451}
6452
6453ATF_TC_BODY(suspend2, tc)
6454{
6455	const int exitval = 5;
6456	const int sigval = SIGSTOP;
6457	pid_t child, wpid;
6458#if defined(TWAIT_HAVE_STATUS)
6459	int status;
6460#endif
6461	struct ptrace_siginfo psi;
6462
6463	DPRINTF("Before forking process PID=%d\n", getpid());
6464	SYSCALL_REQUIRE((child = fork()) != -1);
6465	if (child == 0) {
6466		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6467		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6468
6469		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6470		FORKEE_ASSERT(raise(sigval) == 0);
6471
6472		DPRINTF("Before exiting of the child process\n");
6473		_exit(exitval);
6474	}
6475	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6476
6477	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6478	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6479
6480	validate_status_stopped(status, sigval);
6481
6482	DPRINTF("Before reading siginfo and lwpid_t\n");
6483	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6484
6485	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6486	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6487
6488	DPRINTF("Before resuming the child process where it left off and "
6489	    "without signal to be sent\n");
6490	ATF_REQUIRE_ERRNO(EDEADLK,
6491	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
6492
6493	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
6494	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
6495
6496	DPRINTF("Before resuming the child process where it left off and "
6497	    "without signal to be sent\n");
6498	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6499
6500	DPRINTF("Before calling %s() for the child - expected exited\n",
6501	    TWAIT_FNAME);
6502	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6503
6504	validate_status_exited(status, exitval);
6505
6506	DPRINTF("Before calling %s() for the child - expected no process\n",
6507	    TWAIT_FNAME);
6508	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6509}
6510
6511ATF_TC(resume1);
6512ATF_TC_HEAD(resume1, tc)
6513{
6514	atf_tc_set_md_var(tc, "descr",
6515	    "Verify that a thread can be suspended by a debugger and later "
6516	    "resumed by the debugger");
6517}
6518
6519ATF_TC_BODY(resume1, tc)
6520{
6521	struct msg_fds fds;
6522	const int exitval = 5;
6523	const int sigval = SIGSTOP;
6524	pid_t child, wpid;
6525	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6526#if defined(TWAIT_HAVE_STATUS)
6527	int status;
6528#endif
6529	ucontext_t uc;
6530	lwpid_t lid;
6531	static const size_t ssize = 16*1024;
6532	void *stack;
6533	struct ptrace_lwpinfo pl;
6534	struct ptrace_siginfo psi;
6535
6536	SYSCALL_REQUIRE(msg_open(&fds) == 0);
6537
6538	DPRINTF("Before forking process PID=%d\n", getpid());
6539	SYSCALL_REQUIRE((child = fork()) != -1);
6540	if (child == 0) {
6541		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6542		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6543
6544		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6545		FORKEE_ASSERT(raise(sigval) == 0);
6546
6547		DPRINTF("Before allocating memory for stack in child\n");
6548		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6549
6550		DPRINTF("Before making context for new lwp in child\n");
6551		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
6552
6553		DPRINTF("Before creating new in child\n");
6554		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6555
6556		CHILD_TO_PARENT("Message", fds, msg);
6557
6558		raise(SIGINT);
6559
6560		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6561		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6562
6563		DPRINTF("Before verifying that reported %d and running lid %d "
6564		    "are the same\n", lid, the_lwp_id);
6565		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6566
6567		DPRINTF("Before exiting of the child process\n");
6568		_exit(exitval);
6569	}
6570	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6571
6572	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6573	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6574
6575	validate_status_stopped(status, sigval);
6576
6577	DPRINTF("Before resuming the child process where it left off and "
6578	    "without signal to be sent\n");
6579	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6580
6581	DPRINTF("Before calling %s() for the child - expected stopped "
6582	    "SIGTRAP\n", TWAIT_FNAME);
6583	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6584
6585	validate_status_stopped(status, SIGTRAP);
6586
6587	DPRINTF("Before reading siginfo and lwpid_t\n");
6588	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6589
6590	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6591	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6592
6593	PARENT_FROM_CHILD("Message", fds, msg);
6594
6595	DPRINTF("Before resuming the child process where it left off and "
6596	    "without signal to be sent\n");
6597	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6598
6599	DPRINTF("Before calling %s() for the child - expected stopped "
6600	    "SIGINT\n", TWAIT_FNAME);
6601	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6602
6603	validate_status_stopped(status, SIGINT);
6604
6605	pl.pl_lwpid = 0;
6606
6607	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6608	while (pl.pl_lwpid != 0) {
6609		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6610		switch (pl.pl_lwpid) {
6611		case 1:
6612			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
6613			break;
6614		case 2:
6615			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
6616			break;
6617		}
6618	}
6619
6620	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
6621	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
6622
6623	DPRINTF("Before resuming the child process where it left off and "
6624	    "without signal to be sent\n");
6625	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6626
6627	DPRINTF("Before calling %s() for the child - expected exited\n",
6628	    TWAIT_FNAME);
6629	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6630
6631	validate_status_exited(status, exitval);
6632
6633	DPRINTF("Before calling %s() for the child - expected no process\n",
6634	    TWAIT_FNAME);
6635	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6636
6637	msg_close(&fds);
6638}
6639
6640ATF_TC(syscall1);
6641ATF_TC_HEAD(syscall1, tc)
6642{
6643	atf_tc_set_md_var(tc, "descr",
6644	    "Verify that getpid(2) can be traced with PT_SYSCALL");
6645}
6646
6647ATF_TC_BODY(syscall1, tc)
6648{
6649	const int exitval = 5;
6650	const int sigval = SIGSTOP;
6651	pid_t child, wpid;
6652#if defined(TWAIT_HAVE_STATUS)
6653	int status;
6654#endif
6655	struct ptrace_siginfo info;
6656	memset(&info, 0, sizeof(info));
6657
6658	DPRINTF("Before forking process PID=%d\n", getpid());
6659	SYSCALL_REQUIRE((child = fork()) != -1);
6660	if (child == 0) {
6661		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6662		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6663
6664		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6665		FORKEE_ASSERT(raise(sigval) == 0);
6666
6667		syscall(SYS_getpid);
6668
6669		DPRINTF("Before exiting of the child process\n");
6670		_exit(exitval);
6671	}
6672	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6673
6674	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6675	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6676
6677	validate_status_stopped(status, sigval);
6678
6679	DPRINTF("Before resuming the child process where it left off and "
6680	    "without signal to be sent\n");
6681	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6682
6683	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6684	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6685
6686	validate_status_stopped(status, SIGTRAP);
6687
6688	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6689	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6690
6691	DPRINTF("Before checking siginfo_t and lwpid\n");
6692	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
6693	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6694	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
6695
6696	DPRINTF("Before resuming the child process where it left off and "
6697	    "without signal to be sent\n");
6698	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6699
6700	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6701	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6702
6703	validate_status_stopped(status, SIGTRAP);
6704
6705	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6706	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6707
6708	DPRINTF("Before checking siginfo_t and lwpid\n");
6709	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
6710	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6711	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
6712
6713	DPRINTF("Before resuming the child process where it left off and "
6714	    "without signal to be sent\n");
6715	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6716
6717	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6718	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6719
6720	validate_status_exited(status, exitval);
6721
6722	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6723	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6724}
6725
6726ATF_TC(syscallemu1);
6727ATF_TC_HEAD(syscallemu1, tc)
6728{
6729	atf_tc_set_md_var(tc, "descr",
6730	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
6731}
6732
6733ATF_TC_BODY(syscallemu1, tc)
6734{
6735	const int exitval = 5;
6736	const int sigval = SIGSTOP;
6737	pid_t child, wpid;
6738#if defined(TWAIT_HAVE_STATUS)
6739	int status;
6740#endif
6741
6742#if defined(__sparc__) && !defined(__sparc64__)
6743	/* syscallemu does not work on sparc (32-bit) */
6744	atf_tc_expect_fail("PR kern/52166");
6745#endif
6746
6747	DPRINTF("Before forking process PID=%d\n", getpid());
6748	SYSCALL_REQUIRE((child = fork()) != -1);
6749	if (child == 0) {
6750		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6751		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6752
6753		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6754		FORKEE_ASSERT(raise(sigval) == 0);
6755
6756		syscall(SYS_exit, 100);
6757
6758		DPRINTF("Before exiting of the child process\n");
6759		_exit(exitval);
6760	}
6761	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6762
6763	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6764	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6765
6766	validate_status_stopped(status, sigval);
6767
6768	DPRINTF("Before resuming the child process where it left off and "
6769	    "without signal to be sent\n");
6770	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6771
6772	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6773	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6774
6775	validate_status_stopped(status, SIGTRAP);
6776
6777	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
6778	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
6779
6780	DPRINTF("Before resuming the child process where it left off and "
6781	    "without signal to be sent\n");
6782	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6783
6784	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6785	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6786
6787	validate_status_stopped(status, SIGTRAP);
6788
6789	DPRINTF("Before resuming the child process where it left off and "
6790	    "without signal to be sent\n");
6791	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6792
6793	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6794	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6795
6796	validate_status_exited(status, exitval);
6797
6798	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6799	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6800}
6801
6802/// ----------------------------------------------------------------------------
6803
6804static void
6805clone_body(int flags, bool trackfork, bool trackvfork,
6806    bool trackvforkdone)
6807{
6808	const int exitval = 5;
6809	const int exitval2 = 15;
6810	const int sigval = SIGSTOP;
6811	pid_t child, child2 = 0, wpid;
6812#if defined(TWAIT_HAVE_STATUS)
6813	int status;
6814#endif
6815	ptrace_state_t state;
6816	const int slen = sizeof(state);
6817	ptrace_event_t event;
6818	const int elen = sizeof(event);
6819
6820	const size_t stack_size = 1024 * 1024;
6821	void *stack, *stack_base;
6822
6823	stack = malloc(stack_size);
6824	ATF_REQUIRE(stack != NULL);
6825
6826#ifdef __MACHINE_STACK_GROWS_UP
6827	stack_base = stack;
6828#else
6829	stack_base = (char *)stack + stack_size;
6830#endif
6831
6832	DPRINTF("Before forking process PID=%d\n", getpid());
6833	SYSCALL_REQUIRE((child = fork()) != -1);
6834	if (child == 0) {
6835		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6836		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6837
6838		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6839		FORKEE_ASSERT(raise(sigval) == 0);
6840
6841		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
6842		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
6843
6844		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
6845		    child2);
6846
6847		// XXX WALLSIG?
6848		FORKEE_REQUIRE_SUCCESS
6849		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
6850
6851		forkee_status_exited(status, exitval2);
6852
6853		DPRINTF("Before exiting of the child process\n");
6854		_exit(exitval);
6855	}
6856	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6857
6858	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6859	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6860
6861	validate_status_stopped(status, sigval);
6862
6863	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
6864	    trackfork ? "|PTRACE_FORK" : "",
6865	    trackvfork ? "|PTRACE_VFORK" : "",
6866	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
6867	event.pe_set_event = 0;
6868	if (trackfork)
6869		event.pe_set_event |= PTRACE_FORK;
6870	if (trackvfork)
6871		event.pe_set_event |= PTRACE_VFORK;
6872	if (trackvforkdone)
6873		event.pe_set_event |= PTRACE_VFORK_DONE;
6874	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6875
6876	DPRINTF("Before resuming the child process where it left off and "
6877	    "without signal to be sent\n");
6878	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6879
6880#if defined(TWAIT_HAVE_PID)
6881	if ((trackfork && !(flags & CLONE_VFORK)) ||
6882	    (trackvfork && (flags & CLONE_VFORK))) {
6883		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
6884		    child);
6885		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6886		    child);
6887
6888		validate_status_stopped(status, SIGTRAP);
6889
6890		SYSCALL_REQUIRE(
6891		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6892		if (trackfork && !(flags & CLONE_VFORK)) {
6893			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
6894			       PTRACE_FORK);
6895		}
6896		if (trackvfork && (flags & CLONE_VFORK)) {
6897			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
6898			       PTRACE_VFORK);
6899		}
6900
6901		child2 = state.pe_other_pid;
6902		DPRINTF("Reported ptrace event with forkee %d\n", child2);
6903
6904		DPRINTF("Before calling %s() for the forkee %d of the child "
6905		    "%d\n", TWAIT_FNAME, child2, child);
6906		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6907		    child2);
6908
6909		validate_status_stopped(status, SIGTRAP);
6910
6911		SYSCALL_REQUIRE(
6912		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
6913		if (trackfork && !(flags & CLONE_VFORK)) {
6914			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
6915			       PTRACE_FORK);
6916		}
6917		if (trackvfork && (flags & CLONE_VFORK)) {
6918			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
6919			       PTRACE_VFORK);
6920		}
6921
6922		ATF_REQUIRE_EQ(state.pe_other_pid, child);
6923
6924		DPRINTF("Before resuming the forkee process where it left off "
6925		    "and without signal to be sent\n");
6926		SYSCALL_REQUIRE(
6927		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
6928
6929		DPRINTF("Before resuming the child process where it left off "
6930		    "and without signal to be sent\n");
6931		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6932	}
6933#endif
6934
6935	if (trackvforkdone && (flags & CLONE_VFORK)) {
6936		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
6937		    child);
6938		TWAIT_REQUIRE_SUCCESS(
6939		    wpid = TWAIT_GENERIC(child, &status, 0), child);
6940
6941		validate_status_stopped(status, SIGTRAP);
6942
6943		SYSCALL_REQUIRE(
6944		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6945		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
6946
6947		child2 = state.pe_other_pid;
6948		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
6949		    child2);
6950
6951		DPRINTF("Before resuming the child process where it left off "
6952		    "and without signal to be sent\n");
6953		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6954	}
6955
6956#if defined(TWAIT_HAVE_PID)
6957	if ((trackfork && !(flags & CLONE_VFORK)) ||
6958	    (trackvfork && (flags & CLONE_VFORK))) {
6959		DPRINTF("Before calling %s() for the forkee - expected exited"
6960		    "\n", TWAIT_FNAME);
6961		TWAIT_REQUIRE_SUCCESS(
6962		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6963
6964		validate_status_exited(status, exitval2);
6965
6966		DPRINTF("Before calling %s() for the forkee - expected no "
6967		    "process\n", TWAIT_FNAME);
6968		TWAIT_REQUIRE_FAILURE(ECHILD,
6969		    wpid = TWAIT_GENERIC(child2, &status, 0));
6970	}
6971#endif
6972
6973	DPRINTF("Before calling %s() for the child - expected stopped "
6974	    "SIGCHLD\n", TWAIT_FNAME);
6975	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6976
6977	validate_status_stopped(status, SIGCHLD);
6978
6979	DPRINTF("Before resuming the child process where it left off and "
6980	    "without signal to be sent\n");
6981	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6982
6983	DPRINTF("Before calling %s() for the child - expected exited\n",
6984	    TWAIT_FNAME);
6985	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6986
6987	validate_status_exited(status, exitval);
6988
6989	DPRINTF("Before calling %s() for the child - expected no process\n",
6990	    TWAIT_FNAME);
6991	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6992}
6993
6994#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone)			\
6995ATF_TC(name);								\
6996ATF_TC_HEAD(name, tc)							\
6997{									\
6998	atf_tc_set_md_var(tc, "descr", "Verify clone(%s) "		\
6999	    "called with 0%s%s%s in EVENT_MASK",			\
7000	    #flags,							\
7001	    tfork ? "|PTRACE_FORK" : "",				\
7002	    tvfork ? "|PTRACE_VFORK" : "",				\
7003	    tvforkdone ? "|PTRACE_VFORK_DONE" : "");			\
7004}									\
7005									\
7006ATF_TC_BODY(name, tc)							\
7007{									\
7008									\
7009	clone_body(flags, tfork, tvfork, tvforkdone);			\
7010}
7011
7012CLONE_TEST(clone1, 0, false, false, false)
7013#if defined(TWAIT_HAVE_PID)
7014CLONE_TEST(clone2, 0, true, false, false)
7015CLONE_TEST(clone3, 0, false, true, false)
7016CLONE_TEST(clone4, 0, true, true, false)
7017#endif
7018CLONE_TEST(clone5, 0, false, false, true)
7019#if defined(TWAIT_HAVE_PID)
7020CLONE_TEST(clone6, 0, true, false, true)
7021CLONE_TEST(clone7, 0, false, true, true)
7022CLONE_TEST(clone8, 0, true, true, true)
7023#endif
7024
7025CLONE_TEST(clone_vm1, CLONE_VM, false, false, false)
7026#if defined(TWAIT_HAVE_PID)
7027CLONE_TEST(clone_vm2, CLONE_VM, true, false, false)
7028CLONE_TEST(clone_vm3, CLONE_VM, false, true, false)
7029CLONE_TEST(clone_vm4, CLONE_VM, true, true, false)
7030#endif
7031CLONE_TEST(clone_vm5, CLONE_VM, false, false, true)
7032#if defined(TWAIT_HAVE_PID)
7033CLONE_TEST(clone_vm6, CLONE_VM, true, false, true)
7034CLONE_TEST(clone_vm7, CLONE_VM, false, true, true)
7035CLONE_TEST(clone_vm8, CLONE_VM, true, true, true)
7036#endif
7037
7038CLONE_TEST(clone_fs1, CLONE_FS, false, false, false)
7039#if defined(TWAIT_HAVE_PID)
7040CLONE_TEST(clone_fs2, CLONE_FS, true, false, false)
7041CLONE_TEST(clone_fs3, CLONE_FS, false, true, false)
7042CLONE_TEST(clone_fs4, CLONE_FS, true, true, false)
7043#endif
7044CLONE_TEST(clone_fs5, CLONE_FS, false, false, true)
7045#if defined(TWAIT_HAVE_PID)
7046CLONE_TEST(clone_fs6, CLONE_FS, true, false, true)
7047CLONE_TEST(clone_fs7, CLONE_FS, false, true, true)
7048CLONE_TEST(clone_fs8, CLONE_FS, true, true, true)
7049#endif
7050
7051CLONE_TEST(clone_files1, CLONE_FILES, false, false, false)
7052#if defined(TWAIT_HAVE_PID)
7053CLONE_TEST(clone_files2, CLONE_FILES, true, false, false)
7054CLONE_TEST(clone_files3, CLONE_FILES, false, true, false)
7055CLONE_TEST(clone_files4, CLONE_FILES, true, true, false)
7056#endif
7057CLONE_TEST(clone_files5, CLONE_FILES, false, false, true)
7058#if defined(TWAIT_HAVE_PID)
7059CLONE_TEST(clone_files6, CLONE_FILES, true, false, true)
7060CLONE_TEST(clone_files7, CLONE_FILES, false, true, true)
7061CLONE_TEST(clone_files8, CLONE_FILES, true, true, true)
7062#endif
7063
7064//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false)
7065#if defined(TWAIT_HAVE_PID)
7066//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false)
7067//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false)
7068//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false)
7069#endif
7070//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true)
7071#if defined(TWAIT_HAVE_PID)
7072//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true)
7073//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true)
7074//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true)
7075#endif
7076
7077#if TEST_VFORK_ENABLED
7078CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false)
7079#if defined(TWAIT_HAVE_PID)
7080CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false)
7081CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false)
7082CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false)
7083#endif
7084CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true)
7085#if defined(TWAIT_HAVE_PID)
7086CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true)
7087CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true)
7088CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true)
7089#endif
7090#endif
7091
7092/// ----------------------------------------------------------------------------
7093
7094#if defined(TWAIT_HAVE_PID)
7095static void
7096clone_body2(int flags, bool masked, bool ignored)
7097{
7098	const int exitval = 5;
7099	const int exitval2 = 15;
7100	const int sigval = SIGSTOP;
7101	pid_t child, child2 = 0, wpid;
7102#if defined(TWAIT_HAVE_STATUS)
7103	int status;
7104#endif
7105	ptrace_state_t state;
7106	const int slen = sizeof(state);
7107	ptrace_event_t event;
7108	const int elen = sizeof(event);
7109	struct sigaction sa;
7110	struct ptrace_siginfo info;
7111	sigset_t intmask;
7112	struct kinfo_proc2 kp;
7113	size_t len = sizeof(kp);
7114
7115	int name[6];
7116	const size_t namelen = __arraycount(name);
7117	ki_sigset_t kp_sigmask;
7118	ki_sigset_t kp_sigignore;
7119
7120	const size_t stack_size = 1024 * 1024;
7121	void *stack, *stack_base;
7122
7123	stack = malloc(stack_size);
7124	ATF_REQUIRE(stack != NULL);
7125
7126#ifdef __MACHINE_STACK_GROWS_UP
7127	stack_base = stack;
7128#else
7129	stack_base = (char *)stack + stack_size;
7130#endif
7131
7132	SYSCALL_REQUIRE((child = fork()) != -1);
7133	if (child == 0) {
7134		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7135		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7136
7137		if (masked) {
7138			sigemptyset(&intmask);
7139			sigaddset(&intmask, SIGTRAP);
7140			sigprocmask(SIG_BLOCK, &intmask, NULL);
7141		}
7142
7143		if (ignored) {
7144			memset(&sa, 0, sizeof(sa));
7145			sa.sa_handler = SIG_IGN;
7146			sigemptyset(&sa.sa_mask);
7147			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
7148		}
7149		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7150		FORKEE_ASSERT(raise(sigval) == 0);
7151
7152		DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
7153		    flags);
7154		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7155		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7156
7157		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7158		    child2);
7159
7160		// XXX WALLSIG?
7161		FORKEE_REQUIRE_SUCCESS
7162		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7163
7164		forkee_status_exited(status, exitval2);
7165
7166		DPRINTF("Before exiting of the child process\n");
7167		_exit(exitval);
7168	}
7169	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7170
7171	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7172	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7173
7174	validate_status_stopped(status, sigval);
7175
7176	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
7177	SYSCALL_REQUIRE(
7178	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
7179
7180	DPRINTF("Before checking siginfo_t\n");
7181	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
7182	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
7183
7184	name[0] = CTL_KERN,
7185	name[1] = KERN_PROC2,
7186	name[2] = KERN_PROC_PID;
7187	name[3] = child;
7188	name[4] = sizeof(kp);
7189	name[5] = 1;
7190
7191	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7192
7193	if (masked)
7194		kp_sigmask = kp.p_sigmask;
7195
7196	if (ignored)
7197		kp_sigignore = kp.p_sigignore;
7198
7199	DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in "
7200	    "EVENT_MASK for the child %d\n", child);
7201	event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE;
7202	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
7203
7204	DPRINTF("Before resuming the child process where it left off and "
7205	    "without signal to be sent\n");
7206	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7207
7208	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7209	    child);
7210	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
7211	    child);
7212
7213	validate_status_stopped(status, SIGTRAP);
7214
7215	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7216
7217	if (masked) {
7218		DPRINTF("kp_sigmask="
7219		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7220		    PRIx32 "\n",
7221		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7222		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7223
7224		DPRINTF("kp.p_sigmask="
7225		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7226		    PRIx32 "\n",
7227		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7228		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7229
7230		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7231		    sizeof(kp_sigmask)));
7232	}
7233
7234	if (ignored) {
7235		DPRINTF("kp_sigignore="
7236		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7237		    PRIx32 "\n",
7238		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7239		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7240
7241		DPRINTF("kp.p_sigignore="
7242		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7243		    PRIx32 "\n",
7244		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7245		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7246
7247		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7248		    sizeof(kp_sigignore)));
7249	}
7250
7251	SYSCALL_REQUIRE(
7252	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7253	DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event,
7254	    child2);
7255	if (!(flags & CLONE_VFORK)) {
7256		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7257		       PTRACE_FORK);
7258	} else {
7259		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7260		       PTRACE_VFORK);
7261	}
7262
7263	child2 = state.pe_other_pid;
7264	DPRINTF("Reported ptrace event with forkee %d\n", child2);
7265
7266	DPRINTF("Before calling %s() for the forkee %d of the child "
7267	    "%d\n", TWAIT_FNAME, child2, child);
7268	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
7269	    child2);
7270
7271	validate_status_stopped(status, SIGTRAP);
7272
7273	name[3] = child2;
7274	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7275
7276	if (masked) {
7277		DPRINTF("kp_sigmask="
7278		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7279		    PRIx32 "\n",
7280		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7281		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7282
7283		DPRINTF("kp.p_sigmask="
7284		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7285		    PRIx32 "\n",
7286		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7287		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7288
7289		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7290		    sizeof(kp_sigmask)));
7291	}
7292
7293	if (ignored) {
7294		DPRINTF("kp_sigignore="
7295		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7296		    PRIx32 "\n",
7297		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7298		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7299
7300		DPRINTF("kp.p_sigignore="
7301		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7302		    PRIx32 "\n",
7303		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7304		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7305
7306		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7307		    sizeof(kp_sigignore)));
7308	}
7309
7310	SYSCALL_REQUIRE(
7311	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
7312	if (!(flags & CLONE_VFORK)) {
7313		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7314		       PTRACE_FORK);
7315	} else {
7316		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7317		       PTRACE_VFORK);
7318	}
7319
7320	ATF_REQUIRE_EQ(state.pe_other_pid, child);
7321
7322	DPRINTF("Before resuming the forkee process where it left off "
7323	    "and without signal to be sent\n");
7324	SYSCALL_REQUIRE(
7325	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
7326
7327	DPRINTF("Before resuming the child process where it left off "
7328	    "and without signal to be sent\n");
7329	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7330
7331	if (flags & CLONE_VFORK) {
7332		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7333		    child);
7334		TWAIT_REQUIRE_SUCCESS(
7335		    wpid = TWAIT_GENERIC(child, &status, 0), child);
7336
7337		validate_status_stopped(status, SIGTRAP);
7338
7339		name[3] = child;
7340		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7341
7342		/*
7343		 * SIGCHLD is now pending in the signal queue and
7344		 * the kernel presents it to userland as a masked signal.
7345		 */
7346		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
7347
7348		if (masked) {
7349			DPRINTF("kp_sigmask="
7350			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7351			    PRIx32 "\n",
7352			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7353			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7354
7355			DPRINTF("kp.p_sigmask="
7356			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7357			    PRIx32 "\n",
7358			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7359			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7360
7361			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7362			    sizeof(kp_sigmask)));
7363		}
7364
7365		if (ignored) {
7366			DPRINTF("kp_sigignore="
7367			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7368			    PRIx32 "\n",
7369			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7370			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7371
7372			DPRINTF("kp.p_sigignore="
7373			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7374			    PRIx32 "\n",
7375			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7376			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7377
7378			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7379			    sizeof(kp_sigignore)));
7380		}
7381
7382		SYSCALL_REQUIRE(
7383		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7384		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
7385
7386		child2 = state.pe_other_pid;
7387		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
7388		    child2);
7389
7390		DPRINTF("Before resuming the child process where it left off "
7391		    "and without signal to be sent\n");
7392		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7393	}
7394
7395	DPRINTF("Before calling %s() for the forkee - expected exited"
7396	    "\n", TWAIT_FNAME);
7397	TWAIT_REQUIRE_SUCCESS(
7398	    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
7399
7400	validate_status_exited(status, exitval2);
7401
7402	DPRINTF("Before calling %s() for the forkee - expected no "
7403	    "process\n", TWAIT_FNAME);
7404	TWAIT_REQUIRE_FAILURE(ECHILD,
7405	    wpid = TWAIT_GENERIC(child2, &status, 0));
7406
7407	DPRINTF("Before calling %s() for the child - expected stopped "
7408	    "SIGCHLD\n", TWAIT_FNAME);
7409	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7410
7411	validate_status_stopped(status, SIGCHLD);
7412
7413	DPRINTF("Before resuming the child process where it left off and "
7414	    "without signal to be sent\n");
7415	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7416
7417	DPRINTF("Before calling %s() for the child - expected exited\n",
7418	    TWAIT_FNAME);
7419	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7420
7421	validate_status_exited(status, exitval);
7422
7423	DPRINTF("Before calling %s() for the child - expected no process\n",
7424	    TWAIT_FNAME);
7425	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7426}
7427
7428#define CLONE_TEST2(name,flags,masked,ignored)				\
7429ATF_TC(name);								\
7430ATF_TC_HEAD(name, tc)							\
7431{									\
7432	atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\
7433	    " regardless of signal %s%s", 				\
7434	    #flags, masked ? "masked" : "", ignored ? "ignored" : "");	\
7435}									\
7436									\
7437ATF_TC_BODY(name, tc)							\
7438{									\
7439									\
7440	clone_body2(flags, masked, ignored);				\
7441}
7442
7443CLONE_TEST2(clone_signalignored, 0, true, false)
7444CLONE_TEST2(clone_signalmasked, 0, false, true)
7445CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false)
7446CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true)
7447CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false)
7448CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true)
7449CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false)
7450CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true)
7451//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX
7452//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true)  // XXX
7453#if TEST_VFORK_ENABLED
7454CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false)
7455CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true)
7456#endif
7457#endif
7458
7459/// ----------------------------------------------------------------------------
7460
7461#if TEST_VFORK_ENABLED
7462#if defined(TWAIT_HAVE_PID)
7463static void
7464traceme_vfork_clone_body(int flags)
7465{
7466	const int exitval = 5;
7467	const int exitval2 = 15;
7468	pid_t child, child2 = 0, wpid;
7469#if defined(TWAIT_HAVE_STATUS)
7470	int status;
7471#endif
7472
7473	const size_t stack_size = 1024 * 1024;
7474	void *stack, *stack_base;
7475
7476	stack = malloc(stack_size);
7477	ATF_REQUIRE(stack != NULL);
7478
7479#ifdef __MACHINE_STACK_GROWS_UP
7480	stack_base = stack;
7481#else
7482	stack_base = (char *)stack + stack_size;
7483#endif
7484
7485	SYSCALL_REQUIRE((child = vfork()) != -1);
7486	if (child == 0) {
7487		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7488		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7489
7490		DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
7491		    flags);
7492		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7493		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7494
7495		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7496		    child2);
7497
7498		// XXX WALLSIG?
7499		FORKEE_REQUIRE_SUCCESS
7500		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7501
7502		forkee_status_exited(status, exitval2);
7503
7504		DPRINTF("Before exiting of the child process\n");
7505		_exit(exitval);
7506	}
7507	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7508
7509	DPRINTF("Before calling %s() for the child - expected exited\n",
7510	    TWAIT_FNAME);
7511	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7512
7513	validate_status_exited(status, exitval);
7514
7515	DPRINTF("Before calling %s() for the child - expected no process\n",
7516	    TWAIT_FNAME);
7517	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7518}
7519
7520#define TRACEME_VFORK_CLONE_TEST(name,flags)				\
7521ATF_TC(name);								\
7522ATF_TC_HEAD(name, tc)							\
7523{									\
7524	atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is "	\
7525	    "handled correctly with vfork(2)ed tracer", 		\
7526	    #flags);							\
7527}									\
7528									\
7529ATF_TC_BODY(name, tc)							\
7530{									\
7531									\
7532	traceme_vfork_clone_body(flags);				\
7533}
7534
7535TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0)
7536TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM)
7537TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS)
7538TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES)
7539//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND)  // XXX
7540TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK)
7541#endif
7542#endif
7543
7544/// ----------------------------------------------------------------------------
7545
7546static void
7547user_va0_disable(int operation)
7548{
7549	pid_t child, wpid;
7550#if defined(TWAIT_HAVE_STATUS)
7551	int status;
7552#endif
7553	const int sigval = SIGSTOP;
7554	int rv;
7555
7556	struct ptrace_siginfo info;
7557
7558	if (get_user_va0_disable() == 0)
7559		atf_tc_skip("vm.user_va0_disable is set to 0");
7560
7561	memset(&info, 0, sizeof(info));
7562
7563	DPRINTF("Before forking process PID=%d\n", getpid());
7564	SYSCALL_REQUIRE((child = fork()) != -1);
7565	if (child == 0) {
7566		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7567		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7568
7569		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7570		FORKEE_ASSERT(raise(sigval) == 0);
7571
7572		/* NOTREACHED */
7573		FORKEE_ASSERTX(0 && "This shall not be reached");
7574		__unreachable();
7575	}
7576	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7577
7578	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7579	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7580
7581	validate_status_stopped(status, sigval);
7582
7583	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
7584		"child\n");
7585	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
7586		sizeof(info)) != -1);
7587
7588	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
7589	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
7590		"si_errno=%#x\n",
7591		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
7592		info.psi_siginfo.si_errno);
7593
7594	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
7595	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
7596
7597	DPRINTF("Before resuming the child process in PC=0x0 "
7598	    "and without signal to be sent\n");
7599	errno = 0;
7600	rv = ptrace(operation, child, (void *)0, 0);
7601	ATF_REQUIRE_EQ(errno, EINVAL);
7602	ATF_REQUIRE_EQ(rv, -1);
7603
7604	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
7605
7606	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7607	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7608	validate_status_signaled(status, SIGKILL, 0);
7609
7610	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7611	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7612}
7613
7614#define USER_VA0_DISABLE(test, operation)				\
7615ATF_TC(test);								\
7616ATF_TC_HEAD(test, tc)							\
7617{									\
7618	atf_tc_set_md_var(tc, "descr",					\
7619	    "Verify behavior of " #operation " with PC set to 0x0");	\
7620}									\
7621									\
7622ATF_TC_BODY(test, tc)							\
7623{									\
7624									\
7625	user_va0_disable(operation);					\
7626}
7627
7628USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
7629USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
7630USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
7631
7632/// ----------------------------------------------------------------------------
7633
7634#include "t_ptrace_amd64_wait.h"
7635#include "t_ptrace_i386_wait.h"
7636#include "t_ptrace_x86_wait.h"
7637
7638ATF_TP_ADD_TCS(tp)
7639{
7640	setvbuf(stdout, NULL, _IONBF, 0);
7641	setvbuf(stderr, NULL, _IONBF, 0);
7642
7643	ATF_TP_ADD_TC(tp, traceme_raise1);
7644	ATF_TP_ADD_TC(tp, traceme_raise2);
7645	ATF_TP_ADD_TC(tp, traceme_raise3);
7646	ATF_TP_ADD_TC(tp, traceme_raise4);
7647	ATF_TP_ADD_TC(tp, traceme_raise5);
7648	ATF_TP_ADD_TC(tp, traceme_raise6);
7649	ATF_TP_ADD_TC(tp, traceme_raise7);
7650	ATF_TP_ADD_TC(tp, traceme_raise8);
7651	ATF_TP_ADD_TC(tp, traceme_raise9);
7652	ATF_TP_ADD_TC(tp, traceme_raise10);
7653
7654	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1);
7655	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2);
7656	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3);
7657	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4);
7658	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5);
7659	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6);
7660	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7);
7661	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8);
7662
7663	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1);
7664	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2);
7665	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3);
7666	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4);
7667	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5);
7668	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6);
7669	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7);
7670	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8);
7671
7672	ATF_TP_ADD_TC(tp, traceme_crash_trap);
7673	ATF_TP_ADD_TC(tp, traceme_crash_segv);
7674	ATF_TP_ADD_TC(tp, traceme_crash_ill);
7675	ATF_TP_ADD_TC(tp, traceme_crash_fpe);
7676	ATF_TP_ADD_TC(tp, traceme_crash_bus);
7677
7678	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap);
7679	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv);
7680	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill);
7681	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe);
7682	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus);
7683
7684	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap);
7685	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv);
7686	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill);
7687	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe);
7688	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus);
7689
7690	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1);
7691	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2);
7692	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3);
7693	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4);
7694	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5);
7695	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6);
7696	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7);
7697	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8);
7698
7699	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1);
7700	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2);
7701	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3);
7702	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4);
7703	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5);
7704	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6);
7705	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7);
7706	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8);
7707
7708	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1);
7709	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2);
7710	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3);
7711	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4);
7712	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5);
7713	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6);
7714	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7);
7715	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8);
7716
7717	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1);
7718	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2);
7719	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3);
7720	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4);
7721	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5);
7722	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6);
7723	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7);
7724	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8);
7725	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9);
7726	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10);
7727
7728	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
7729
7730	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
7731	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
7732	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
7733	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
7734	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
7735	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
7736	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
7737	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
7738	ATF_TP_ADD_TC(tp, traceme_vfork_raise9);
7739	ATF_TP_ADD_TC(tp, traceme_vfork_raise10);
7740	ATF_TP_ADD_TC(tp, traceme_vfork_raise11);
7741	ATF_TP_ADD_TC(tp, traceme_vfork_raise12);
7742	ATF_TP_ADD_TC(tp, traceme_vfork_raise13);
7743
7744	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap);
7745	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv);
7746	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill);
7747	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe);
7748	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus);
7749
7750	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap);
7751	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv);
7752	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill);
7753	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe);
7754	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus);
7755
7756	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap);
7757	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv);
7758	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill);
7759	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe);
7760	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus);
7761
7762	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
7763	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec);
7764	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec);
7765
7766	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap);
7767	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv);
7768	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill);
7769	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe);
7770	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus);
7771
7772	ATF_TP_ADD_TC_HAVE_PID(tp,
7773	    unrelated_tracer_sees_signalmasked_crash_trap);
7774	ATF_TP_ADD_TC_HAVE_PID(tp,
7775	    unrelated_tracer_sees_signalmasked_crash_segv);
7776	ATF_TP_ADD_TC_HAVE_PID(tp,
7777	    unrelated_tracer_sees_signalmasked_crash_ill);
7778	ATF_TP_ADD_TC_HAVE_PID(tp,
7779	    unrelated_tracer_sees_signalmasked_crash_fpe);
7780	ATF_TP_ADD_TC_HAVE_PID(tp,
7781	    unrelated_tracer_sees_signalmasked_crash_bus);
7782
7783	ATF_TP_ADD_TC_HAVE_PID(tp,
7784	    unrelated_tracer_sees_signalignored_crash_trap);
7785	ATF_TP_ADD_TC_HAVE_PID(tp,
7786	    unrelated_tracer_sees_signalignored_crash_segv);
7787	ATF_TP_ADD_TC_HAVE_PID(tp,
7788	    unrelated_tracer_sees_signalignored_crash_ill);
7789	ATF_TP_ADD_TC_HAVE_PID(tp,
7790	    unrelated_tracer_sees_signalignored_crash_fpe);
7791	ATF_TP_ADD_TC_HAVE_PID(tp,
7792	    unrelated_tracer_sees_signalignored_crash_bus);
7793
7794	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
7795	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
7796	ATF_TP_ADD_TC_HAVE_PID(tp,
7797		unrelated_tracer_sees_terminaton_before_the_parent);
7798	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
7799
7800	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
7801	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
7802
7803	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
7804	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
7805
7806	ATF_TP_ADD_TC_HAVE_PID(tp,
7807		tracee_sees_its_original_parent_getppid);
7808	ATF_TP_ADD_TC_HAVE_PID(tp,
7809		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
7810	ATF_TP_ADD_TC_HAVE_PID(tp,
7811		tracee_sees_its_original_parent_procfs_status);
7812
7813	ATF_TP_ADD_TC(tp, eventmask_preserved_empty);
7814	ATF_TP_ADD_TC(tp, eventmask_preserved_fork);
7815	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork);
7816	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done);
7817	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create);
7818	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit);
7819	ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn);
7820
7821	ATF_TP_ADD_TC(tp, fork1);
7822	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
7823	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
7824	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
7825	ATF_TP_ADD_TC(tp, fork5);
7826	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
7827	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
7828	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
7829	ATF_TP_ADD_TC(tp, fork9);
7830	ATF_TP_ADD_TC_HAVE_PID(tp, fork10);
7831	ATF_TP_ADD_TC_HAVE_PID(tp, fork11);
7832	ATF_TP_ADD_TC_HAVE_PID(tp, fork12);
7833	ATF_TP_ADD_TC(tp, fork13);
7834	ATF_TP_ADD_TC_HAVE_PID(tp, fork14);
7835	ATF_TP_ADD_TC_HAVE_PID(tp, fork15);
7836	ATF_TP_ADD_TC_HAVE_PID(tp, fork16);
7837
7838#if TEST_VFORK_ENABLED
7839	ATF_TP_ADD_TC(tp, vfork1);
7840	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
7841	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
7842	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
7843	ATF_TP_ADD_TC(tp, vfork5);
7844	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
7845	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
7846	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
7847	ATF_TP_ADD_TC(tp, vfork9);
7848	ATF_TP_ADD_TC_HAVE_PID(tp, vfork10);
7849	ATF_TP_ADD_TC_HAVE_PID(tp, vfork11);
7850	ATF_TP_ADD_TC_HAVE_PID(tp, vfork12);
7851	ATF_TP_ADD_TC(tp, vfork13);
7852	ATF_TP_ADD_TC_HAVE_PID(tp, vfork14);
7853	ATF_TP_ADD_TC_HAVE_PID(tp, vfork15);
7854	ATF_TP_ADD_TC_HAVE_PID(tp, vfork16);
7855#endif
7856
7857	ATF_TP_ADD_TC(tp, posix_spawn1);
7858	ATF_TP_ADD_TC(tp, posix_spawn2);
7859	ATF_TP_ADD_TC(tp, posix_spawn3);
7860	ATF_TP_ADD_TC(tp, posix_spawn4);
7861	ATF_TP_ADD_TC(tp, posix_spawn5);
7862	ATF_TP_ADD_TC(tp, posix_spawn6);
7863	ATF_TP_ADD_TC(tp, posix_spawn7);
7864	ATF_TP_ADD_TC(tp, posix_spawn8);
7865	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9);
7866	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10);
7867	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11);
7868	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12);
7869	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13);
7870	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14);
7871	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15);
7872	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16);
7873
7874	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner);
7875	ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker);
7876#if TEST_VFORK_ENABLED
7877	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker);
7878	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone);
7879#endif
7880
7881	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner);
7882	ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker);
7883#if TEST_VFORK_ENABLED
7884	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker);
7885	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone);
7886#endif
7887
7888#if TEST_VFORK_ENABLED
7889	ATF_TP_ADD_TC(tp, traceme_vfork_fork);
7890	ATF_TP_ADD_TC(tp, traceme_vfork_vfork);
7891#endif
7892
7893	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8);
7894	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16);
7895	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32);
7896	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64);
7897
7898	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8);
7899	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16);
7900	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32);
7901	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64);
7902
7903	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8);
7904	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16);
7905	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32);
7906	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64);
7907
7908	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8);
7909	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16);
7910	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32);
7911	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64);
7912
7913	ATF_TP_ADD_TC(tp, bytes_transfer_read_d);
7914	ATF_TP_ADD_TC(tp, bytes_transfer_read_i);
7915	ATF_TP_ADD_TC(tp, bytes_transfer_write_d);
7916	ATF_TP_ADD_TC(tp, bytes_transfer_write_i);
7917
7918	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text);
7919	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text);
7920	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text);
7921	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text);
7922
7923	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text);
7924	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text);
7925	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text);
7926	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text);
7927
7928	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text);
7929	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text);
7930	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text);
7931	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text);
7932
7933	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text);
7934	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text);
7935	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text);
7936	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text);
7937
7938	ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text);
7939	ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text);
7940	ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text);
7941	ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text);
7942
7943	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv);
7944
7945	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i);
7946	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d);
7947	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i);
7948	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d);
7949
7950	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i);
7951	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d);
7952	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i);
7953	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d);
7954
7955	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv);
7956
7957	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i);
7958	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d);
7959	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i);
7960	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d);
7961
7962	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i);
7963	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d);
7964	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i);
7965	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d);
7966
7967	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1);
7968	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2);
7969	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3);
7970	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4);
7971	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5);
7972	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6);
7973
7974	ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1);
7975	ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2);
7976
7977	ATF_TP_ADD_TC_PT_STEP(tp, step1);
7978	ATF_TP_ADD_TC_PT_STEP(tp, step2);
7979	ATF_TP_ADD_TC_PT_STEP(tp, step3);
7980	ATF_TP_ADD_TC_PT_STEP(tp, step4);
7981
7982	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
7983	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
7984	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
7985	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
7986
7987	ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked);
7988	ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored);
7989
7990	ATF_TP_ADD_TC(tp, kill1);
7991	ATF_TP_ADD_TC(tp, kill2);
7992	ATF_TP_ADD_TC(tp, kill3);
7993
7994	ATF_TP_ADD_TC(tp, traceme_lwpinfo0);
7995	ATF_TP_ADD_TC(tp, traceme_lwpinfo1);
7996	ATF_TP_ADD_TC(tp, traceme_lwpinfo2);
7997	ATF_TP_ADD_TC(tp, traceme_lwpinfo3);
7998
7999	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0);
8000	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1);
8001	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2);
8002	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3);
8003
8004	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
8005	ATF_TP_ADD_TC(tp, siginfo_set_faked);
8006
8007	ATF_TP_ADD_TC(tp, traceme_exec);
8008	ATF_TP_ADD_TC(tp, traceme_signalmasked_exec);
8009	ATF_TP_ADD_TC(tp, traceme_signalignored_exec);
8010
8011	ATF_TP_ADD_TC(tp, trace_thread_nolwpevents);
8012	ATF_TP_ADD_TC(tp, trace_thread_lwpexit);
8013	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate);
8014	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit);
8015
8016	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
8017
8018	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked);
8019	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored);
8020	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked);
8021	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored);
8022#if TEST_VFORK_ENABLED
8023	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked);
8024	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored);
8025	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked);
8026	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored);
8027#endif
8028
8029	ATF_TP_ADD_TC(tp, signal9);
8030	ATF_TP_ADD_TC(tp, signal10);
8031
8032	ATF_TP_ADD_TC(tp, suspend1);
8033	ATF_TP_ADD_TC(tp, suspend2);
8034
8035	ATF_TP_ADD_TC(tp, resume1);
8036
8037	ATF_TP_ADD_TC(tp, syscall1);
8038
8039	ATF_TP_ADD_TC(tp, syscallemu1);
8040
8041	ATF_TP_ADD_TC(tp, clone1);
8042	ATF_TP_ADD_TC_HAVE_PID(tp, clone2);
8043	ATF_TP_ADD_TC_HAVE_PID(tp, clone3);
8044	ATF_TP_ADD_TC_HAVE_PID(tp, clone4);
8045	ATF_TP_ADD_TC(tp, clone5);
8046	ATF_TP_ADD_TC_HAVE_PID(tp, clone6);
8047	ATF_TP_ADD_TC_HAVE_PID(tp, clone7);
8048	ATF_TP_ADD_TC_HAVE_PID(tp, clone8);
8049
8050	ATF_TP_ADD_TC(tp, clone_vm1);
8051	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2);
8052	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3);
8053	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4);
8054	ATF_TP_ADD_TC(tp, clone_vm5);
8055	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6);
8056	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7);
8057	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8);
8058
8059	ATF_TP_ADD_TC(tp, clone_fs1);
8060	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2);
8061	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3);
8062	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4);
8063	ATF_TP_ADD_TC(tp, clone_fs5);
8064	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6);
8065	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7);
8066	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8);
8067
8068	ATF_TP_ADD_TC(tp, clone_files1);
8069	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2);
8070	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3);
8071	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4);
8072	ATF_TP_ADD_TC(tp, clone_files5);
8073	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6);
8074	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7);
8075	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8);
8076
8077//	ATF_TP_ADD_TC(tp, clone_sighand1); // XXX
8078//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX
8079//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX
8080//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX
8081//	ATF_TP_ADD_TC(tp, clone_sighand5); // XXX
8082//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX
8083//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX
8084//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX
8085
8086#if TEST_VFORK_ENABLED
8087	ATF_TP_ADD_TC(tp, clone_vfork1);
8088	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2);
8089	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3);
8090	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4);
8091	ATF_TP_ADD_TC(tp, clone_vfork5);
8092	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6);
8093	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7);
8094	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8);
8095#endif
8096
8097	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored);
8098	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked);
8099	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored);
8100	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked);
8101	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored);
8102	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked);
8103	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored);
8104	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked);
8105//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX
8106//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX
8107#if TEST_VFORK_ENABLED
8108	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored);
8109	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked);
8110#endif
8111
8112#if TEST_VFORK_ENABLED
8113	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone);
8114	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm);
8115	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs);
8116	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files);
8117//	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX
8118	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork);
8119#endif
8120
8121	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
8122	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
8123	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
8124
8125	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
8126	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
8127	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
8128
8129	return atf_no_error();
8130}
8131