t_ptrace_wait.c revision 1.93
1/*	$NetBSD: t_ptrace_wait.c,v 1.93 2019/02/20 05:20:05 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.93 2019/02/20 05:20:05 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 <stdint.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <strings.h>
53#include <time.h>
54#include <unistd.h>
55
56#include <atf-c.h>
57
58#include "h_macros.h"
59
60#include "t_ptrace_wait.h"
61#include "msg.h"
62
63#define PARENT_TO_CHILD(info, fds, msg) \
64    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, \
65	sizeof(msg)) == 0)
66
67#define CHILD_FROM_PARENT(info, fds, msg) \
68    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, \
69	sizeof(msg)) == 0)
70
71#define CHILD_TO_PARENT(info, fds, msg) \
72    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, \
73	sizeof(msg)) == 0)
74
75#define PARENT_FROM_CHILD(info, fds, msg) \
76    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, \
77	sizeof(msg)) == 0)
78
79#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
80    strerror(errno))
81#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
82    "%d(%s) != %d", res, strerror(res), exp)
83
84static int debug = 0;
85
86#define DPRINTF(a, ...)	do  \
87	if (debug) printf(a,  ##__VA_ARGS__); \
88    while (/*CONSTCOND*/0)
89
90/// ----------------------------------------------------------------------------
91
92static void
93traceme_raise(int sigval)
94{
95	const int exitval = 5;
96	pid_t child, wpid;
97#if defined(TWAIT_HAVE_STATUS)
98	int status;
99#endif
100
101	struct ptrace_siginfo info;
102	memset(&info, 0, sizeof(info));
103
104	DPRINTF("Before forking process PID=%d\n", getpid());
105	SYSCALL_REQUIRE((child = fork()) != -1);
106	if (child == 0) {
107		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
108		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
109
110		DPRINTF("Before raising %s from child\n", strsignal(sigval));
111		FORKEE_ASSERT(raise(sigval) == 0);
112
113		switch (sigval) {
114		case SIGKILL:
115			/* NOTREACHED */
116			FORKEE_ASSERTX(0 && "This shall not be reached");
117			__unreachable();
118		default:
119			DPRINTF("Before exiting of the child process\n");
120			_exit(exitval);
121		}
122	}
123	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
124
125	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
126	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
127
128	switch (sigval) {
129	case SIGKILL:
130		validate_status_signaled(status, sigval, 0);
131		break;
132	default:
133		validate_status_stopped(status, sigval);
134
135		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
136			"child\n");
137		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
138			sizeof(info)) != -1);
139
140		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
141		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
142			"si_errno=%#x\n",
143			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
144			info.psi_siginfo.si_errno);
145
146		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
147		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
148
149		DPRINTF("Before resuming the child process where it left off "
150		    "and without signal to be sent\n");
151		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
152
153		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
154		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
155		    child);
156		break;
157	}
158
159	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
160	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
161}
162
163#define TRACEME_RAISE(test, sig)					\
164ATF_TC(test);								\
165ATF_TC_HEAD(test, tc)							\
166{									\
167	atf_tc_set_md_var(tc, "descr",					\
168	    "Verify " #sig " followed by _exit(2) in a child");		\
169}									\
170									\
171ATF_TC_BODY(test, tc)							\
172{									\
173									\
174	traceme_raise(sig);						\
175}
176
177TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
178TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
179TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
180TRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
181TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
182TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */
183TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */
184TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */
185TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */
186TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */
187
188/// ----------------------------------------------------------------------------
189
190static void
191traceme_raisesignal_ignored(int sigignored)
192{
193	const int exitval = 5;
194	const int sigval = SIGSTOP;
195	pid_t child, wpid;
196	struct sigaction sa;
197#if defined(TWAIT_HAVE_STATUS)
198	int status;
199#endif
200	struct ptrace_siginfo info;
201
202	memset(&info, 0, sizeof(info));
203
204	DPRINTF("Before forking process PID=%d\n", getpid());
205	SYSCALL_REQUIRE((child = fork()) != -1);
206	if (child == 0) {
207		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
208		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
209
210		memset(&sa, 0, sizeof(sa));
211		sa.sa_handler = SIG_IGN;
212		sigemptyset(&sa.sa_mask);
213		FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1);
214
215		DPRINTF("Before raising %s from child\n", strsignal(sigval));
216		FORKEE_ASSERT(raise(sigval) == 0);
217
218		DPRINTF("Before raising %s from child\n",
219		    strsignal(sigignored));
220		FORKEE_ASSERT(raise(sigignored) == 0);
221
222		DPRINTF("Before exiting of the child process\n");
223		_exit(exitval);
224	}
225	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
226
227	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
228	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
229
230	validate_status_stopped(status, sigval);
231
232	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
233	SYSCALL_REQUIRE(
234	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
235
236	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
237	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
238	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
239	    info.psi_siginfo.si_errno);
240
241	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
242	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
243
244	DPRINTF("Before resuming the child process where it left off and "
245	    "without signal to be sent\n");
246	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
247
248	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
249	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
250
251	validate_status_stopped(status, sigignored);
252
253	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
254	SYSCALL_REQUIRE(
255	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
256
257	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
258	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
259	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
260	    info.psi_siginfo.si_errno);
261
262	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored);
263	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
264
265	DPRINTF("Before resuming the child process where it left off and "
266	    "without signal to be sent\n");
267	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
268
269	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
270	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
271
272	validate_status_exited(status, exitval);
273
274	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
275	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
276}
277
278#define TRACEME_RAISESIGNAL_IGNORED(test, sig)				\
279ATF_TC(test);								\
280ATF_TC_HEAD(test, tc)							\
281{									\
282	atf_tc_set_md_var(tc, "descr",					\
283	    "Verify that ignoring (with SIG_IGN) " #sig " in tracee "	\
284	    "does not stop tracer from catching this raised signal");	\
285}									\
286									\
287ATF_TC_BODY(test, tc)							\
288{									\
289									\
290	traceme_raisesignal_ignored(sig);				\
291}
292
293// A signal handler for SIGKILL and SIGSTOP cannot be ignored.
294TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */
295TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP)  /* hangup */
296TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */
297TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */
298TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */
299TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */
300TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */
301TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */
302
303/// ----------------------------------------------------------------------------
304
305static void
306traceme_raisesignal_masked(int sigmasked)
307{
308	const int exitval = 5;
309	const int sigval = SIGSTOP;
310	pid_t child, wpid;
311#if defined(TWAIT_HAVE_STATUS)
312	int status;
313#endif
314	sigset_t intmask;
315	struct ptrace_siginfo info;
316
317	memset(&info, 0, sizeof(info));
318
319	DPRINTF("Before forking process PID=%d\n", getpid());
320	SYSCALL_REQUIRE((child = fork()) != -1);
321	if (child == 0) {
322		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
323		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
324
325		sigemptyset(&intmask);
326		sigaddset(&intmask, sigmasked);
327		sigprocmask(SIG_BLOCK, &intmask, NULL);
328
329		DPRINTF("Before raising %s from child\n", strsignal(sigval));
330		FORKEE_ASSERT(raise(sigval) == 0);
331
332		DPRINTF("Before raising %s breakpoint from child\n",
333		    strsignal(sigmasked));
334		FORKEE_ASSERT(raise(sigmasked) == 0);
335
336		DPRINTF("Before exiting of the child process\n");
337		_exit(exitval);
338	}
339	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
340
341	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
342	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
343
344	validate_status_stopped(status, sigval);
345
346	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
347	SYSCALL_REQUIRE(
348	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
349
350	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
351	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
352	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
353	    info.psi_siginfo.si_errno);
354
355	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
356	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
357
358	DPRINTF("Before resuming the child process where it left off and "
359	    "without signal to be sent\n");
360	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
361
362	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
363	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
364
365	validate_status_exited(status, exitval);
366
367	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
368	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
369}
370
371#define TRACEME_RAISESIGNAL_MASKED(test, sig)				\
372ATF_TC(test);								\
373ATF_TC_HEAD(test, tc)							\
374{									\
375	atf_tc_set_md_var(tc, "descr",					\
376	    "Verify that masking (with SIG_BLOCK) " #sig " in tracee "	\
377	    "stops tracer from catching this raised signal");		\
378}									\
379									\
380ATF_TC_BODY(test, tc)							\
381{									\
382									\
383	traceme_raisesignal_masked(sig);				\
384}
385
386// A signal handler for SIGKILL and SIGSTOP cannot be masked.
387TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */
388TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP)  /* hangup */
389TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */
390TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */
391TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */
392TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */
393TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */
394TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */
395
396/// ----------------------------------------------------------------------------
397
398static void
399traceme_crash(int sig)
400{
401	pid_t child, wpid;
402#if defined(TWAIT_HAVE_STATUS)
403	int status;
404#endif
405	struct ptrace_siginfo info;
406
407#ifndef PTRACE_ILLEGAL_ASM
408	if (sig == SIGILL)
409		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
410#endif
411
412	memset(&info, 0, sizeof(info));
413
414	DPRINTF("Before forking process PID=%d\n", getpid());
415	SYSCALL_REQUIRE((child = fork()) != -1);
416	if (child == 0) {
417		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
418		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
419
420		DPRINTF("Before executing a trap\n");
421		switch (sig) {
422		case SIGTRAP:
423			trigger_trap();
424			break;
425		case SIGSEGV:
426			trigger_segv();
427			break;
428		case SIGILL:
429			trigger_ill();
430			break;
431		case SIGFPE:
432			trigger_fpe();
433			break;
434		case SIGBUS:
435			trigger_bus();
436			break;
437		default:
438			/* NOTREACHED */
439			FORKEE_ASSERTX(0 && "This shall not be reached");
440		}
441
442		/* NOTREACHED */
443		FORKEE_ASSERTX(0 && "This shall not be reached");
444	}
445	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
446
447	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
448	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
449
450	validate_status_stopped(status, sig);
451
452	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
453	SYSCALL_REQUIRE(
454	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
455
456	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
457	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
458	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
459	    info.psi_siginfo.si_errno);
460
461	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
462	switch (sig) {
463	case SIGTRAP:
464		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
465		break;
466	case SIGSEGV:
467		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
468		break;
469	case SIGILL:
470		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC);
471		break;
472	case SIGFPE:
473		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
474		break;
475	case SIGBUS:
476		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
477		break;
478	}
479
480	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
481
482	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
483	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
484
485	validate_status_signaled(status, SIGKILL, 0);
486
487	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
488	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
489}
490
491#define TRACEME_CRASH(test, sig)					\
492ATF_TC(test);								\
493ATF_TC_HEAD(test, tc)							\
494{									\
495	atf_tc_set_md_var(tc, "descr",					\
496	    "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \
497}									\
498									\
499ATF_TC_BODY(test, tc)							\
500{									\
501									\
502	traceme_crash(sig);						\
503}
504
505TRACEME_CRASH(traceme_crash_trap, SIGTRAP)
506TRACEME_CRASH(traceme_crash_segv, SIGSEGV)
507TRACEME_CRASH(traceme_crash_ill, SIGILL)
508TRACEME_CRASH(traceme_crash_fpe, SIGFPE)
509TRACEME_CRASH(traceme_crash_bus, SIGBUS)
510
511/// ----------------------------------------------------------------------------
512
513static void
514traceme_signalmasked_crash(int sig)
515{
516	const int sigval = SIGSTOP;
517	pid_t child, wpid;
518#if defined(TWAIT_HAVE_STATUS)
519	int status;
520#endif
521	struct ptrace_siginfo info;
522	sigset_t intmask;
523	struct kinfo_proc2 kp;
524	size_t len = sizeof(kp);
525
526	int name[6];
527	const size_t namelen = __arraycount(name);
528	ki_sigset_t kp_sigmask;
529
530#ifndef PTRACE_ILLEGAL_ASM
531	if (sig == SIGILL)
532		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
533#endif
534
535	memset(&info, 0, sizeof(info));
536
537	atf_tc_expect_fail("Unexpected sigmask reset on crash under debugger");
538
539	DPRINTF("Before forking process PID=%d\n", getpid());
540	SYSCALL_REQUIRE((child = fork()) != -1);
541	if (child == 0) {
542		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
543		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
544
545		sigemptyset(&intmask);
546		sigaddset(&intmask, sig);
547		sigprocmask(SIG_BLOCK, &intmask, NULL);
548
549		DPRINTF("Before raising %s from child\n", strsignal(sigval));
550		FORKEE_ASSERT(raise(sigval) == 0);
551
552		DPRINTF("Before executing a trap\n");
553		switch (sig) {
554		case SIGTRAP:
555			trigger_trap();
556			break;
557		case SIGSEGV:
558			trigger_segv();
559			break;
560		case SIGILL:
561			trigger_ill();
562			break;
563		case SIGFPE:
564			trigger_fpe();
565			break;
566		case SIGBUS:
567			trigger_bus();
568			break;
569		default:
570			/* NOTREACHED */
571			FORKEE_ASSERTX(0 && "This shall not be reached");
572		}
573
574		/* NOTREACHED */
575		FORKEE_ASSERTX(0 && "This shall not be reached");
576	}
577	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
578
579	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
580	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
581
582	validate_status_stopped(status, sigval);
583
584	name[0] = CTL_KERN,
585	name[1] = KERN_PROC2,
586	name[2] = KERN_PROC_PID;
587	name[3] = child;
588	name[4] = sizeof(kp);
589	name[5] = 1;
590
591	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
592
593	kp_sigmask = kp.p_sigmask;
594
595	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
596	SYSCALL_REQUIRE(
597	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
598
599	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
600	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
601	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
602	    info.psi_siginfo.si_errno);
603
604	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
605	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
606
607	DPRINTF("Before resuming the child process where it left off and "
608	    "without signal to be sent\n");
609	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
610
611	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
612	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
613
614	validate_status_stopped(status, sig);
615
616	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
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(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
626
627	DPRINTF("kp_sigmask="
628	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
629	    kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2],
630	    kp_sigmask.__bits[3]);
631
632	DPRINTF("kp.p_sigmask="
633	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
634	    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
635	    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
636
637	ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask)));
638
639	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
640	switch (sig) {
641	case SIGTRAP:
642		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
643		break;
644	case SIGSEGV:
645		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
646		break;
647	case SIGILL:
648		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC);
649		break;
650	case SIGFPE:
651		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
652		break;
653	case SIGBUS:
654		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
655		break;
656	}
657
658	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
659
660	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
661	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
662
663	validate_status_signaled(status, SIGKILL, 0);
664
665	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
666	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
667}
668
669#define TRACEME_SIGNALMASKED_CRASH(test, sig)				\
670ATF_TC(test);								\
671ATF_TC_HEAD(test, tc)							\
672{									\
673	atf_tc_set_md_var(tc, "descr",					\
674	    "Verify masked crash signal " #sig " in a child after "	\
675	    "PT_TRACE_ME is delivered to its tracer");			\
676}									\
677									\
678ATF_TC_BODY(test, tc)							\
679{									\
680									\
681	traceme_signalmasked_crash(sig);				\
682}
683
684TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP)
685TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV)
686TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL)
687TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE)
688TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS)
689
690/// ----------------------------------------------------------------------------
691
692static void
693traceme_signalignored_crash(int sig)
694{
695	const int sigval = SIGSTOP;
696	pid_t child, wpid;
697#if defined(TWAIT_HAVE_STATUS)
698	int status;
699#endif
700	struct sigaction sa;
701	struct ptrace_siginfo info;
702	struct kinfo_proc2 kp;
703	size_t len = sizeof(kp);
704
705	int name[6];
706	const size_t namelen = __arraycount(name);
707	ki_sigset_t kp_sigignore;
708
709#ifndef PTRACE_ILLEGAL_ASM
710	if (sig == SIGILL)
711		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
712#endif
713
714	atf_tc_expect_fail("Unexpected sigmask reset on crash under debugger");
715
716	memset(&info, 0, sizeof(info));
717
718	DPRINTF("Before forking process PID=%d\n", getpid());
719	SYSCALL_REQUIRE((child = fork()) != -1);
720	if (child == 0) {
721		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
722		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
723
724		memset(&sa, 0, sizeof(sa));
725		sa.sa_handler = SIG_IGN;
726		sigemptyset(&sa.sa_mask);
727
728		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
729
730		DPRINTF("Before raising %s from child\n", strsignal(sigval));
731		FORKEE_ASSERT(raise(sigval) == 0);
732
733		DPRINTF("Before executing a trap\n");
734		switch (sig) {
735		case SIGTRAP:
736			trigger_trap();
737			break;
738		case SIGSEGV:
739			trigger_segv();
740			break;
741		case SIGILL:
742			trigger_ill();
743			break;
744		case SIGFPE:
745			trigger_fpe();
746			break;
747		case SIGBUS:
748			trigger_bus();
749			break;
750		default:
751			/* NOTREACHED */
752			FORKEE_ASSERTX(0 && "This shall not be reached");
753		}
754
755		/* NOTREACHED */
756		FORKEE_ASSERTX(0 && "This shall not be reached");
757	}
758	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
759
760	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
761	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
762
763	validate_status_stopped(status, sigval);
764
765	name[0] = CTL_KERN,
766	name[1] = KERN_PROC2,
767	name[2] = KERN_PROC_PID;
768	name[3] = child;
769	name[4] = sizeof(kp);
770	name[5] = 1;
771
772	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
773
774	kp_sigignore = kp.p_sigignore;
775
776	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
777	SYSCALL_REQUIRE(
778	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
779
780	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
781	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
782	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
783	    info.psi_siginfo.si_errno);
784
785	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
786	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
787
788	DPRINTF("Before resuming the child process where it left off and "
789	    "without signal to be sent\n");
790	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
791
792	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
793	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
794
795	validate_status_stopped(status, sig);
796
797	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
798	SYSCALL_REQUIRE(
799	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
800
801	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
802	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
803	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
804	    info.psi_siginfo.si_errno);
805
806	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
807
808	DPRINTF("kp_sigignore="
809	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
810	    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
811	    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
812
813	DPRINTF("kp.p_sigignore="
814	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
815	    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
816	    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
817
818	ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore)));
819
820	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
821	switch (sig) {
822	case SIGTRAP:
823		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
824		break;
825	case SIGSEGV:
826		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
827		break;
828	case SIGILL:
829		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC);
830		break;
831	case SIGFPE:
832		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
833		break;
834	case SIGBUS:
835		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
836		break;
837	}
838
839	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
840
841	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
842	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
843
844	validate_status_signaled(status, SIGKILL, 0);
845
846	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
847	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
848}
849
850#define TRACEME_SIGNALIGNORED_CRASH(test, sig)				\
851ATF_TC(test);								\
852ATF_TC_HEAD(test, tc)							\
853{									\
854	atf_tc_set_md_var(tc, "descr",					\
855	    "Verify ignored crash signal " #sig " in a child after "	\
856	    "PT_TRACE_ME is delivered to its tracer"); 			\
857}									\
858									\
859ATF_TC_BODY(test, tc)							\
860{									\
861									\
862	traceme_signalignored_crash(sig);				\
863}
864
865TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP)
866TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV)
867TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL)
868TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE)
869TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS)
870
871/// ----------------------------------------------------------------------------
872
873static void
874traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught)
875{
876	const int exitval = 5;
877	const int sigval = SIGSTOP;
878	pid_t child, wpid;
879	struct sigaction sa;
880#if defined(TWAIT_HAVE_STATUS)
881	int status;
882#endif
883	struct ptrace_siginfo info;
884
885	memset(&info, 0, sizeof(info));
886
887	DPRINTF("Before forking process PID=%d\n", getpid());
888	SYSCALL_REQUIRE((child = fork()) != -1);
889	if (child == 0) {
890		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
891		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
892
893		sa.sa_handler = sah;
894		sa.sa_flags = SA_SIGINFO;
895		sigemptyset(&sa.sa_mask);
896
897		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
898
899		DPRINTF("Before raising %s from child\n", strsignal(sigval));
900		FORKEE_ASSERT(raise(sigval) == 0);
901
902		FORKEE_ASSERT_EQ(*traceme_caught, 1);
903
904		DPRINTF("Before exiting of the child process\n");
905		_exit(exitval);
906	}
907	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
908
909	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
910	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
911
912	validate_status_stopped(status, sigval);
913
914	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
915	SYSCALL_REQUIRE(
916	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
917
918	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
919	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
920	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
921	    info.psi_siginfo.si_errno);
922
923	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
924	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
925
926	DPRINTF("Before resuming the child process where it left off and with "
927	    "signal %s to be sent\n", strsignal(sigsent));
928	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
929
930	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
931	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
932
933	validate_status_exited(status, exitval);
934
935	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
936	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
937}
938
939#define TRACEME_SENDSIGNAL_HANDLE(test, sig)				\
940ATF_TC(test);								\
941ATF_TC_HEAD(test, tc)							\
942{									\
943	atf_tc_set_md_var(tc, "descr",					\
944	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
945	    "handled correctly and caught by a signal handler");	\
946}									\
947									\
948static int test##_caught = 0;						\
949									\
950static void								\
951test##_sighandler(int arg)						\
952{									\
953	FORKEE_ASSERT_EQ(arg, sig);					\
954									\
955	++ test##_caught;						\
956}									\
957									\
958ATF_TC_BODY(test, tc)							\
959{									\
960									\
961	traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \
962}
963
964// A signal handler for SIGKILL and SIGSTOP cannot be registered.
965TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */
966TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP)  /* hangup */
967TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */
968TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */
969TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */
970TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */
971TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */
972TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */
973
974/// ----------------------------------------------------------------------------
975
976static void
977traceme_sendsignal_masked(int sigsent)
978{
979	const int exitval = 5;
980	const int sigval = SIGSTOP;
981	pid_t child, wpid;
982	sigset_t set;
983#if defined(TWAIT_HAVE_STATUS)
984	int status;
985#endif
986	struct ptrace_siginfo info;
987
988	memset(&info, 0, sizeof(info));
989
990	DPRINTF("Before forking process PID=%d\n", getpid());
991	SYSCALL_REQUIRE((child = fork()) != -1);
992	if (child == 0) {
993		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
994		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
995
996		sigemptyset(&set);
997		sigaddset(&set, sigsent);
998		FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
999
1000		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1001		FORKEE_ASSERT(raise(sigval) == 0);
1002
1003		_exit(exitval);
1004	}
1005	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1006
1007	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1008	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1009
1010	validate_status_stopped(status, sigval);
1011
1012	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1013	SYSCALL_REQUIRE(
1014	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1015
1016	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1017	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1018	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1019	    info.psi_siginfo.si_errno);
1020
1021	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1022	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1023
1024	DPRINTF("Before resuming the child process where it left off and with "
1025	    "signal %s to be sent\n", strsignal(sigsent));
1026	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1027
1028	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1029	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1030
1031	validate_status_exited(status, exitval);
1032
1033	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1034	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1035}
1036
1037#define TRACEME_SENDSIGNAL_MASKED(test, sig)				\
1038ATF_TC(test);								\
1039ATF_TC_HEAD(test, tc)							\
1040{									\
1041	atf_tc_set_md_var(tc, "descr",					\
1042	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1043	    "handled correctly and the signal is masked by SIG_BLOCK");	\
1044}									\
1045									\
1046ATF_TC_BODY(test, tc)							\
1047{									\
1048									\
1049	traceme_sendsignal_masked(sig);					\
1050}
1051
1052// A signal handler for SIGKILL and SIGSTOP cannot be masked.
1053TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */
1054TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP)  /* hangup */
1055TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */
1056TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */
1057TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */
1058TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */
1059TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */
1060TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */
1061
1062/// ----------------------------------------------------------------------------
1063
1064static void
1065traceme_sendsignal_ignored(int sigsent)
1066{
1067	const int exitval = 5;
1068	const int sigval = SIGSTOP;
1069	pid_t child, wpid;
1070	struct sigaction sa;
1071#if defined(TWAIT_HAVE_STATUS)
1072	int status;
1073#endif
1074	struct ptrace_siginfo info;
1075
1076	memset(&info, 0, sizeof(info));
1077
1078	DPRINTF("Before forking process PID=%d\n", getpid());
1079	SYSCALL_REQUIRE((child = fork()) != -1);
1080	if (child == 0) {
1081		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1082
1083		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1084
1085		memset(&sa, 0, sizeof(sa));
1086		sa.sa_handler = SIG_IGN;
1087		sigemptyset(&sa.sa_mask);
1088		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1089
1090		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1091		FORKEE_ASSERT(raise(sigval) == 0);
1092
1093		_exit(exitval);
1094	}
1095	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1096
1097	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1098	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1099
1100	validate_status_stopped(status, sigval);
1101
1102	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1103	SYSCALL_REQUIRE(
1104	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1105
1106	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1107	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1108	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1109	    info.psi_siginfo.si_errno);
1110
1111	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1112	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1113
1114	DPRINTF("Before resuming the child process where it left off and with "
1115	    "signal %s to be sent\n", strsignal(sigsent));
1116	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1117
1118	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1119	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1120
1121	validate_status_exited(status, exitval);
1122
1123	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1124	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1125}
1126
1127#define TRACEME_SENDSIGNAL_IGNORED(test, sig)				\
1128ATF_TC(test);								\
1129ATF_TC_HEAD(test, tc)							\
1130{									\
1131	atf_tc_set_md_var(tc, "descr",					\
1132	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1133	    "handled correctly and the signal is masked by SIG_IGN");	\
1134}									\
1135									\
1136ATF_TC_BODY(test, tc)							\
1137{									\
1138									\
1139	traceme_sendsignal_ignored(sig);				\
1140}
1141
1142// A signal handler for SIGKILL and SIGSTOP cannot be ignored.
1143TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */
1144TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP)  /* hangup */
1145TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */
1146TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */
1147TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */
1148TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */
1149TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */
1150TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */
1151
1152/// ----------------------------------------------------------------------------
1153
1154static void
1155traceme_sendsignal_simple(int sigsent)
1156{
1157	const int sigval = SIGSTOP;
1158	int exitval = 0;
1159	pid_t child, wpid;
1160#if defined(TWAIT_HAVE_STATUS)
1161	int status;
1162	int expect_core;
1163
1164	switch (sigsent) {
1165	case SIGABRT:
1166	case SIGTRAP:
1167	case SIGBUS:
1168	case SIGILL:
1169	case SIGFPE:
1170	case SIGSEGV:
1171		expect_core = 1;
1172		break;
1173	default:
1174		expect_core = 0;
1175		break;
1176	}
1177#endif
1178	struct ptrace_siginfo info;
1179
1180	memset(&info, 0, sizeof(info));
1181
1182	DPRINTF("Before forking process PID=%d\n", getpid());
1183	SYSCALL_REQUIRE((child = fork()) != -1);
1184	if (child == 0) {
1185		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1186		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1187
1188		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1189		FORKEE_ASSERT(raise(sigval) == 0);
1190
1191		switch (sigsent) {
1192		case SIGCONT:
1193		case SIGSTOP:
1194			_exit(exitval);
1195		default:
1196			/* NOTREACHED */
1197			FORKEE_ASSERTX(0 && "This shall not be reached");
1198		}
1199	}
1200	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1201
1202	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1203	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1204
1205	validate_status_stopped(status, sigval);
1206
1207	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1208	SYSCALL_REQUIRE(
1209	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1210
1211	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1212	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1213	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1214	    info.psi_siginfo.si_errno);
1215
1216	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1217	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1218
1219	DPRINTF("Before resuming the child process where it left off and with "
1220	    "signal %s to be sent\n", strsignal(sigsent));
1221	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1222
1223	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1224	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1225
1226	switch (sigsent) {
1227	case SIGSTOP:
1228		validate_status_stopped(status, sigsent);
1229		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1230		    "child\n");
1231		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1232		    sizeof(info)) != -1);
1233
1234		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1235		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1236		    "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 "
1244		    "and with signal %s to be sent\n", strsignal(sigsent));
1245		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1246
1247		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1248		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1249		    child);
1250		/* FALLTHROUGH */
1251	case SIGCONT:
1252		validate_status_exited(status, exitval);
1253		break;
1254	default:
1255		validate_status_signaled(status, sigsent, expect_core);
1256		break;
1257	}
1258
1259	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1260	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1261}
1262
1263#define TRACEME_SENDSIGNAL_SIMPLE(test, sig)				\
1264ATF_TC(test);								\
1265ATF_TC_HEAD(test, tc)							\
1266{									\
1267	atf_tc_set_md_var(tc, "descr",					\
1268	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1269	    "handled correctly in a child without a signal handler");	\
1270}									\
1271									\
1272ATF_TC_BODY(test, tc)							\
1273{									\
1274									\
1275	traceme_sendsignal_simple(sig);					\
1276}
1277
1278TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/
1279TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/
1280TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */
1281TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP)  /* hangup */
1282TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */
1283TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */
1284TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */
1285TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */
1286TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */
1287TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */
1288
1289/// ----------------------------------------------------------------------------
1290
1291ATF_TC(traceme_pid1_parent);
1292ATF_TC_HEAD(traceme_pid1_parent, tc)
1293{
1294	atf_tc_set_md_var(tc, "descr",
1295	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
1296}
1297
1298ATF_TC_BODY(traceme_pid1_parent, tc)
1299{
1300	struct msg_fds parent_child;
1301	int exitval_child1 = 1, exitval_child2 = 2;
1302	pid_t child1, child2, wpid;
1303	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1304#if defined(TWAIT_HAVE_STATUS)
1305	int status;
1306#endif
1307
1308	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
1309
1310	DPRINTF("Before forking process PID=%d\n", getpid());
1311	SYSCALL_REQUIRE((child1 = fork()) != -1);
1312	if (child1 == 0) {
1313		DPRINTF("Before forking process PID=%d\n", getpid());
1314		SYSCALL_REQUIRE((child2 = fork()) != -1);
1315		if (child2 != 0) {
1316			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
1317			    getpid(), child2);
1318			_exit(exitval_child1);
1319		}
1320		CHILD_FROM_PARENT("exit child1", parent_child, msg);
1321
1322		DPRINTF("Assert that our parent is PID1 (initproc)\n");
1323		FORKEE_ASSERT_EQ(getppid(), 1);
1324
1325		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1326		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
1327		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
1328
1329		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
1330
1331		_exit(exitval_child2);
1332	}
1333	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
1334
1335	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1336	TWAIT_REQUIRE_SUCCESS(
1337	    wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1);
1338
1339	validate_status_exited(status, exitval_child1);
1340
1341	DPRINTF("Notify that child1 is dead\n");
1342	PARENT_TO_CHILD("exit child1", parent_child, msg);
1343
1344	DPRINTF("Wait for exiting of child2\n");
1345	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
1346}
1347
1348/// ----------------------------------------------------------------------------
1349
1350static void
1351traceme_vfork_raise(int sigval)
1352{
1353	const int exitval = 5, exitval_watcher = 10;
1354	pid_t child, parent, watcher, wpid;
1355	int rv;
1356#if defined(TWAIT_HAVE_STATUS)
1357	int status;
1358
1359	/* volatile workarounds GCC -Werror=clobbered */
1360	volatile int expect_core;
1361
1362	switch (sigval) {
1363	case SIGABRT:
1364	case SIGTRAP:
1365	case SIGBUS:
1366	case SIGILL:
1367	case SIGFPE:
1368	case SIGSEGV:
1369		expect_core = 1;
1370		break;
1371	default:
1372		expect_core = 0;
1373		break;
1374	}
1375#endif
1376
1377	/*
1378	 * Spawn a dedicated thread to watch for a stopped child and emit
1379	 * the SIGKILL signal to it.
1380	 *
1381	 * vfork(2) might clobber watcher, this means that it's safer and
1382	 * simpler to reparent this process to initproc and forget about it.
1383	 */
1384	if (sigval == SIGSTOP) {
1385		parent = getpid();
1386
1387		watcher = fork();
1388		ATF_REQUIRE(watcher != 1);
1389		if (watcher == 0) {
1390			/* Double fork(2) trick to reparent to initproc */
1391			watcher = fork();
1392			FORKEE_ASSERT_NEQ(watcher, -1);
1393			if (watcher != 0)
1394				_exit(exitval_watcher);
1395
1396			child = await_stopped_child(parent);
1397
1398			errno = 0;
1399			rv = kill(child, SIGKILL);
1400			FORKEE_ASSERT_EQ(rv, 0);
1401			FORKEE_ASSERT_EQ(errno, 0);
1402
1403			/* This exit value will be collected by initproc */
1404			_exit(0);
1405		}
1406		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1407		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
1408		    watcher);
1409
1410		validate_status_exited(status, exitval_watcher);
1411
1412		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1413		TWAIT_REQUIRE_FAILURE(ECHILD,
1414		    wpid = TWAIT_GENERIC(watcher, &status, 0));
1415	}
1416
1417	DPRINTF("Before forking process PID=%d\n", getpid());
1418	SYSCALL_REQUIRE((child = vfork()) != -1);
1419	if (child == 0) {
1420		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1421		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1422
1423		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1424		FORKEE_ASSERT(raise(sigval) == 0);
1425
1426		switch (sigval) {
1427		case SIGSTOP:
1428		case SIGKILL:
1429		case SIGABRT:
1430		case SIGHUP:
1431		case SIGTRAP:
1432		case SIGBUS:
1433		case SIGILL:
1434		case SIGFPE:
1435		case SIGSEGV:
1436			/* NOTREACHED */
1437			FORKEE_ASSERTX(0 && "This shall not be reached");
1438			__unreachable();
1439		default:
1440			DPRINTF("Before exiting of the child process\n");
1441			_exit(exitval);
1442		}
1443	}
1444	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1445
1446	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1447	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1448
1449	switch (sigval) {
1450	case SIGKILL:
1451	case SIGABRT:
1452	case SIGHUP:
1453	case SIGTRAP:
1454	case SIGBUS:
1455	case SIGILL:
1456	case SIGFPE:
1457	case SIGSEGV:
1458		validate_status_signaled(status, sigval, expect_core);
1459		break;
1460	case SIGSTOP:
1461		validate_status_signaled(status, SIGKILL, 0);
1462		break;
1463	case SIGCONT:
1464	case SIGTSTP:
1465	case SIGTTIN:
1466	case SIGTTOU:
1467		validate_status_exited(status, exitval);
1468		break;
1469	default:
1470		/* NOTREACHED */
1471		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
1472		break;
1473	}
1474
1475	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1476	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1477}
1478
1479#define TRACEME_VFORK_RAISE(test, sig)					\
1480ATF_TC(test);								\
1481ATF_TC_HEAD(test, tc)							\
1482{									\
1483	atf_tc_set_md_var(tc, "descr",					\
1484	    "Verify PT_TRACE_ME followed by raise of " #sig " in a "	\
1485	    "vfork(2)ed child");					\
1486}									\
1487									\
1488ATF_TC_BODY(test, tc)							\
1489{									\
1490									\
1491	traceme_vfork_raise(sig);					\
1492}
1493
1494TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
1495TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
1496TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
1497TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
1498TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
1499TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
1500TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
1501TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
1502TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */
1503TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */
1504TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */
1505TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */
1506TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */
1507
1508/// ----------------------------------------------------------------------------
1509
1510static void
1511traceme_vfork_crash(int sig)
1512{
1513	pid_t child, wpid;
1514#if defined(TWAIT_HAVE_STATUS)
1515	int status;
1516#endif
1517
1518#ifndef PTRACE_ILLEGAL_ASM
1519	if (sig == SIGILL)
1520		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1521#endif
1522
1523	DPRINTF("Before forking process PID=%d\n", getpid());
1524	SYSCALL_REQUIRE((child = vfork()) != -1);
1525	if (child == 0) {
1526		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1527		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1528
1529		DPRINTF("Before executing a trap\n");
1530		switch (sig) {
1531		case SIGTRAP:
1532			trigger_trap();
1533			break;
1534		case SIGSEGV:
1535			trigger_segv();
1536			break;
1537		case SIGILL:
1538			trigger_ill();
1539			break;
1540		case SIGFPE:
1541			trigger_fpe();
1542			break;
1543		case SIGBUS:
1544			trigger_bus();
1545			break;
1546		default:
1547			/* NOTREACHED */
1548			FORKEE_ASSERTX(0 && "This shall not be reached");
1549		}
1550
1551		/* NOTREACHED */
1552		FORKEE_ASSERTX(0 && "This shall not be reached");
1553	}
1554	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1555
1556	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1557	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1558
1559	validate_status_signaled(status, sig, 1);
1560
1561	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1562	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1563}
1564
1565#define TRACEME_VFORK_CRASH(test, sig)					\
1566ATF_TC(test);								\
1567ATF_TC_HEAD(test, tc)							\
1568{									\
1569	atf_tc_set_md_var(tc, "descr",					\
1570	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1571	    "vfork(2)ed child");					\
1572}									\
1573									\
1574ATF_TC_BODY(test, tc)							\
1575{									\
1576									\
1577	traceme_vfork_crash(sig);					\
1578}
1579
1580TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP)
1581TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV)
1582TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL)
1583TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE)
1584TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS)
1585
1586/// ----------------------------------------------------------------------------
1587
1588static void
1589traceme_vfork_signalmasked_crash(int sig)
1590{
1591	pid_t child, wpid;
1592#if defined(TWAIT_HAVE_STATUS)
1593	int status;
1594#endif
1595	sigset_t intmask;
1596
1597#ifndef PTRACE_ILLEGAL_ASM
1598	if (sig == SIGILL)
1599		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1600#endif
1601
1602	DPRINTF("Before forking process PID=%d\n", getpid());
1603	SYSCALL_REQUIRE((child = vfork()) != -1);
1604	if (child == 0) {
1605		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1606		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1607
1608		sigemptyset(&intmask);
1609		sigaddset(&intmask, sig);
1610		sigprocmask(SIG_BLOCK, &intmask, NULL);
1611
1612		DPRINTF("Before executing a trap\n");
1613		switch (sig) {
1614		case SIGTRAP:
1615			trigger_trap();
1616			break;
1617		case SIGSEGV:
1618			trigger_segv();
1619			break;
1620		case SIGILL:
1621			trigger_ill();
1622			break;
1623		case SIGFPE:
1624			trigger_fpe();
1625			break;
1626		case SIGBUS:
1627			trigger_bus();
1628			break;
1629		default:
1630			/* NOTREACHED */
1631			FORKEE_ASSERTX(0 && "This shall not be reached");
1632		}
1633
1634		/* NOTREACHED */
1635		FORKEE_ASSERTX(0 && "This shall not be reached");
1636	}
1637	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1638
1639	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1640	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1641
1642	validate_status_signaled(status, sig, 1);
1643
1644	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1645	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1646}
1647
1648#define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig)			\
1649ATF_TC(test);								\
1650ATF_TC_HEAD(test, tc)							\
1651{									\
1652	atf_tc_set_md_var(tc, "descr",					\
1653	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1654	    "vfork(2)ed child with a masked signal");			\
1655}									\
1656									\
1657ATF_TC_BODY(test, tc)							\
1658{									\
1659									\
1660	traceme_vfork_signalmasked_crash(sig);				\
1661}
1662
1663TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP)
1664TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV)
1665TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL)
1666TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE)
1667TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS)
1668
1669/// ----------------------------------------------------------------------------
1670
1671static void
1672traceme_vfork_signalignored_crash(int sig)
1673{
1674	pid_t child, wpid;
1675#if defined(TWAIT_HAVE_STATUS)
1676	int status;
1677#endif
1678	struct sigaction sa;
1679
1680#ifndef PTRACE_ILLEGAL_ASM
1681	if (sig == SIGILL)
1682		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1683#endif
1684
1685	DPRINTF("Before forking process PID=%d\n", getpid());
1686	SYSCALL_REQUIRE((child = vfork()) != -1);
1687	if (child == 0) {
1688		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1689		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1690
1691		memset(&sa, 0, sizeof(sa));
1692		sa.sa_handler = SIG_IGN;
1693		sigemptyset(&sa.sa_mask);
1694
1695		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1696
1697		DPRINTF("Before executing a trap\n");
1698		switch (sig) {
1699		case SIGTRAP:
1700			trigger_trap();
1701			break;
1702		case SIGSEGV:
1703			trigger_segv();
1704			break;
1705		case SIGILL:
1706			trigger_ill();
1707			break;
1708		case SIGFPE:
1709			trigger_fpe();
1710			break;
1711		case SIGBUS:
1712			trigger_bus();
1713			break;
1714		default:
1715			/* NOTREACHED */
1716			FORKEE_ASSERTX(0 && "This shall not be reached");
1717		}
1718
1719		/* NOTREACHED */
1720		FORKEE_ASSERTX(0 && "This shall not be reached");
1721	}
1722	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1723
1724	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1725	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1726
1727	validate_status_signaled(status, sig, 1);
1728
1729	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1730	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1731}
1732
1733#define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig)			\
1734ATF_TC(test);								\
1735ATF_TC_HEAD(test, tc)							\
1736{									\
1737	atf_tc_set_md_var(tc, "descr",					\
1738	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1739	    "vfork(2)ed child with ignored signal");			\
1740}									\
1741									\
1742ATF_TC_BODY(test, tc)							\
1743{									\
1744									\
1745	traceme_vfork_signalignored_crash(sig);				\
1746}
1747
1748TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,
1749    SIGTRAP)
1750TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv,
1751    SIGSEGV)
1752TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill,
1753    SIGILL)
1754TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe,
1755    SIGFPE)
1756TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus,
1757    SIGBUS)
1758
1759/// ----------------------------------------------------------------------------
1760
1761ATF_TC(traceme_vfork_exec);
1762ATF_TC_HEAD(traceme_vfork_exec, tc)
1763{
1764	atf_tc_set_md_var(tc, "descr",
1765	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child");
1766}
1767
1768ATF_TC_BODY(traceme_vfork_exec, tc)
1769{
1770	const int sigval = SIGTRAP;
1771	pid_t child, wpid;
1772#if defined(TWAIT_HAVE_STATUS)
1773	int status;
1774#endif
1775	struct ptrace_siginfo info;
1776
1777	memset(&info, 0, sizeof(info));
1778
1779	DPRINTF("Before forking process PID=%d\n", getpid());
1780	SYSCALL_REQUIRE((child = vfork()) != -1);
1781	if (child == 0) {
1782		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1783		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1784
1785		DPRINTF("Before calling execve(2) from child\n");
1786		execlp("/bin/echo", "/bin/echo", NULL);
1787
1788		/* NOTREACHED */
1789		FORKEE_ASSERTX(0 && "Not reached");
1790	}
1791	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1792
1793	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1794	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1795
1796	validate_status_stopped(status, sigval);
1797
1798	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1799	SYSCALL_REQUIRE(
1800	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1801
1802	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1803	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1804	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1805	    info.psi_siginfo.si_errno);
1806
1807	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1808	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
1809
1810	DPRINTF("Before resuming the child process where it left off and "
1811	    "without signal to be sent\n");
1812	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1813
1814	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1815	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1816
1817	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1818	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1819}
1820
1821/// ----------------------------------------------------------------------------
1822
1823#if defined(TWAIT_HAVE_PID)
1824static void
1825unrelated_tracer_sees_crash(int sig)
1826{
1827	struct msg_fds parent_tracee, parent_tracer;
1828	const int exitval = 10;
1829	pid_t tracee, tracer, wpid;
1830	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1831#if defined(TWAIT_HAVE_STATUS)
1832	int status;
1833#endif
1834	struct ptrace_siginfo info;
1835
1836#ifndef PTRACE_ILLEGAL_ASM
1837	if (sig == SIGILL)
1838		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1839#endif
1840
1841	memset(&info, 0, sizeof(info));
1842
1843	DPRINTF("Spawn tracee\n");
1844	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1845	tracee = atf_utils_fork();
1846	if (tracee == 0) {
1847		// Wait for parent to let us crash
1848		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
1849
1850		DPRINTF("Before executing a trap\n");
1851		switch (sig) {
1852		case SIGTRAP:
1853			trigger_trap();
1854			break;
1855		case SIGSEGV:
1856			trigger_segv();
1857			break;
1858		case SIGILL:
1859			trigger_ill();
1860			break;
1861		case SIGFPE:
1862			trigger_fpe();
1863			break;
1864		case SIGBUS:
1865			trigger_bus();
1866			break;
1867		default:
1868			/* NOTREACHED */
1869			FORKEE_ASSERTX(0 && "This shall not be reached");
1870		}
1871
1872		/* NOTREACHED */
1873		FORKEE_ASSERTX(0 && "This shall not be reached");
1874	}
1875
1876	DPRINTF("Spawn debugger\n");
1877	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1878	tracer = atf_utils_fork();
1879	if (tracer == 0) {
1880		/* Fork again and drop parent to reattach to PID 1 */
1881		tracer = atf_utils_fork();
1882		if (tracer != 0)
1883			_exit(exitval);
1884
1885		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1886		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1887
1888		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1889		FORKEE_REQUIRE_SUCCESS(
1890		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1891
1892		forkee_status_stopped(status, SIGSTOP);
1893
1894		/* Resume tracee with PT_CONTINUE */
1895		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1896
1897		/* Inform parent that tracer has attached to tracee */
1898		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1899
1900		/* Wait for parent to tell use that tracee should have exited */
1901		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
1902
1903		/* Wait for tracee and assert that it exited */
1904		FORKEE_REQUIRE_SUCCESS(
1905		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1906
1907		forkee_status_stopped(status, sig);
1908
1909		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1910		    "traced process\n");
1911		SYSCALL_REQUIRE(
1912		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1913
1914		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1915		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1916		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1917		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1918
1919		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig);
1920		switch (sig) {
1921		case SIGTRAP:
1922			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
1923			break;
1924		case SIGSEGV:
1925			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
1926			break;
1927		case SIGILL:
1928			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, ILL_PRVOPC);
1929			break;
1930		case SIGFPE:
1931			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
1932			break;
1933		case SIGBUS:
1934			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
1935			break;
1936		}
1937
1938		FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1);
1939		DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME);
1940		FORKEE_REQUIRE_SUCCESS(
1941		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1942
1943		forkee_status_signaled(status, SIGKILL, 0);
1944
1945		DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
1946		TWAIT_REQUIRE_FAILURE(ECHILD,
1947		    wpid = TWAIT_GENERIC(tracee, &status, 0));
1948
1949		/* Inform parent that tracer is exiting normally */
1950		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
1951
1952		DPRINTF("Before exiting of the tracer process\n");
1953		_exit(0 /* collect by initproc */);
1954	}
1955
1956	DPRINTF("Wait for the tracer process (direct child) to exit "
1957	    "calling %s()\n", TWAIT_FNAME);
1958	TWAIT_REQUIRE_SUCCESS(
1959	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
1960
1961	validate_status_exited(status, exitval);
1962
1963	DPRINTF("Wait for the non-exited tracee process with %s()\n",
1964	    TWAIT_FNAME);
1965	TWAIT_REQUIRE_SUCCESS(
1966	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
1967
1968	DPRINTF("Wait for the tracer to attach to the tracee\n");
1969	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
1970
1971	DPRINTF("Resume the tracee and let it crash\n");
1972	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
1973
1974	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
1975	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
1976
1977	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1978	    TWAIT_FNAME);
1979	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1980
1981	validate_status_signaled(status, SIGKILL, 0);
1982
1983	DPRINTF("Await normal exit of tracer\n");
1984	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
1985
1986	msg_close(&parent_tracer);
1987	msg_close(&parent_tracee);
1988}
1989
1990#define UNRELATED_TRACER_SEES_CRASH(test, sig)				\
1991ATF_TC(test);								\
1992ATF_TC_HEAD(test, tc)							\
1993{									\
1994	atf_tc_set_md_var(tc, "descr",					\
1995	    "Assert that an unrelated tracer sees crash signal from the " \
1996	    "debuggee");						\
1997}									\
1998									\
1999ATF_TC_BODY(test, tc)							\
2000{									\
2001									\
2002	unrelated_tracer_sees_crash(sig);				\
2003}
2004
2005UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP)
2006UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV)
2007UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL)
2008UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE)
2009UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS)
2010#endif
2011
2012/// ----------------------------------------------------------------------------
2013
2014#if defined(TWAIT_HAVE_PID)
2015static void
2016tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated,
2017                                             bool stopped)
2018{
2019	/*
2020	 * notimeout - disable timeout in await zombie function
2021	 * unrelated - attach from unrelated tracer reparented to initproc
2022	 * stopped - attach to a stopped process
2023	 */
2024
2025	struct msg_fds parent_tracee, parent_tracer;
2026	const int exitval_tracee = 5;
2027	const int exitval_tracer = 10;
2028	pid_t tracee, tracer, wpid;
2029	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2030#if defined(TWAIT_HAVE_STATUS)
2031	int status;
2032#endif
2033
2034	/*
2035	 * Only a subset of options are supported.
2036	 */
2037	ATF_REQUIRE((!notimeout && !unrelated && !stopped) ||
2038	            (!notimeout && unrelated && !stopped) ||
2039	            (notimeout && !unrelated && !stopped) ||
2040	            (!notimeout && unrelated && stopped));
2041
2042	DPRINTF("Spawn tracee\n");
2043	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2044	tracee = atf_utils_fork();
2045	if (tracee == 0) {
2046		if (stopped) {
2047			DPRINTF("Stop self PID %d\n", getpid());
2048			raise(SIGSTOP);
2049		}
2050
2051		// Wait for parent to let us exit
2052		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2053		_exit(exitval_tracee);
2054	}
2055
2056	DPRINTF("Spawn debugger\n");
2057	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2058	tracer = atf_utils_fork();
2059	if (tracer == 0) {
2060		if(unrelated) {
2061			/* Fork again and drop parent to reattach to PID 1 */
2062			tracer = atf_utils_fork();
2063			if (tracer != 0)
2064				_exit(exitval_tracer);
2065		}
2066
2067		if (stopped) {
2068			DPRINTF("Await for a stopped parent PID %d\n", tracee);
2069			await_stopped(tracee);
2070		}
2071
2072		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2073		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2074
2075		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2076		FORKEE_REQUIRE_SUCCESS(
2077		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2078
2079		forkee_status_stopped(status, SIGSTOP);
2080
2081		/* Resume tracee with PT_CONTINUE */
2082		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2083
2084		/* Inform parent that tracer has attached to tracee */
2085		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2086
2087		/* Wait for parent to tell use that tracee should have exited */
2088		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2089
2090		/* Wait for tracee and assert that it exited */
2091		FORKEE_REQUIRE_SUCCESS(
2092		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2093
2094		forkee_status_exited(status, exitval_tracee);
2095		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
2096
2097		DPRINTF("Before exiting of the tracer process\n");
2098		_exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer);
2099	}
2100
2101	if (unrelated) {
2102		DPRINTF("Wait for the tracer process (direct child) to exit "
2103		    "calling %s()\n", TWAIT_FNAME);
2104		TWAIT_REQUIRE_SUCCESS(
2105		    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2106
2107		validate_status_exited(status, exitval_tracer);
2108
2109		DPRINTF("Wait for the non-exited tracee process with %s()\n",
2110		    TWAIT_FNAME);
2111		TWAIT_REQUIRE_SUCCESS(
2112		    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
2113	}
2114
2115	DPRINTF("Wait for the tracer to attach to the tracee\n");
2116	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
2117
2118	DPRINTF("Resume the tracee and let it exit\n");
2119	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
2120
2121	DPRINTF("Detect that tracee is zombie\n");
2122	if (notimeout)
2123		await_zombie_raw(tracee, 0);
2124	else
2125		await_zombie(tracee);
2126
2127	DPRINTF("Assert that there is no status about tracee %d - "
2128	    "Tracer must detect zombie first - calling %s()\n", tracee,
2129	    TWAIT_FNAME);
2130	TWAIT_REQUIRE_SUCCESS(
2131	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2132
2133	if (unrelated) {
2134		DPRINTF("Resume the tracer and let it detect exited tracee\n");
2135		PARENT_TO_CHILD("Message 2", parent_tracer, msg);
2136	} else {
2137		DPRINTF("Tell the tracer child should have exited\n");
2138		PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
2139		DPRINTF("Wait for tracer to finish its job and exit - calling "
2140			"%s()\n", TWAIT_FNAME);
2141
2142		DPRINTF("Wait from tracer child to complete waiting for "
2143			"tracee\n");
2144		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2145		    tracer);
2146
2147		validate_status_exited(status, exitval_tracer);
2148	}
2149
2150	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2151	    TWAIT_FNAME);
2152	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2153
2154	validate_status_exited(status, exitval_tracee);
2155
2156	msg_close(&parent_tracer);
2157	msg_close(&parent_tracee);
2158}
2159
2160ATF_TC(tracer_sees_terminaton_before_the_parent);
2161ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc)
2162{
2163	atf_tc_set_md_var(tc, "descr",
2164	    "Assert that tracer sees process termination before the parent");
2165}
2166
2167ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc)
2168{
2169
2170	tracer_sees_terminaton_before_the_parent_raw(false, false, false);
2171}
2172
2173ATF_TC(tracer_sysctl_lookup_without_duplicates);
2174ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc)
2175{
2176	atf_tc_set_md_var(tc, "descr",
2177	    "Assert that await_zombie() in attach1 always finds a single "
2178	    "process and no other error is reported");
2179}
2180
2181ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc)
2182{
2183	time_t start, end;
2184	double diff;
2185	unsigned long N = 0;
2186
2187	/*
2188	 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw().
2189	 * This test body isn't specific to this race, however it's just good
2190	 * enough for this purposes, no need to invent a dedicated code flow.
2191	 */
2192
2193	start = time(NULL);
2194	while (true) {
2195		DPRINTF("Step: %lu\n", N);
2196		tracer_sees_terminaton_before_the_parent_raw(true, false,
2197		                                             false);
2198		end = time(NULL);
2199		diff = difftime(end, start);
2200		if (diff >= 5.0)
2201			break;
2202		++N;
2203	}
2204	DPRINTF("Iterations: %lu\n", N);
2205}
2206
2207ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent);
2208ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2209{
2210	atf_tc_set_md_var(tc, "descr",
2211	    "Assert that tracer sees process termination before the parent");
2212}
2213
2214ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2215{
2216
2217	tracer_sees_terminaton_before_the_parent_raw(false, true, false);
2218}
2219
2220ATF_TC(tracer_attach_to_unrelated_stopped_process);
2221ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc)
2222{
2223	atf_tc_set_md_var(tc, "descr",
2224	    "Assert that tracer can attach to an unrelated stopped process");
2225}
2226
2227ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc)
2228{
2229
2230	tracer_sees_terminaton_before_the_parent_raw(false, true, true);
2231}
2232#endif
2233
2234/// ----------------------------------------------------------------------------
2235
2236static void
2237parent_attach_to_its_child(bool stopped)
2238{
2239	struct msg_fds parent_tracee;
2240	const int exitval_tracee = 5;
2241	pid_t tracee, wpid;
2242	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2243#if defined(TWAIT_HAVE_STATUS)
2244	int status;
2245#endif
2246
2247	DPRINTF("Spawn tracee\n");
2248	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2249	tracee = atf_utils_fork();
2250	if (tracee == 0) {
2251		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2252		DPRINTF("Parent should now attach to tracee\n");
2253
2254		if (stopped) {
2255			DPRINTF("Stop self PID %d\n", getpid());
2256			SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2257		}
2258
2259		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
2260		/* Wait for message from the parent */
2261		_exit(exitval_tracee);
2262	}
2263	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2264
2265	if (stopped) {
2266		DPRINTF("Await for a stopped tracee PID %d\n", tracee);
2267		await_stopped(tracee);
2268	}
2269
2270	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
2271	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2272
2273	DPRINTF("Wait for the stopped tracee process with %s()\n",
2274	    TWAIT_FNAME);
2275	TWAIT_REQUIRE_SUCCESS(
2276	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2277
2278	validate_status_stopped(status, SIGSTOP);
2279
2280	DPRINTF("Resume tracee with PT_CONTINUE\n");
2281	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2282
2283	DPRINTF("Let the tracee exit now\n");
2284	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
2285
2286	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
2287	TWAIT_REQUIRE_SUCCESS(
2288	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2289
2290	validate_status_exited(status, exitval_tracee);
2291
2292	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
2293	TWAIT_REQUIRE_FAILURE(ECHILD,
2294	    wpid = TWAIT_GENERIC(tracee, &status, 0));
2295
2296	msg_close(&parent_tracee);
2297}
2298
2299ATF_TC(parent_attach_to_its_child);
2300ATF_TC_HEAD(parent_attach_to_its_child, tc)
2301{
2302	atf_tc_set_md_var(tc, "descr",
2303	    "Assert that tracer parent can PT_ATTACH to its child");
2304}
2305
2306ATF_TC_BODY(parent_attach_to_its_child, tc)
2307{
2308
2309	parent_attach_to_its_child(false);
2310}
2311
2312ATF_TC(parent_attach_to_its_stopped_child);
2313ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc)
2314{
2315	atf_tc_set_md_var(tc, "descr",
2316	    "Assert that tracer parent can PT_ATTACH to its stopped child");
2317}
2318
2319ATF_TC_BODY(parent_attach_to_its_stopped_child, tc)
2320{
2321
2322	parent_attach_to_its_child(true);
2323}
2324
2325/// ----------------------------------------------------------------------------
2326
2327static void
2328child_attach_to_its_parent(bool stopped)
2329{
2330	struct msg_fds parent_tracee;
2331	const int exitval_tracer = 5;
2332	pid_t tracer, wpid;
2333	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2334#if defined(TWAIT_HAVE_STATUS)
2335	int status;
2336#endif
2337
2338	DPRINTF("Spawn tracer\n");
2339	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2340	tracer = atf_utils_fork();
2341	if (tracer == 0) {
2342		/* Wait for message from the parent */
2343		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2344
2345		if (stopped) {
2346			DPRINTF("Await for a stopped parent PID %d\n",
2347			        getppid());
2348			await_stopped(getppid());
2349		}
2350
2351		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
2352		    getppid());
2353		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
2354
2355		DPRINTF("Wait for the stopped parent process with %s()\n",
2356		    TWAIT_FNAME);
2357		FORKEE_REQUIRE_SUCCESS(
2358		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
2359
2360		forkee_status_stopped(status, SIGSTOP);
2361
2362		DPRINTF("Resume parent with PT_DETACH\n");
2363		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
2364		    != -1);
2365
2366		/* Tell parent we are ready */
2367		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
2368
2369		_exit(exitval_tracer);
2370	}
2371
2372	DPRINTF("Wait for the tracer to become ready\n");
2373	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2374
2375	if (stopped) {
2376		DPRINTF("Stop self PID %d\n", getpid());
2377		SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2378	}
2379
2380	DPRINTF("Allow the tracer to exit now\n");
2381	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
2382
2383	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
2384	TWAIT_REQUIRE_SUCCESS(
2385	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2386
2387	validate_status_exited(status, exitval_tracer);
2388
2389	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
2390	TWAIT_REQUIRE_FAILURE(ECHILD,
2391	    wpid = TWAIT_GENERIC(tracer, &status, 0));
2392
2393	msg_close(&parent_tracee);
2394}
2395
2396ATF_TC(child_attach_to_its_parent);
2397ATF_TC_HEAD(child_attach_to_its_parent, tc)
2398{
2399	atf_tc_set_md_var(tc, "descr",
2400	    "Assert that tracer child can PT_ATTACH to its parent");
2401}
2402
2403ATF_TC_BODY(child_attach_to_its_parent, tc)
2404{
2405
2406	child_attach_to_its_parent(false);
2407}
2408
2409ATF_TC(child_attach_to_its_stopped_parent);
2410ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc)
2411{
2412	atf_tc_set_md_var(tc, "descr",
2413	    "Assert that tracer child can PT_ATTACH to its stopped parent");
2414}
2415
2416ATF_TC_BODY(child_attach_to_its_stopped_parent, tc)
2417{
2418	/*
2419	 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as
2420	 * this causes a pipe (established from atf-run) to be broken.
2421	 * atf-run uses this mechanism to monitor whether a test is alive.
2422	 *
2423	 * As a workaround spawn this test as a subprocess.
2424	 */
2425
2426	const int exitval = 15;
2427	pid_t child, wpid;
2428#if defined(TWAIT_HAVE_STATUS)
2429	int status;
2430#endif
2431
2432	SYSCALL_REQUIRE((child = fork()) != -1);
2433	if (child == 0) {
2434		child_attach_to_its_parent(true);
2435		_exit(exitval);
2436	} else {
2437		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2438		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2439
2440		validate_status_exited(status, exitval);
2441
2442		DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2443		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2444	}
2445}
2446
2447/// ----------------------------------------------------------------------------
2448
2449#if defined(TWAIT_HAVE_PID)
2450
2451enum tracee_sees_its_original_parent_type {
2452	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2453	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2454	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS
2455};
2456
2457static void
2458tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type)
2459{
2460	struct msg_fds parent_tracer, parent_tracee;
2461	const int exitval_tracee = 5;
2462	const int exitval_tracer = 10;
2463	pid_t parent, tracee, tracer, wpid;
2464	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2465#if defined(TWAIT_HAVE_STATUS)
2466	int status;
2467#endif
2468	/* sysctl(3) - kinfo_proc2 */
2469	int name[CTL_MAXNAME];
2470	struct kinfo_proc2 kp;
2471	size_t len = sizeof(kp);
2472	unsigned int namelen;
2473
2474	/* procfs - status  */
2475	FILE *fp;
2476	struct stat st;
2477	const char *fname = "/proc/curproc/status";
2478	char s_executable[MAXPATHLEN];
2479	int s_pid, s_ppid;
2480	int rv;
2481
2482	if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) {
2483		SYSCALL_REQUIRE(
2484		    (rv = stat(fname, &st)) == 0 || (errno == ENOENT));
2485		if (rv != 0)
2486			atf_tc_skip("/proc/curproc/status not found");
2487	}
2488
2489	DPRINTF("Spawn tracee\n");
2490	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2491	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2492	tracee = atf_utils_fork();
2493	if (tracee == 0) {
2494		parent = getppid();
2495
2496		/* Emit message to the parent */
2497		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
2498		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2499
2500		switch (type) {
2501		case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID:
2502			FORKEE_ASSERT_EQ(parent, getppid());
2503			break;
2504		case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2:
2505			namelen = 0;
2506			name[namelen++] = CTL_KERN;
2507			name[namelen++] = KERN_PROC2;
2508			name[namelen++] = KERN_PROC_PID;
2509			name[namelen++] = getpid();
2510			name[namelen++] = len;
2511			name[namelen++] = 1;
2512
2513			FORKEE_ASSERT_EQ(
2514			    sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2515			FORKEE_ASSERT_EQ(parent, kp.p_ppid);
2516			break;
2517		case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS:
2518			/*
2519			 * Format:
2520			 *  EXECUTABLE PID PPID ...
2521			 */
2522			FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
2523			fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
2524			FORKEE_ASSERT_EQ(fclose(fp), 0);
2525			FORKEE_ASSERT_EQ(parent, s_ppid);
2526			break;
2527		}
2528
2529		_exit(exitval_tracee);
2530	}
2531	DPRINTF("Wait for child to record its parent identifier (pid)\n");
2532	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
2533
2534	DPRINTF("Spawn debugger\n");
2535	tracer = atf_utils_fork();
2536	if (tracer == 0) {
2537		/* No IPC to communicate with the child */
2538		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2539		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2540
2541		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2542		FORKEE_REQUIRE_SUCCESS(
2543		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2544
2545		forkee_status_stopped(status, SIGSTOP);
2546
2547		/* Resume tracee with PT_CONTINUE */
2548		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2549
2550		/* Inform parent that tracer has attached to tracee */
2551		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2552
2553		/* Wait for parent to tell use that tracee should have exited */
2554		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2555
2556		/* Wait for tracee and assert that it exited */
2557		FORKEE_REQUIRE_SUCCESS(
2558		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2559
2560		forkee_status_exited(status, exitval_tracee);
2561
2562		DPRINTF("Before exiting of the tracer process\n");
2563		_exit(exitval_tracer);
2564	}
2565
2566	DPRINTF("Wait for the tracer to attach to the tracee\n");
2567	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
2568
2569	DPRINTF("Resume the tracee and let it exit\n");
2570	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
2571
2572	DPRINTF("Detect that tracee is zombie\n");
2573	await_zombie(tracee);
2574
2575	DPRINTF("Assert that there is no status about tracee - "
2576	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
2577	TWAIT_REQUIRE_SUCCESS(
2578	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2579
2580	DPRINTF("Tell the tracer child should have exited\n");
2581	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
2582
2583	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
2584	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2585	    tracer);
2586
2587	validate_status_exited(status, exitval_tracer);
2588
2589	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2590	    TWAIT_FNAME);
2591	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
2592	    tracee);
2593
2594	validate_status_exited(status, exitval_tracee);
2595
2596	msg_close(&parent_tracer);
2597	msg_close(&parent_tracee);
2598}
2599
2600#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr)		\
2601ATF_TC(test);								\
2602ATF_TC_HEAD(test, tc)							\
2603{									\
2604	atf_tc_set_md_var(tc, "descr",					\
2605	    "Assert that tracee sees its original parent when being traced " \
2606	    "(check " descr ")");					\
2607}									\
2608									\
2609ATF_TC_BODY(test, tc)							\
2610{									\
2611									\
2612	tracee_sees_its_original_parent(type);				\
2613}
2614
2615TRACEE_SEES_ITS_ORIGINAL_PARENT(
2616	tracee_sees_its_original_parent_getppid,
2617	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2618	"getppid(2)");
2619TRACEE_SEES_ITS_ORIGINAL_PARENT(
2620	tracee_sees_its_original_parent_sysctl_kinfo_proc2,
2621	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2622	"sysctl(3) and kinfo_proc2");
2623TRACEE_SEES_ITS_ORIGINAL_PARENT(
2624	tracee_sees_its_original_parent_procfs_status,
2625	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS,
2626	"the status file in procfs");
2627#endif
2628
2629/// ----------------------------------------------------------------------------
2630
2631static void
2632eventmask_preserved(int event)
2633{
2634	const int exitval = 5;
2635	const int sigval = SIGSTOP;
2636	pid_t child, wpid;
2637#if defined(TWAIT_HAVE_STATUS)
2638	int status;
2639#endif
2640	ptrace_event_t set_event, get_event;
2641	const int len = sizeof(ptrace_event_t);
2642
2643	DPRINTF("Before forking process PID=%d\n", getpid());
2644	SYSCALL_REQUIRE((child = fork()) != -1);
2645	if (child == 0) {
2646		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2647		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2648
2649		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2650		FORKEE_ASSERT(raise(sigval) == 0);
2651
2652		DPRINTF("Before exiting of the child process\n");
2653		_exit(exitval);
2654	}
2655	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2656
2657	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2658	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2659
2660	validate_status_stopped(status, sigval);
2661
2662	set_event.pe_set_event = event;
2663	SYSCALL_REQUIRE(
2664	    ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
2665	SYSCALL_REQUIRE(
2666	    ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
2667	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
2668
2669	DPRINTF("Before resuming the child process where it left off and "
2670	    "without signal to be sent\n");
2671	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2672
2673	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2674	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2675
2676	validate_status_exited(status, exitval);
2677
2678	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2679	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2680}
2681
2682#define EVENTMASK_PRESERVED(test, event)				\
2683ATF_TC(test);								\
2684ATF_TC_HEAD(test, tc)							\
2685{									\
2686	atf_tc_set_md_var(tc, "descr",					\
2687	    "Verify that eventmask " #event " is preserved");		\
2688}									\
2689									\
2690ATF_TC_BODY(test, tc)							\
2691{									\
2692									\
2693	eventmask_preserved(event);					\
2694}
2695
2696EVENTMASK_PRESERVED(eventmask_preserved_empty, 0)
2697EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK)
2698EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK)
2699EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE)
2700EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE)
2701EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT)
2702
2703/// ----------------------------------------------------------------------------
2704
2705static void
2706fork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
2707    bool trackvforkdone, bool detachchild, bool detachparent)
2708{
2709	const int exitval = 5;
2710	const int exitval2 = 15;
2711	const int sigval = SIGSTOP;
2712	pid_t child, child2 = 0, wpid;
2713#if defined(TWAIT_HAVE_STATUS)
2714	int status;
2715#endif
2716	ptrace_state_t state;
2717	const int slen = sizeof(state);
2718	ptrace_event_t event;
2719	const int elen = sizeof(event);
2720
2721	DPRINTF("Before forking process PID=%d\n", getpid());
2722	SYSCALL_REQUIRE((child = fork()) != -1);
2723	if (child == 0) {
2724		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2725		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2726
2727		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2728		FORKEE_ASSERT(raise(sigval) == 0);
2729
2730		FORKEE_ASSERT((child2 = (fn)()) != -1);
2731
2732		if (child2 == 0)
2733			_exit(exitval2);
2734
2735		FORKEE_REQUIRE_SUCCESS
2736		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
2737
2738		forkee_status_exited(status, exitval2);
2739
2740		DPRINTF("Before exiting of the child process\n");
2741		_exit(exitval);
2742	}
2743	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2744
2745	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2746	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2747
2748	validate_status_stopped(status, sigval);
2749
2750	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
2751	    trackfork ? "|PTRACE_FORK" : "",
2752	    trackvfork ? "|PTRACE_VFORK" : "",
2753	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
2754	event.pe_set_event = 0;
2755	if (trackfork)
2756		event.pe_set_event |= PTRACE_FORK;
2757	if (trackvfork)
2758		event.pe_set_event |= PTRACE_VFORK;
2759	if (trackvforkdone)
2760		event.pe_set_event |= PTRACE_VFORK_DONE;
2761	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
2762
2763	DPRINTF("Before resuming the child process where it left off and "
2764	    "without signal to be sent\n");
2765	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2766
2767#if defined(TWAIT_HAVE_PID)
2768	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
2769		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
2770		    child);
2771		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2772		    child);
2773
2774		validate_status_stopped(status, SIGTRAP);
2775
2776		SYSCALL_REQUIRE(
2777		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2778		if (trackfork && fn == fork) {
2779			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
2780			       PTRACE_FORK);
2781		}
2782		if (trackvfork && fn == vfork) {
2783			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
2784			       PTRACE_VFORK);
2785		}
2786
2787		child2 = state.pe_other_pid;
2788		DPRINTF("Reported ptrace event with forkee %d\n", child2);
2789
2790		DPRINTF("Before calling %s() for the forkee %d of the child "
2791		    "%d\n", TWAIT_FNAME, child2, child);
2792		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
2793		    child2);
2794
2795		validate_status_stopped(status, SIGTRAP);
2796
2797		SYSCALL_REQUIRE(
2798		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
2799		if (trackfork && fn == fork) {
2800			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
2801			       PTRACE_FORK);
2802		}
2803		if (trackvfork && fn == vfork) {
2804			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
2805			       PTRACE_VFORK);
2806		}
2807
2808		ATF_REQUIRE_EQ(state.pe_other_pid, child);
2809
2810		DPRINTF("Before resuming the forkee process where it left off "
2811		    "and without signal to be sent\n");
2812		SYSCALL_REQUIRE(
2813		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
2814
2815		DPRINTF("Before resuming the child process where it left off "
2816		    "and without signal to be sent\n");
2817		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2818	}
2819#endif
2820
2821	if (trackvforkdone && fn == vfork) {
2822		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
2823		    child);
2824		TWAIT_REQUIRE_SUCCESS(
2825		    wpid = TWAIT_GENERIC(child, &status, 0), child);
2826
2827		validate_status_stopped(status, SIGTRAP);
2828
2829		SYSCALL_REQUIRE(
2830		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2831		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
2832
2833		child2 = state.pe_other_pid;
2834		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
2835		    child2);
2836
2837		DPRINTF("Before resuming the child process where it left off "
2838		    "and without signal to be sent\n");
2839		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2840	}
2841
2842#if defined(TWAIT_HAVE_PID)
2843	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
2844		DPRINTF("Before calling %s() for the forkee - expected exited"
2845		    "\n", TWAIT_FNAME);
2846		TWAIT_REQUIRE_SUCCESS(
2847		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
2848
2849		validate_status_exited(status, exitval2);
2850
2851		DPRINTF("Before calling %s() for the forkee - expected no "
2852		    "process\n", TWAIT_FNAME);
2853		TWAIT_REQUIRE_FAILURE(ECHILD,
2854		    wpid = TWAIT_GENERIC(child2, &status, 0));
2855	}
2856#endif
2857
2858	DPRINTF("Before calling %s() for the child - expected stopped "
2859	    "SIGCHLD\n", TWAIT_FNAME);
2860	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2861
2862	validate_status_stopped(status, SIGCHLD);
2863
2864	DPRINTF("Before resuming the child process where it left off and "
2865	    "without signal to be sent\n");
2866	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2867
2868	DPRINTF("Before calling %s() for the child - expected exited\n",
2869	    TWAIT_FNAME);
2870	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2871
2872	validate_status_exited(status, exitval);
2873
2874	DPRINTF("Before calling %s() for the child - expected no process\n",
2875	    TWAIT_FNAME);
2876	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2877}
2878
2879#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \
2880ATF_TC(name);								\
2881ATF_TC_HEAD(name, tc)							\
2882{									\
2883	atf_tc_set_md_var(tc, "descr", descr);				\
2884}									\
2885									\
2886ATF_TC_BODY(name, tc)							\
2887{									\
2888									\
2889	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);	\
2890}
2891
2892#define F false
2893#define T true
2894
2895#define F_IF__0(x)
2896#define F_IF__1(x) x
2897#define F_IF__(x,y) F_IF__ ## x (y)
2898#define F_IF_(x,y) F_IF__(x,y)
2899#define F_IF(x,y) F_IF_(x,y)
2900
2901#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \
2902	"Verify " #function "(2) called with 0"				\
2903	F_IF(forkbit,"|PTRACE_FORK")					\
2904	F_IF(vforkbit,"|PTRACE_VFORK")					\
2905	F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")				\
2906	" in EVENT_MASK."						\
2907	F_IF(dchildbit," Detach child in this test.")			\
2908	F_IF(dparentbit," Detach parent in this test.")
2909
2910FORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
2911#if defined(TWAIT_HAVE_PID)
2912FORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
2913FORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
2914FORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
2915#endif
2916FORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
2917#if defined(TWAIT_HAVE_PID)
2918FORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
2919FORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
2920FORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
2921#endif
2922
2923FORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
2924#if defined(TWAIT_HAVE_PID)
2925FORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
2926FORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
2927FORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
2928#endif
2929FORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
2930#if defined(TWAIT_HAVE_PID)
2931FORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
2932FORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
2933FORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
2934#endif
2935
2936/// ----------------------------------------------------------------------------
2937
2938enum bytes_transfer_type {
2939	BYTES_TRANSFER_DATA,
2940	BYTES_TRANSFER_DATAIO,
2941	BYTES_TRANSFER_TEXT,
2942	BYTES_TRANSFER_TEXTIO,
2943	BYTES_TRANSFER_AUXV
2944};
2945
2946static int __used
2947bytes_transfer_dummy(int a, int b, int c, int d)
2948{
2949	int e, f, g, h;
2950
2951	a *= 4;
2952	b += 3;
2953	c -= 2;
2954	d /= 1;
2955
2956	e = strtol("10", NULL, 10);
2957	f = strtol("20", NULL, 10);
2958	g = strtol("30", NULL, 10);
2959	h = strtol("40", NULL, 10);
2960
2961	return (a + b * c - d) + (e * f - g / h);
2962}
2963
2964static void
2965bytes_transfer(int operation, size_t size, enum bytes_transfer_type type)
2966{
2967	const int exitval = 5;
2968	const int sigval = SIGSTOP;
2969	pid_t child, wpid;
2970	bool skip = false;
2971
2972	int lookup_me = 0;
2973	uint8_t lookup_me8 = 0;
2974	uint16_t lookup_me16 = 0;
2975	uint32_t lookup_me32 = 0;
2976	uint64_t lookup_me64 = 0;
2977
2978	int magic = 0x13579246;
2979	uint8_t magic8 = 0xab;
2980	uint16_t magic16 = 0x1234;
2981	uint32_t magic32 = 0x98765432;
2982	uint64_t magic64 = 0xabcdef0123456789;
2983
2984	struct ptrace_io_desc io;
2985#if defined(TWAIT_HAVE_STATUS)
2986	int status;
2987#endif
2988	/* 513 is just enough, for the purposes of ATF it's good enough */
2989	AuxInfo ai[513], *aip;
2990
2991	ATF_REQUIRE(size < sizeof(ai));
2992
2993	/* Prepare variables for .TEXT transfers */
2994	switch (type) {
2995	case BYTES_TRANSFER_TEXT:
2996		memcpy(&magic, bytes_transfer_dummy, sizeof(magic));
2997		break;
2998	case BYTES_TRANSFER_TEXTIO:
2999		switch (size) {
3000		case 8:
3001			memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8));
3002			break;
3003		case 16:
3004			memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16));
3005			break;
3006		case 32:
3007			memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32));
3008			break;
3009		case 64:
3010			memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64));
3011			break;
3012		}
3013		break;
3014	default:
3015		break;
3016	}
3017
3018	/* Prepare variables for PIOD and AUXV transfers */
3019	switch (type) {
3020	case BYTES_TRANSFER_TEXTIO:
3021	case BYTES_TRANSFER_DATAIO:
3022		io.piod_op = operation;
3023		switch (size) {
3024		case 8:
3025			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3026			               (void *)bytes_transfer_dummy :
3027			               &lookup_me8;
3028			io.piod_addr = &lookup_me8;
3029			io.piod_len = sizeof(lookup_me8);
3030			break;
3031		case 16:
3032			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3033			               (void *)bytes_transfer_dummy :
3034			               &lookup_me16;
3035			io.piod_addr = &lookup_me16;
3036			io.piod_len = sizeof(lookup_me16);
3037			break;
3038		case 32:
3039			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3040			               (void *)bytes_transfer_dummy :
3041			               &lookup_me32;
3042			io.piod_addr = &lookup_me32;
3043			io.piod_len = sizeof(lookup_me32);
3044			break;
3045		case 64:
3046			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3047			               (void *)bytes_transfer_dummy :
3048			               &lookup_me64;
3049			io.piod_addr = &lookup_me64;
3050			io.piod_len = sizeof(lookup_me64);
3051			break;
3052		default:
3053			break;
3054		}
3055		break;
3056	case BYTES_TRANSFER_AUXV:
3057		io.piod_op = operation;
3058		io.piod_offs = 0;
3059		io.piod_addr = ai;
3060		io.piod_len = size;
3061		break;
3062	default:
3063		break;
3064	}
3065
3066	DPRINTF("Before forking process PID=%d\n", getpid());
3067	SYSCALL_REQUIRE((child = fork()) != -1);
3068	if (child == 0) {
3069		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3070		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3071
3072		switch (type) {
3073		case BYTES_TRANSFER_DATA:
3074			switch (operation) {
3075			case PT_READ_D:
3076			case PT_READ_I:
3077				lookup_me = magic;
3078				break;
3079			default:
3080				break;
3081			}
3082			break;
3083		case BYTES_TRANSFER_DATAIO:
3084			switch (operation) {
3085			case PIOD_READ_D:
3086			case PIOD_READ_I:
3087				switch (size) {
3088				case 8:
3089					lookup_me8 = magic8;
3090					break;
3091				case 16:
3092					lookup_me16 = magic16;
3093					break;
3094				case 32:
3095					lookup_me32 = magic32;
3096					break;
3097				case 64:
3098					lookup_me64 = magic64;
3099					break;
3100				default:
3101					break;
3102				}
3103				break;
3104			default:
3105				break;
3106			}
3107		default:
3108			break;
3109		}
3110
3111		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3112		FORKEE_ASSERT(raise(sigval) == 0);
3113
3114		/* Handle PIOD and PT separately as operation values overlap */
3115		switch (type) {
3116		case BYTES_TRANSFER_DATA:
3117			switch (operation) {
3118			case PT_WRITE_D:
3119			case PT_WRITE_I:
3120				FORKEE_ASSERT_EQ(lookup_me, magic);
3121				break;
3122			default:
3123				break;
3124			}
3125			break;
3126		case BYTES_TRANSFER_DATAIO:
3127			switch (operation) {
3128			case PIOD_WRITE_D:
3129			case PIOD_WRITE_I:
3130				switch (size) {
3131				case 8:
3132					FORKEE_ASSERT_EQ(lookup_me8, magic8);
3133					break;
3134				case 16:
3135					FORKEE_ASSERT_EQ(lookup_me16, magic16);
3136					break;
3137				case 32:
3138					FORKEE_ASSERT_EQ(lookup_me32, magic32);
3139					break;
3140				case 64:
3141					FORKEE_ASSERT_EQ(lookup_me64, magic64);
3142					break;
3143				default:
3144					break;
3145				}
3146				break;
3147			default:
3148				break;
3149			}
3150			break;
3151		case BYTES_TRANSFER_TEXT:
3152			FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy,
3153			                     sizeof(magic)) == 0);
3154			break;
3155		case BYTES_TRANSFER_TEXTIO:
3156			switch (size) {
3157			case 8:
3158				FORKEE_ASSERT(memcmp(&magic8,
3159				                     bytes_transfer_dummy,
3160				                     sizeof(magic8)) == 0);
3161				break;
3162			case 16:
3163				FORKEE_ASSERT(memcmp(&magic16,
3164				                     bytes_transfer_dummy,
3165				                     sizeof(magic16)) == 0);
3166				break;
3167			case 32:
3168				FORKEE_ASSERT(memcmp(&magic32,
3169				                     bytes_transfer_dummy,
3170				                     sizeof(magic32)) == 0);
3171				break;
3172			case 64:
3173				FORKEE_ASSERT(memcmp(&magic64,
3174				                     bytes_transfer_dummy,
3175				                     sizeof(magic64)) == 0);
3176				break;
3177			}
3178			break;
3179		default:
3180			break;
3181		}
3182
3183		DPRINTF("Before exiting of the child process\n");
3184		_exit(exitval);
3185	}
3186	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3187
3188	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3189	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3190
3191	validate_status_stopped(status, sigval);
3192
3193	/* Check PaX MPROTECT */
3194	if (!can_we_write_to_text(child)) {
3195		switch (type) {
3196		case BYTES_TRANSFER_TEXTIO:
3197			switch (operation) {
3198			case PIOD_WRITE_D:
3199			case PIOD_WRITE_I:
3200				skip = true;
3201				break;
3202			default:
3203				break;
3204			}
3205			break;
3206		case BYTES_TRANSFER_TEXT:
3207			switch (operation) {
3208			case PT_WRITE_D:
3209			case PT_WRITE_I:
3210				skip = true;
3211				break;
3212			default:
3213				break;
3214			}
3215			break;
3216		default:
3217			break;
3218		}
3219	}
3220
3221	/* Bailout cleanly killing the child process */
3222	if (skip) {
3223		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
3224		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3225		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3226		                      child);
3227
3228		validate_status_signaled(status, SIGKILL, 0);
3229
3230		atf_tc_skip("PaX MPROTECT setup prevents writes to .text");
3231	}
3232
3233	DPRINTF("Calling operation to transfer bytes between child=%d and "
3234	       "parent=%d\n", child, getpid());
3235
3236	switch (type) {
3237	case BYTES_TRANSFER_TEXTIO:
3238	case BYTES_TRANSFER_DATAIO:
3239	case BYTES_TRANSFER_AUXV:
3240		switch (operation) {
3241		case PIOD_WRITE_D:
3242		case PIOD_WRITE_I:
3243			switch (size) {
3244			case 8:
3245				lookup_me8 = magic8;
3246				break;
3247			case 16:
3248				lookup_me16 = magic16;
3249				break;
3250			case 32:
3251				lookup_me32 = magic32;
3252				break;
3253			case 64:
3254				lookup_me64 = magic64;
3255				break;
3256			default:
3257				break;
3258			}
3259			break;
3260		default:
3261			break;
3262		}
3263		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3264		switch (operation) {
3265		case PIOD_READ_D:
3266		case PIOD_READ_I:
3267			switch (size) {
3268			case 8:
3269				ATF_REQUIRE_EQ(lookup_me8, magic8);
3270				break;
3271			case 16:
3272				ATF_REQUIRE_EQ(lookup_me16, magic16);
3273				break;
3274			case 32:
3275				ATF_REQUIRE_EQ(lookup_me32, magic32);
3276				break;
3277			case 64:
3278				ATF_REQUIRE_EQ(lookup_me64, magic64);
3279				break;
3280			default:
3281				break;
3282			}
3283			break;
3284		case PIOD_READ_AUXV:
3285			DPRINTF("Asserting that AUXV length (%zu) is > 0\n",
3286			        io.piod_len);
3287			ATF_REQUIRE(io.piod_len > 0);
3288			for (aip = ai; aip->a_type != AT_NULL; aip++)
3289				DPRINTF("a_type=%#llx a_v=%#llx\n",
3290				    (long long int)aip->a_type,
3291				    (long long int)aip->a_v);
3292			break;
3293		default:
3294			break;
3295		}
3296		break;
3297	case BYTES_TRANSFER_TEXT:
3298		switch (operation) {
3299		case PT_READ_D:
3300		case PT_READ_I:
3301			errno = 0;
3302			lookup_me = ptrace(operation, child,
3303			                   bytes_transfer_dummy, 0);
3304			ATF_REQUIRE_EQ(lookup_me, magic);
3305			SYSCALL_REQUIRE_ERRNO(errno, 0);
3306			break;
3307		case PT_WRITE_D:
3308		case PT_WRITE_I:
3309			SYSCALL_REQUIRE(ptrace(operation, child,
3310			                       bytes_transfer_dummy, magic)
3311			                != -1);
3312			break;
3313		default:
3314			break;
3315		}
3316		break;
3317	case BYTES_TRANSFER_DATA:
3318		switch (operation) {
3319		case PT_READ_D:
3320		case PT_READ_I:
3321			errno = 0;
3322			lookup_me = ptrace(operation, child, &lookup_me, 0);
3323			ATF_REQUIRE_EQ(lookup_me, magic);
3324			SYSCALL_REQUIRE_ERRNO(errno, 0);
3325			break;
3326		case PT_WRITE_D:
3327		case PT_WRITE_I:
3328			lookup_me = magic;
3329			SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me,
3330			                       magic) != -1);
3331			break;
3332		default:
3333			break;
3334		}
3335		break;
3336	default:
3337		break;
3338	}
3339
3340	DPRINTF("Before resuming the child process where it left off and "
3341	    "without signal to be sent\n");
3342	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3343
3344	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3345	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3346
3347	validate_status_exited(status, exitval);
3348
3349	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3350	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3351}
3352
3353#define BYTES_TRANSFER(test, operation, size, type)			\
3354ATF_TC(test);								\
3355ATF_TC_HEAD(test, tc)							\
3356{									\
3357	atf_tc_set_md_var(tc, "descr",					\
3358	    "Verify bytes transfer operation" #operation " and size " #size \
3359	    " of type " #type);						\
3360}									\
3361									\
3362ATF_TC_BODY(test, tc)							\
3363{									\
3364									\
3365	bytes_transfer(operation, size, BYTES_TRANSFER_##type);		\
3366}
3367
3368// DATA
3369
3370BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO)
3371BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO)
3372BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO)
3373BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO)
3374
3375BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO)
3376BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO)
3377BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO)
3378BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO)
3379
3380BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO)
3381BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO)
3382BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO)
3383BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO)
3384
3385BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO)
3386BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO)
3387BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO)
3388BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO)
3389
3390BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA)
3391BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA)
3392BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA)
3393BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA)
3394
3395// TEXT
3396
3397BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO)
3398BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO)
3399BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO)
3400BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO)
3401
3402BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO)
3403BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO)
3404BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO)
3405BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO)
3406
3407BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO)
3408BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO)
3409BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO)
3410BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO)
3411
3412BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO)
3413BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO)
3414BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO)
3415BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO)
3416
3417BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT)
3418BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT)
3419BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT)
3420BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT)
3421
3422// AUXV
3423
3424BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV)
3425
3426/// ----------------------------------------------------------------------------
3427
3428#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS)
3429static void
3430access_regs(const char *regset, const char *aux)
3431{
3432	const int exitval = 5;
3433	const int sigval = SIGSTOP;
3434	pid_t child, wpid;
3435#if defined(TWAIT_HAVE_STATUS)
3436	int status;
3437#endif
3438#if defined(HAVE_GPREGS)
3439	struct reg gpr;
3440	register_t rgstr;
3441#endif
3442#if defined(HAVE_FPREGS)
3443	struct fpreg fpr;
3444#endif
3445
3446#if !defined(HAVE_GPREGS)
3447	if (strcmp(regset, "regs") == 0)
3448		atf_tc_fail("Impossible test scenario!");
3449#endif
3450
3451#if !defined(HAVE_FPREGS)
3452	if (strcmp(regset, "fpregs") == 0)
3453		atf_tc_fail("Impossible test scenario!");
3454#endif
3455
3456	DPRINTF("Before forking process PID=%d\n", getpid());
3457	SYSCALL_REQUIRE((child = fork()) != -1);
3458	if (child == 0) {
3459		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3460		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3461
3462		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3463		FORKEE_ASSERT(raise(sigval) == 0);
3464
3465		DPRINTF("Before exiting of the child process\n");
3466		_exit(exitval);
3467	}
3468	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3469
3470	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3471	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3472
3473	validate_status_stopped(status, sigval);
3474
3475#if defined(HAVE_GPREGS)
3476	if (strcmp(regset, "regs") == 0) {
3477		DPRINTF("Call GETREGS for the child process\n");
3478		SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1);
3479
3480		if (strcmp(aux, "none") == 0) {
3481			DPRINTF("Retrieved registers\n");
3482		} else if (strcmp(aux, "pc") == 0) {
3483			rgstr = PTRACE_REG_PC(&gpr);
3484			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
3485		} else if (strcmp(aux, "set_pc") == 0) {
3486			rgstr = PTRACE_REG_PC(&gpr);
3487			PTRACE_REG_SET_PC(&gpr, rgstr);
3488		} else if (strcmp(aux, "sp") == 0) {
3489			rgstr = PTRACE_REG_SP(&gpr);
3490			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
3491		} else if (strcmp(aux, "intrv") == 0) {
3492			rgstr = PTRACE_REG_INTRV(&gpr);
3493			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
3494		} else if (strcmp(aux, "setregs") == 0) {
3495			DPRINTF("Call SETREGS for the child process\n");
3496			SYSCALL_REQUIRE(
3497			    ptrace(PT_GETREGS, child, &gpr, 0) != -1);
3498		}
3499	}
3500#endif
3501
3502#if defined(HAVE_FPREGS)
3503	if (strcmp(regset, "fpregs") == 0) {
3504		DPRINTF("Call GETFPREGS for the child process\n");
3505		SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1);
3506
3507		if (strcmp(aux, "getfpregs") == 0) {
3508			DPRINTF("Retrieved FP registers\n");
3509		} else if (strcmp(aux, "setfpregs") == 0) {
3510			DPRINTF("Call SETFPREGS for the child\n");
3511			SYSCALL_REQUIRE(
3512			    ptrace(PT_SETFPREGS, child, &fpr, 0) != -1);
3513		}
3514	}
3515#endif
3516
3517	DPRINTF("Before resuming the child process where it left off and "
3518	    "without signal to be sent\n");
3519	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3520
3521	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3522	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3523
3524	validate_status_exited(status, exitval);
3525
3526	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3527	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3528}
3529
3530#define ACCESS_REGS(test, regset, aux)					\
3531ATF_TC(test);								\
3532ATF_TC_HEAD(test, tc)							\
3533{									\
3534        atf_tc_set_md_var(tc, "descr",					\
3535            "Verify " regset " with auxiliary operation: " aux);	\
3536}									\
3537									\
3538ATF_TC_BODY(test, tc)							\
3539{									\
3540									\
3541        access_regs(regset, aux);					\
3542}
3543#endif
3544
3545#if defined(HAVE_GPREGS)
3546ACCESS_REGS(access_regs1, "regs", "none")
3547ACCESS_REGS(access_regs2, "regs", "pc")
3548ACCESS_REGS(access_regs3, "regs", "set_pc")
3549ACCESS_REGS(access_regs4, "regs", "sp")
3550ACCESS_REGS(access_regs5, "regs", "intrv")
3551ACCESS_REGS(access_regs6, "regs", "setregs")
3552#endif
3553#if defined(HAVE_FPREGS)
3554ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs")
3555ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs")
3556#endif
3557
3558/// ----------------------------------------------------------------------------
3559
3560#if defined(PT_STEP)
3561static void
3562ptrace_step(int N, int setstep)
3563{
3564	const int exitval = 5;
3565	const int sigval = SIGSTOP;
3566	pid_t child, wpid;
3567#if defined(TWAIT_HAVE_STATUS)
3568	int status;
3569#endif
3570	int happy;
3571	struct ptrace_siginfo info;
3572
3573#if defined(__arm__)
3574	/* PT_STEP not supported on arm 32-bit */
3575	atf_tc_expect_fail("PR kern/52119");
3576#endif
3577
3578	DPRINTF("Before forking process PID=%d\n", getpid());
3579	SYSCALL_REQUIRE((child = fork()) != -1);
3580	if (child == 0) {
3581		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3582		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3583
3584		happy = check_happy(999);
3585
3586		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3587		FORKEE_ASSERT(raise(sigval) == 0);
3588
3589		FORKEE_ASSERT_EQ(happy, check_happy(999));
3590
3591		DPRINTF("Before exiting of the child process\n");
3592		_exit(exitval);
3593	}
3594	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3595
3596	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3597	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3598
3599	validate_status_stopped(status, sigval);
3600
3601	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3602	SYSCALL_REQUIRE(
3603	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3604
3605	DPRINTF("Before checking siginfo_t\n");
3606	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3607	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3608
3609	while (N --> 0) {
3610		if (setstep) {
3611			DPRINTF("Before resuming the child process where it "
3612			    "left off and without signal to be sent (use "
3613			    "PT_SETSTEP and PT_CONTINUE)\n");
3614			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
3615			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
3616			    != -1);
3617		} else {
3618			DPRINTF("Before resuming the child process where it "
3619			    "left off and without signal to be sent (use "
3620			    "PT_STEP)\n");
3621			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
3622			    != -1);
3623		}
3624
3625		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3626		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3627		    child);
3628
3629		validate_status_stopped(status, SIGTRAP);
3630
3631		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3632		SYSCALL_REQUIRE(
3633		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3634
3635		DPRINTF("Before checking siginfo_t\n");
3636		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
3637		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
3638
3639		if (setstep) {
3640			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
3641		}
3642	}
3643
3644	DPRINTF("Before resuming the child process where it left off and "
3645	    "without signal to be sent\n");
3646	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3647
3648	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3649	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3650
3651	validate_status_exited(status, exitval);
3652
3653	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3654	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3655}
3656
3657#define PTRACE_STEP(test, N, setstep)					\
3658ATF_TC(test);								\
3659ATF_TC_HEAD(test, tc)							\
3660{									\
3661        atf_tc_set_md_var(tc, "descr",					\
3662            "Verify " #N " (PT_SETSTEP set to: " #setstep ")");		\
3663}									\
3664									\
3665ATF_TC_BODY(test, tc)							\
3666{									\
3667									\
3668        ptrace_step(N, setstep);					\
3669}
3670
3671PTRACE_STEP(step1, 1, 0)
3672PTRACE_STEP(step2, 2, 0)
3673PTRACE_STEP(step3, 3, 0)
3674PTRACE_STEP(step4, 4, 0)
3675PTRACE_STEP(setstep1, 1, 1)
3676PTRACE_STEP(setstep2, 2, 1)
3677PTRACE_STEP(setstep3, 3, 1)
3678PTRACE_STEP(setstep4, 4, 1)
3679#endif
3680
3681/// ----------------------------------------------------------------------------
3682
3683static void
3684ptrace_kill(const char *type)
3685{
3686	const int sigval = SIGSTOP;
3687	pid_t child, wpid;
3688#if defined(TWAIT_HAVE_STATUS)
3689	int status;
3690#endif
3691
3692	DPRINTF("Before forking process PID=%d\n", getpid());
3693	SYSCALL_REQUIRE((child = fork()) != -1);
3694	if (child == 0) {
3695		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3696		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3697
3698		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3699		FORKEE_ASSERT(raise(sigval) == 0);
3700
3701		/* NOTREACHED */
3702		FORKEE_ASSERTX(0 &&
3703		    "Child should be terminated by a signal from its parent");
3704	}
3705	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3706
3707	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3708	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3709
3710	validate_status_stopped(status, sigval);
3711
3712	DPRINTF("Before killing the child process with %s\n", type);
3713	if (strcmp(type, "ptrace(PT_KILL)") == 0) {
3714		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
3715	} else if (strcmp(type, "kill(SIGKILL)") == 0) {
3716		kill(child, SIGKILL);
3717	} else if (strcmp(type, "killpg(SIGKILL)") == 0) {
3718		setpgid(child, 0);
3719		killpg(getpgid(child), SIGKILL);
3720	}
3721
3722	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3723	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3724
3725	validate_status_signaled(status, SIGKILL, 0);
3726
3727	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3728	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3729}
3730
3731#define PTRACE_KILL(test, type)						\
3732ATF_TC(test);								\
3733ATF_TC_HEAD(test, tc)							\
3734{									\
3735        atf_tc_set_md_var(tc, "descr",					\
3736            "Verify killing the child with " type);			\
3737}									\
3738									\
3739ATF_TC_BODY(test, tc)							\
3740{									\
3741									\
3742        ptrace_kill(type);						\
3743}
3744
3745// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1
3746PTRACE_KILL(kill1, "ptrace(PT_KILL)")
3747PTRACE_KILL(kill2, "kill(SIGKILL)")
3748PTRACE_KILL(kill3, "killpg(SIGKILL)")
3749
3750/// ----------------------------------------------------------------------------
3751
3752static void
3753traceme_lwpinfo(const int threads)
3754{
3755	const int sigval = SIGSTOP;
3756	const int sigval2 = SIGINT;
3757	pid_t child, wpid;
3758#if defined(TWAIT_HAVE_STATUS)
3759	int status;
3760#endif
3761	struct ptrace_lwpinfo lwp = {0, 0};
3762	struct ptrace_siginfo info;
3763
3764	/* Maximum number of supported threads in this test */
3765	pthread_t t[3];
3766	int n, rv;
3767
3768	ATF_REQUIRE((int)__arraycount(t) >= threads);
3769
3770	DPRINTF("Before forking process PID=%d\n", getpid());
3771	SYSCALL_REQUIRE((child = fork()) != -1);
3772	if (child == 0) {
3773		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3774		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3775
3776		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3777		FORKEE_ASSERT(raise(sigval) == 0);
3778
3779		for (n = 0; n < threads; n++) {
3780			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
3781			FORKEE_ASSERT(rv == 0);
3782		}
3783
3784		DPRINTF("Before raising %s from child\n", strsignal(sigval2));
3785		FORKEE_ASSERT(raise(sigval2) == 0);
3786
3787		/* NOTREACHED */
3788		FORKEE_ASSERTX(0 && "Not reached");
3789	}
3790	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3791
3792	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3793	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3794
3795	validate_status_stopped(status, sigval);
3796
3797	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
3798	SYSCALL_REQUIRE(
3799	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3800
3801	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3802	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3803	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3804	    info.psi_siginfo.si_errno);
3805
3806	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3807	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3808
3809	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3810	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
3811
3812	DPRINTF("Assert that there exists a single thread only\n");
3813	ATF_REQUIRE(lwp.pl_lwpid > 0);
3814
3815	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
3816	    lwp.pl_lwpid);
3817	FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
3818
3819	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3820	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
3821
3822	DPRINTF("Assert that there exists a single thread only\n");
3823	ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
3824
3825	DPRINTF("Before resuming the child process where it left off and "
3826	    "without signal to be sent\n");
3827	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3828
3829	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3830	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3831
3832	validate_status_stopped(status, sigval2);
3833
3834	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
3835	SYSCALL_REQUIRE(
3836	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3837
3838	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3839	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3840	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3841	    info.psi_siginfo.si_errno);
3842
3843	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
3844	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3845
3846	memset(&lwp, 0, sizeof(lwp));
3847
3848	for (n = 0; n <= threads; n++) {
3849		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3850		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
3851		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
3852
3853		DPRINTF("Assert that the thread exists\n");
3854		ATF_REQUIRE(lwp.pl_lwpid > 0);
3855
3856		DPRINTF("Assert that lwp thread %d received expected event\n",
3857		    lwp.pl_lwpid);
3858		FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ?
3859		    PL_EVENT_SIGNAL : PL_EVENT_NONE);
3860	}
3861	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3862	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
3863	DPRINTF("LWP=%d\n", lwp.pl_lwpid);
3864
3865	DPRINTF("Assert that there are no more threads\n");
3866	ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
3867
3868	DPRINTF("Before resuming the child process where it left off and "
3869	    "without signal to be sent\n");
3870	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1);
3871
3872	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3873	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3874
3875	validate_status_signaled(status, SIGKILL, 0);
3876
3877	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3878	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3879}
3880
3881#define TRACEME_LWPINFO(test, threads)					\
3882ATF_TC(test);								\
3883ATF_TC_HEAD(test, tc)							\
3884{									\
3885	atf_tc_set_md_var(tc, "descr",					\
3886	    "Verify LWPINFO with the child with " #threads		\
3887	    " spawned extra threads");					\
3888}									\
3889									\
3890ATF_TC_BODY(test, tc)							\
3891{									\
3892									\
3893	traceme_lwpinfo(threads);					\
3894}
3895
3896TRACEME_LWPINFO(traceme_lwpinfo0, 0)
3897TRACEME_LWPINFO(traceme_lwpinfo1, 1)
3898TRACEME_LWPINFO(traceme_lwpinfo2, 2)
3899TRACEME_LWPINFO(traceme_lwpinfo3, 3)
3900
3901/// ----------------------------------------------------------------------------
3902
3903#if defined(TWAIT_HAVE_PID)
3904static void
3905attach_lwpinfo(const int threads)
3906{
3907	const int sigval = SIGINT;
3908	struct msg_fds parent_tracee, parent_tracer;
3909	const int exitval_tracer = 10;
3910	pid_t tracee, tracer, wpid;
3911	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3912#if defined(TWAIT_HAVE_STATUS)
3913	int status;
3914#endif
3915	struct ptrace_lwpinfo lwp = {0, 0};
3916	struct ptrace_siginfo info;
3917
3918	/* Maximum number of supported threads in this test */
3919	pthread_t t[3];
3920	int n, rv;
3921
3922	DPRINTF("Spawn tracee\n");
3923	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3924	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3925	tracee = atf_utils_fork();
3926	if (tracee == 0) {
3927		/* Wait for message from the parent */
3928		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
3929
3930		CHILD_FROM_PARENT("spawn threads", parent_tracee, msg);
3931
3932		for (n = 0; n < threads; n++) {
3933			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
3934			FORKEE_ASSERT(rv == 0);
3935		}
3936
3937		CHILD_TO_PARENT("tracee exit", parent_tracee, msg);
3938
3939		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3940		FORKEE_ASSERT(raise(sigval) == 0);
3941
3942		/* NOTREACHED */
3943		FORKEE_ASSERTX(0 && "Not reached");
3944	}
3945	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
3946
3947	DPRINTF("Spawn debugger\n");
3948	tracer = atf_utils_fork();
3949	if (tracer == 0) {
3950		/* No IPC to communicate with the child */
3951		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3952		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3953
3954		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3955		FORKEE_REQUIRE_SUCCESS(
3956		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3957
3958		forkee_status_stopped(status, SIGSTOP);
3959
3960		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
3961		    "tracee");
3962		FORKEE_ASSERT(
3963		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
3964
3965		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3966		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3967		    "si_errno=%#x\n",
3968		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3969		    info.psi_siginfo.si_errno);
3970
3971		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
3972		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
3973
3974		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3975		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
3976		    != -1);
3977
3978		DPRINTF("Assert that there exists a thread\n");
3979		FORKEE_ASSERTX(lwp.pl_lwpid > 0);
3980
3981		DPRINTF("Assert that lwp thread %d received event "
3982		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
3983		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
3984
3985		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
3986		    "tracee\n");
3987		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
3988		    != -1);
3989
3990		DPRINTF("Assert that there are no more lwp threads in "
3991		    "tracee\n");
3992		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
3993
3994		/* Resume tracee with PT_CONTINUE */
3995		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3996
3997		/* Inform parent that tracer has attached to tracee */
3998		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3999
4000		/* Wait for parent */
4001		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
4002
4003		/* Wait for tracee and assert that it raised a signal */
4004		FORKEE_REQUIRE_SUCCESS(
4005		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4006
4007		forkee_status_stopped(status, SIGINT);
4008
4009		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4010		    "child");
4011		FORKEE_ASSERT(
4012		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
4013
4014		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4015		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4016		    "si_errno=%#x\n",
4017		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4018		    info.psi_siginfo.si_errno);
4019
4020		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
4021		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
4022
4023		memset(&lwp, 0, sizeof(lwp));
4024
4025		for (n = 0; n <= threads; n++) {
4026			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
4027			    "child\n");
4028			FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp,
4029			    sizeof(lwp)) != -1);
4030			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4031
4032			DPRINTF("Assert that the thread exists\n");
4033			FORKEE_ASSERT(lwp.pl_lwpid > 0);
4034
4035			DPRINTF("Assert that lwp thread %d received expected "
4036			    "event\n", lwp.pl_lwpid);
4037			FORKEE_ASSERT_EQ(lwp.pl_event,
4038			    info.psi_lwpid == lwp.pl_lwpid ?
4039			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
4040		}
4041		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
4042		    "tracee\n");
4043		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
4044		    != -1);
4045		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4046
4047		DPRINTF("Assert that there are no more threads\n");
4048		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
4049
4050		DPRINTF("Before resuming the child process where it left off "
4051		    "and without signal to be sent\n");
4052		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL)
4053		    != -1);
4054
4055		/* Wait for tracee and assert that it exited */
4056		FORKEE_REQUIRE_SUCCESS(
4057		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4058
4059		forkee_status_signaled(status, SIGKILL, 0);
4060
4061		DPRINTF("Before exiting of the tracer process\n");
4062		_exit(exitval_tracer);
4063	}
4064
4065	DPRINTF("Wait for the tracer to attach to the tracee\n");
4066	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
4067
4068	DPRINTF("Resume the tracee and spawn threads\n");
4069	PARENT_TO_CHILD("spawn threads", parent_tracee, msg);
4070
4071	DPRINTF("Resume the tracee and let it exit\n");
4072	PARENT_FROM_CHILD("tracee exit", parent_tracee, msg);
4073
4074	DPRINTF("Resume the tracer and let it detect multiple threads\n");
4075	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
4076
4077	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
4078	    TWAIT_FNAME);
4079	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
4080	    tracer);
4081
4082	validate_status_exited(status, exitval_tracer);
4083
4084	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4085	    TWAIT_FNAME);
4086	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4087	    tracee);
4088
4089	validate_status_signaled(status, SIGKILL, 0);
4090
4091	msg_close(&parent_tracer);
4092	msg_close(&parent_tracee);
4093}
4094
4095#define ATTACH_LWPINFO(test, threads)					\
4096ATF_TC(test);								\
4097ATF_TC_HEAD(test, tc)							\
4098{									\
4099	atf_tc_set_md_var(tc, "descr",					\
4100	    "Verify LWPINFO with the child with " #threads		\
4101	    " spawned extra threads (tracer is not the original "	\
4102	    "parent)");							\
4103}									\
4104									\
4105ATF_TC_BODY(test, tc)							\
4106{									\
4107									\
4108	attach_lwpinfo(threads);					\
4109}
4110
4111ATTACH_LWPINFO(attach_lwpinfo0, 0)
4112ATTACH_LWPINFO(attach_lwpinfo1, 1)
4113ATTACH_LWPINFO(attach_lwpinfo2, 2)
4114ATTACH_LWPINFO(attach_lwpinfo3, 3)
4115#endif
4116
4117/// ----------------------------------------------------------------------------
4118
4119static void
4120ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
4121{
4122	const int exitval = 5;
4123	const int sigval = SIGINT;
4124	const int sigfaked = SIGTRAP;
4125	const int sicodefaked = TRAP_BRKPT;
4126	pid_t child, wpid;
4127	struct sigaction sa;
4128#if defined(TWAIT_HAVE_STATUS)
4129	int status;
4130#endif
4131	struct ptrace_siginfo info;
4132	memset(&info, 0, sizeof(info));
4133
4134	DPRINTF("Before forking process PID=%d\n", getpid());
4135	SYSCALL_REQUIRE((child = fork()) != -1);
4136	if (child == 0) {
4137		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4138		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4139
4140		sa.sa_sigaction = sah;
4141		sa.sa_flags = SA_SIGINFO;
4142		sigemptyset(&sa.sa_mask);
4143
4144		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
4145		    != -1);
4146
4147		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4148		FORKEE_ASSERT(raise(sigval) == 0);
4149
4150		FORKEE_ASSERT_EQ(*signal_caught, 1);
4151
4152		DPRINTF("Before exiting of the child process\n");
4153		_exit(exitval);
4154	}
4155	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4156
4157	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4158	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4159
4160	validate_status_stopped(status, sigval);
4161
4162	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4163	SYSCALL_REQUIRE(
4164	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4165
4166	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4167	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4168	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4169	    info.psi_siginfo.si_errno);
4170
4171	if (faked) {
4172		DPRINTF("Before setting new faked signal to signo=%d "
4173		    "si_code=%d\n", sigfaked, sicodefaked);
4174		info.psi_siginfo.si_signo = sigfaked;
4175		info.psi_siginfo.si_code = sicodefaked;
4176	}
4177
4178	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
4179	SYSCALL_REQUIRE(
4180	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
4181
4182	if (faked) {
4183		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4184		    "child\n");
4185		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
4186		    sizeof(info)) != -1);
4187
4188		DPRINTF("Before checking siginfo_t\n");
4189		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
4190		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
4191	}
4192
4193	DPRINTF("Before resuming the child process where it left off and "
4194	    "without signal to be sent\n");
4195	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
4196	    faked ? sigfaked : sigval) != -1);
4197
4198	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4199	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4200
4201	validate_status_exited(status, exitval);
4202
4203	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4204	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4205}
4206
4207#define PTRACE_SIGINFO(test, faked)					\
4208ATF_TC(test);								\
4209ATF_TC_HEAD(test, tc)							\
4210{									\
4211	atf_tc_set_md_var(tc, "descr",					\
4212	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
4213	    "with%s setting signal to new value", faked ? "" : "out");	\
4214}									\
4215									\
4216static int test##_caught = 0;						\
4217									\
4218static void								\
4219test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
4220{									\
4221	if (faked) {							\
4222		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
4223		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
4224		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
4225	} else {							\
4226		FORKEE_ASSERT_EQ(sig, SIGINT);				\
4227		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
4228		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
4229	}								\
4230									\
4231	++ test##_caught;						\
4232}									\
4233									\
4234ATF_TC_BODY(test, tc)							\
4235{									\
4236									\
4237	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
4238}
4239
4240PTRACE_SIGINFO(siginfo_set_unmodified, false)
4241PTRACE_SIGINFO(siginfo_set_faked, true)
4242
4243/// ----------------------------------------------------------------------------
4244
4245ATF_TC(traceme_exec);
4246ATF_TC_HEAD(traceme_exec, tc)
4247{
4248	atf_tc_set_md_var(tc, "descr",
4249	    "Detect SIGTRAP TRAP_EXEC from tracee");
4250}
4251
4252ATF_TC_BODY(traceme_exec, tc)
4253{
4254	const int sigval = SIGTRAP;
4255	pid_t child, wpid;
4256#if defined(TWAIT_HAVE_STATUS)
4257	int status;
4258#endif
4259
4260	struct ptrace_siginfo info;
4261	memset(&info, 0, sizeof(info));
4262
4263	DPRINTF("Before forking process PID=%d\n", getpid());
4264	SYSCALL_REQUIRE((child = fork()) != -1);
4265	if (child == 0) {
4266		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4267		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4268
4269		DPRINTF("Before calling execve(2) from child\n");
4270		execlp("/bin/echo", "/bin/echo", NULL);
4271
4272		FORKEE_ASSERT(0 && "Not reached");
4273	}
4274	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4275
4276	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4277	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4278
4279	validate_status_stopped(status, sigval);
4280
4281	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4282	SYSCALL_REQUIRE(
4283	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4284
4285	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4286	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4287	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4288	    info.psi_siginfo.si_errno);
4289
4290	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4291	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
4292
4293	DPRINTF("Before resuming the child process where it left off and "
4294	    "without signal to be sent\n");
4295	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4296
4297	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4298	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4299
4300	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4301	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4302}
4303
4304/// ----------------------------------------------------------------------------
4305
4306static volatile int done;
4307
4308static void *
4309trace_threads_cb(void *arg __unused)
4310{
4311
4312	done++;
4313
4314	while (done < 3)
4315		continue;
4316
4317	return NULL;
4318}
4319
4320static void
4321trace_threads(bool trace_create, bool trace_exit)
4322{
4323	const int sigval = SIGSTOP;
4324	pid_t child, wpid;
4325#if defined(TWAIT_HAVE_STATUS)
4326	int status;
4327#endif
4328	ptrace_state_t state;
4329	const int slen = sizeof(state);
4330	ptrace_event_t event;
4331	const int elen = sizeof(event);
4332	struct ptrace_siginfo info;
4333
4334	pthread_t t[3];
4335	int rv;
4336	size_t n;
4337	lwpid_t lid;
4338
4339	/* Track created and exited threads */
4340	bool traced_lwps[__arraycount(t)];
4341
4342	atf_tc_skip("PR kern/51995");
4343
4344	DPRINTF("Before forking process PID=%d\n", getpid());
4345	SYSCALL_REQUIRE((child = fork()) != -1);
4346	if (child == 0) {
4347		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4348		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4349
4350		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4351		FORKEE_ASSERT(raise(sigval) == 0);
4352
4353		for (n = 0; n < __arraycount(t); n++) {
4354			rv = pthread_create(&t[n], NULL, trace_threads_cb,
4355			    NULL);
4356			FORKEE_ASSERT(rv == 0);
4357		}
4358
4359		for (n = 0; n < __arraycount(t); n++) {
4360			rv = pthread_join(t[n], NULL);
4361			FORKEE_ASSERT(rv == 0);
4362		}
4363
4364		/*
4365		 * There is race between _exit() and pthread_join() detaching
4366		 * a thread. For simplicity kill the process after detecting
4367		 * LWP events.
4368		 */
4369		while (true)
4370			continue;
4371
4372		FORKEE_ASSERT(0 && "Not reached");
4373	}
4374	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4375
4376	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4377	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4378
4379	validate_status_stopped(status, sigval);
4380
4381	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4382	SYSCALL_REQUIRE(
4383	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4384
4385	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4386	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4387	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4388	    info.psi_siginfo.si_errno);
4389
4390	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4391	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4392
4393	DPRINTF("Set LWP event mask for the child %d\n", child);
4394	memset(&event, 0, sizeof(event));
4395	if (trace_create)
4396		event.pe_set_event |= PTRACE_LWP_CREATE;
4397	if (trace_exit)
4398		event.pe_set_event |= PTRACE_LWP_EXIT;
4399	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
4400
4401	DPRINTF("Before resuming the child process where it left off and "
4402	    "without signal to be sent\n");
4403	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4404
4405	memset(traced_lwps, 0, sizeof(traced_lwps));
4406
4407	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
4408		DPRINTF("Before calling %s() for the child - expected stopped "
4409		    "SIGTRAP\n", TWAIT_FNAME);
4410		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4411		    child);
4412
4413		validate_status_stopped(status, SIGTRAP);
4414
4415		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4416		    "child\n");
4417		SYSCALL_REQUIRE(
4418		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4419
4420		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4421		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4422		    "si_errno=%#x\n",
4423		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4424		    info.psi_siginfo.si_errno);
4425
4426		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4427		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4428
4429		SYSCALL_REQUIRE(
4430		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4431
4432		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
4433		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
4434
4435		lid = state.pe_lwp;
4436		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
4437
4438		traced_lwps[lid - 1] = true;
4439
4440		DPRINTF("Before resuming the child process where it left off "
4441		    "and without signal to be sent\n");
4442		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4443	}
4444
4445	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
4446		DPRINTF("Before calling %s() for the child - expected stopped "
4447		    "SIGTRAP\n", TWAIT_FNAME);
4448		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4449		    child);
4450
4451		validate_status_stopped(status, SIGTRAP);
4452
4453		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4454		    "child\n");
4455		SYSCALL_REQUIRE(
4456		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4457
4458		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4459		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4460		    "si_errno=%#x\n",
4461		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4462		    info.psi_siginfo.si_errno);
4463
4464		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4465		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4466
4467		SYSCALL_REQUIRE(
4468		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4469
4470		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
4471		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
4472
4473		lid = state.pe_lwp;
4474		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
4475
4476		if (trace_create) {
4477			ATF_REQUIRE(traced_lwps[lid - 1] == true);
4478			traced_lwps[lid - 1] = false;
4479		}
4480
4481		DPRINTF("Before resuming the child process where it left off "
4482		    "and without signal to be sent\n");
4483		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4484	}
4485
4486	kill(child, SIGKILL);
4487
4488	DPRINTF("Before calling %s() for the child - expected exited\n",
4489	    TWAIT_FNAME);
4490	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4491
4492	validate_status_signaled(status, SIGKILL, 0);
4493
4494	DPRINTF("Before calling %s() for the child - expected no process\n",
4495	    TWAIT_FNAME);
4496	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4497}
4498
4499#define TRACE_THREADS(test, trace_create, trace_exit)			\
4500ATF_TC(test);								\
4501ATF_TC_HEAD(test, tc)							\
4502{									\
4503        atf_tc_set_md_var(tc, "descr",					\
4504            "Verify spawning threads with%s tracing LWP create and"	\
4505	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
4506	    trace_exit ? "" : "out");					\
4507}									\
4508									\
4509ATF_TC_BODY(test, tc)							\
4510{									\
4511									\
4512        trace_threads(trace_create, trace_exit);			\
4513}
4514
4515TRACE_THREADS(trace_thread1, false, false)
4516TRACE_THREADS(trace_thread2, false, true)
4517TRACE_THREADS(trace_thread3, true, false)
4518TRACE_THREADS(trace_thread4, true, true)
4519
4520/// ----------------------------------------------------------------------------
4521
4522ATF_TC(signal_mask_unrelated);
4523ATF_TC_HEAD(signal_mask_unrelated, tc)
4524{
4525	atf_tc_set_md_var(tc, "descr",
4526	    "Verify that masking single unrelated signal does not stop tracer "
4527	    "from catching other signals");
4528}
4529
4530ATF_TC_BODY(signal_mask_unrelated, tc)
4531{
4532	const int exitval = 5;
4533	const int sigval = SIGSTOP;
4534	const int sigmasked = SIGTRAP;
4535	const int signotmasked = SIGINT;
4536	pid_t child, wpid;
4537#if defined(TWAIT_HAVE_STATUS)
4538	int status;
4539#endif
4540	sigset_t intmask;
4541
4542	DPRINTF("Before forking process PID=%d\n", getpid());
4543	SYSCALL_REQUIRE((child = fork()) != -1);
4544	if (child == 0) {
4545		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4546		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4547
4548		sigemptyset(&intmask);
4549		sigaddset(&intmask, sigmasked);
4550		sigprocmask(SIG_BLOCK, &intmask, NULL);
4551
4552		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4553		FORKEE_ASSERT(raise(sigval) == 0);
4554
4555		DPRINTF("Before raising %s from child\n",
4556		    strsignal(signotmasked));
4557		FORKEE_ASSERT(raise(signotmasked) == 0);
4558
4559		DPRINTF("Before exiting of the child process\n");
4560		_exit(exitval);
4561	}
4562	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4563
4564	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4565	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4566
4567	validate_status_stopped(status, sigval);
4568
4569	DPRINTF("Before resuming the child process where it left off and "
4570	    "without signal to be sent\n");
4571	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4572
4573	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4574	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4575
4576	validate_status_stopped(status, signotmasked);
4577
4578	DPRINTF("Before resuming the child process where it left off and "
4579	    "without signal to be sent\n");
4580	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4581
4582	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4583	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4584
4585	validate_status_exited(status, exitval);
4586
4587	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4588	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4589}
4590
4591/// ----------------------------------------------------------------------------
4592
4593#if defined(PT_STEP)
4594ATF_TC(signal4);
4595ATF_TC_HEAD(signal4, tc)
4596{
4597	atf_tc_set_md_var(tc, "descr",
4598	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
4599	    "catching single step trap");
4600}
4601
4602ATF_TC_BODY(signal4, tc)
4603{
4604	const int exitval = 5;
4605	const int sigval = SIGSTOP;
4606	const int sigmasked = SIGTRAP;
4607	pid_t child, wpid;
4608#if defined(TWAIT_HAVE_STATUS)
4609	int status;
4610#endif
4611	sigset_t intmask;
4612	int happy;
4613
4614#if defined(__arm__)
4615	/* PT_STEP not supported on arm 32-bit */
4616	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
4617#endif
4618
4619	DPRINTF("Before forking process PID=%d\n", getpid());
4620	SYSCALL_REQUIRE((child = fork()) != -1);
4621	if (child == 0) {
4622		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4623		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4624
4625		happy = check_happy(100);
4626
4627		sigemptyset(&intmask);
4628		sigaddset(&intmask, sigmasked);
4629		sigprocmask(SIG_BLOCK, &intmask, NULL);
4630
4631		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4632		FORKEE_ASSERT(raise(sigval) == 0);
4633
4634		FORKEE_ASSERT_EQ(happy, check_happy(100));
4635
4636		DPRINTF("Before exiting of the child process\n");
4637		_exit(exitval);
4638	}
4639	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4640
4641	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4642	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4643
4644	validate_status_stopped(status, sigval);
4645
4646	DPRINTF("Before resuming the child process where it left off and "
4647	    "without signal to be sent\n");
4648	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4649
4650	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4651	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4652
4653	validate_status_stopped(status, sigmasked);
4654
4655	DPRINTF("Before resuming the child process where it left off and "
4656	    "without signal to be sent\n");
4657	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4658
4659	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4660	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4661
4662	validate_status_exited(status, exitval);
4663
4664	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4665	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4666}
4667#endif
4668
4669ATF_TC(signal5);
4670ATF_TC_HEAD(signal5, tc)
4671{
4672	atf_tc_set_md_var(tc, "descr",
4673	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
4674	    "catching exec() breakpoint");
4675}
4676
4677ATF_TC_BODY(signal5, tc)
4678{
4679	const int sigval = SIGSTOP;
4680	const int sigmasked = SIGTRAP;
4681	pid_t child, wpid;
4682#if defined(TWAIT_HAVE_STATUS)
4683	int status;
4684#endif
4685	struct ptrace_siginfo info;
4686	sigset_t intmask;
4687
4688	memset(&info, 0, sizeof(info));
4689
4690	DPRINTF("Before forking process PID=%d\n", getpid());
4691	SYSCALL_REQUIRE((child = fork()) != -1);
4692	if (child == 0) {
4693		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4694		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4695
4696		sigemptyset(&intmask);
4697		sigaddset(&intmask, sigmasked);
4698		sigprocmask(SIG_BLOCK, &intmask, NULL);
4699
4700		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4701		FORKEE_ASSERT(raise(sigval) == 0);
4702
4703		DPRINTF("Before calling execve(2) from child\n");
4704		execlp("/bin/echo", "/bin/echo", NULL);
4705
4706		/* NOTREACHED */
4707		FORKEE_ASSERTX(0 && "Not reached");
4708	}
4709	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4710
4711	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4712	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4713
4714	validate_status_stopped(status, sigval);
4715
4716	DPRINTF("Before resuming the child process where it left off and "
4717	    "without signal to be sent\n");
4718	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4719
4720	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4721	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4722
4723	validate_status_stopped(status, sigmasked);
4724
4725	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4726	SYSCALL_REQUIRE(
4727	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4728
4729	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4730	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4731	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4732	    info.psi_siginfo.si_errno);
4733
4734	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked);
4735	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
4736
4737	DPRINTF("Before resuming the child process where it left off and "
4738	    "without signal to be sent\n");
4739	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4740
4741	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4742	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4743
4744	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4745	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4746}
4747
4748#if defined(TWAIT_HAVE_PID)
4749ATF_TC(signal6);
4750ATF_TC_HEAD(signal6, tc)
4751{
4752	atf_tc_set_md_var(tc, "timeout", "5");
4753	atf_tc_set_md_var(tc, "descr",
4754	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
4755	    "catching PTRACE_FORK breakpoint");
4756}
4757
4758ATF_TC_BODY(signal6, tc)
4759{
4760	const int exitval = 5;
4761	const int exitval2 = 15;
4762	const int sigval = SIGSTOP;
4763	const int sigmasked = SIGTRAP;
4764	pid_t child, child2, wpid;
4765#if defined(TWAIT_HAVE_STATUS)
4766	int status;
4767#endif
4768	sigset_t intmask;
4769	ptrace_state_t state;
4770	const int slen = sizeof(state);
4771	ptrace_event_t event;
4772	const int elen = sizeof(event);
4773
4774	atf_tc_expect_fail("PR kern/51918");
4775
4776	DPRINTF("Before forking process PID=%d\n", getpid());
4777	SYSCALL_REQUIRE((child = fork()) != -1);
4778	if (child == 0) {
4779		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4780		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4781
4782		sigemptyset(&intmask);
4783		sigaddset(&intmask, sigmasked);
4784		sigprocmask(SIG_BLOCK, &intmask, NULL);
4785
4786		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4787		FORKEE_ASSERT(raise(sigval) == 0);
4788
4789		FORKEE_ASSERT((child2 = fork()) != -1);
4790
4791		if (child2 == 0)
4792			_exit(exitval2);
4793
4794		FORKEE_REQUIRE_SUCCESS
4795			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
4796
4797		forkee_status_exited(status, exitval2);
4798
4799		DPRINTF("Before exiting of the child process\n");
4800		_exit(exitval);
4801	}
4802	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4803
4804	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4805	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4806
4807	validate_status_stopped(status, sigval);
4808
4809	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
4810	event.pe_set_event = PTRACE_FORK;
4811	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
4812
4813	DPRINTF("Before resuming the child process where it left off and "
4814	    "without signal to be sent\n");
4815	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4816
4817	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4818	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4819
4820	validate_status_stopped(status, sigmasked);
4821
4822	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4823	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
4824
4825	child2 = state.pe_other_pid;
4826	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
4827
4828	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
4829	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
4830	    child2);
4831
4832	validate_status_stopped(status, SIGTRAP);
4833
4834	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
4835	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
4836	ATF_REQUIRE_EQ(state.pe_other_pid, child);
4837
4838	DPRINTF("Before resuming the forkee process where it left off and "
4839	    "without signal to be sent\n");
4840	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
4841
4842	DPRINTF("Before resuming the child process where it left off and "
4843	    "without signal to be sent\n");
4844	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4845
4846	DPRINTF("Before calling %s() for the forkee - expected exited\n",
4847	    TWAIT_FNAME);
4848	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
4849	    child2);
4850
4851	validate_status_exited(status, exitval2);
4852
4853	DPRINTF("Before calling %s() for the forkee - expected no process\n",
4854	    TWAIT_FNAME);
4855	TWAIT_REQUIRE_FAILURE(ECHILD,
4856	    wpid = TWAIT_GENERIC(child2, &status, 0));
4857
4858	DPRINTF("Before calling %s() for the child - expected stopped "
4859	    "SIGCHLD\n", TWAIT_FNAME);
4860	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4861
4862	validate_status_stopped(status, SIGCHLD);
4863
4864	DPRINTF("Before resuming the child process where it left off and "
4865	    "without signal to be sent\n");
4866	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4867
4868	DPRINTF("Before calling %s() for the child - expected exited\n",
4869	    TWAIT_FNAME);
4870	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4871
4872	validate_status_exited(status, exitval);
4873
4874	DPRINTF("Before calling %s() for the child - expected no process\n",
4875	    TWAIT_FNAME);
4876	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4877}
4878#endif
4879
4880#if defined(TWAIT_HAVE_PID)
4881ATF_TC(signal7);
4882ATF_TC_HEAD(signal7, tc)
4883{
4884	atf_tc_set_md_var(tc, "descr",
4885	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
4886	    "catching PTRACE_VFORK breakpoint");
4887}
4888
4889ATF_TC_BODY(signal7, tc)
4890{
4891	const int exitval = 5;
4892	const int exitval2 = 15;
4893	const int sigval = SIGSTOP;
4894	const int sigmasked = SIGTRAP;
4895	pid_t child, child2, wpid;
4896#if defined(TWAIT_HAVE_STATUS)
4897	int status;
4898#endif
4899	sigset_t intmask;
4900	ptrace_state_t state;
4901	const int slen = sizeof(state);
4902	ptrace_event_t event;
4903	const int elen = sizeof(event);
4904
4905	atf_tc_expect_fail("PR kern/51918");
4906
4907	DPRINTF("Before forking process PID=%d\n", getpid());
4908	SYSCALL_REQUIRE((child = fork()) != -1);
4909	if (child == 0) {
4910		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4911		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4912
4913		sigemptyset(&intmask);
4914		sigaddset(&intmask, sigmasked);
4915		sigprocmask(SIG_BLOCK, &intmask, NULL);
4916
4917		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4918		FORKEE_ASSERT(raise(sigval) == 0);
4919
4920		FORKEE_ASSERT((child2 = fork()) != -1);
4921
4922		if (child2 == 0)
4923			_exit(exitval2);
4924
4925		FORKEE_REQUIRE_SUCCESS
4926			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
4927
4928		forkee_status_exited(status, exitval2);
4929
4930		DPRINTF("Before exiting of the child process\n");
4931		_exit(exitval);
4932	}
4933	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4934
4935	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4936	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4937
4938	validate_status_stopped(status, sigval);
4939
4940	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
4941	event.pe_set_event = PTRACE_VFORK;
4942	SYSCALL_REQUIRE(
4943	    ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 ||
4944	    errno == ENOTSUP);
4945
4946	DPRINTF("Before resuming the child process where it left off and "
4947	    "without signal to be sent\n");
4948	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4949
4950	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4951	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4952
4953	validate_status_stopped(status, sigmasked);
4954
4955	SYSCALL_REQUIRE(
4956	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4957	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
4958
4959	child2 = state.pe_other_pid;
4960	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
4961
4962	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
4963	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
4964	    child2);
4965
4966	validate_status_stopped(status, SIGTRAP);
4967
4968	SYSCALL_REQUIRE(
4969	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
4970	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
4971	ATF_REQUIRE_EQ(state.pe_other_pid, child);
4972
4973	DPRINTF("Before resuming the forkee process where it left off and "
4974	    "without signal to be sent\n");
4975	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
4976
4977	DPRINTF("Before resuming the child process where it left off and "
4978	    "without signal to be sent\n");
4979	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4980
4981	DPRINTF("Before calling %s() for the forkee - expected exited\n",
4982	    TWAIT_FNAME);
4983	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
4984	    child2);
4985
4986	validate_status_exited(status, exitval2);
4987
4988	DPRINTF("Before calling %s() for the forkee - expected no process\n",
4989	    TWAIT_FNAME);
4990	TWAIT_REQUIRE_FAILURE(ECHILD,
4991	    wpid = TWAIT_GENERIC(child2, &status, 0));
4992
4993	DPRINTF("Before calling %s() for the child - expected stopped "
4994	    "SIGCHLD\n", TWAIT_FNAME);
4995	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4996
4997	validate_status_stopped(status, SIGCHLD);
4998
4999	DPRINTF("Before resuming the child process where it left off and "
5000	    "without signal to be sent\n");
5001	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5002
5003	DPRINTF("Before calling %s() for the child - expected exited\n",
5004	    TWAIT_FNAME);
5005	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5006
5007	validate_status_exited(status, exitval);
5008
5009	DPRINTF("Before calling %s() for the child - expected no process\n",
5010	    TWAIT_FNAME);
5011	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5012}
5013#endif
5014
5015ATF_TC(signal8);
5016ATF_TC_HEAD(signal8, tc)
5017{
5018	atf_tc_set_md_var(tc, "descr",
5019	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5020	    "catching PTRACE_VFORK_DONE breakpoint");
5021}
5022
5023ATF_TC_BODY(signal8, tc)
5024{
5025	const int exitval = 5;
5026	const int exitval2 = 15;
5027	const int sigval = SIGSTOP;
5028	const int sigmasked = SIGTRAP;
5029	pid_t child, child2, wpid;
5030#if defined(TWAIT_HAVE_STATUS)
5031	int status;
5032#endif
5033	sigset_t intmask;
5034	ptrace_state_t state;
5035	const int slen = sizeof(state);
5036	ptrace_event_t event;
5037	const int elen = sizeof(event);
5038
5039	atf_tc_expect_fail("PR kern/51918");
5040
5041	DPRINTF("Before forking process PID=%d\n", getpid());
5042	SYSCALL_REQUIRE((child = fork()) != -1);
5043	if (child == 0) {
5044		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5045		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5046
5047		sigemptyset(&intmask);
5048		sigaddset(&intmask, sigmasked);
5049		sigprocmask(SIG_BLOCK, &intmask, NULL);
5050
5051		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5052		FORKEE_ASSERT(raise(sigval) == 0);
5053
5054		FORKEE_ASSERT((child2 = vfork()) != -1);
5055
5056		if (child2 == 0)
5057			_exit(exitval2);
5058
5059		FORKEE_REQUIRE_SUCCESS
5060			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
5061
5062		forkee_status_exited(status, exitval2);
5063
5064		DPRINTF("Before exiting of the child process\n");
5065		_exit(exitval);
5066	}
5067	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5068
5069	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5070	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5071
5072	validate_status_stopped(status, sigval);
5073
5074	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
5075	    child);
5076	event.pe_set_event = PTRACE_VFORK_DONE;
5077	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5078
5079	DPRINTF("Before resuming the child process where it left off and "
5080	    "without signal to be sent\n");
5081	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5082
5083	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5084	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5085
5086	validate_status_stopped(status, sigmasked);
5087
5088	SYSCALL_REQUIRE(
5089	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5090	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
5091
5092	child2 = state.pe_other_pid;
5093	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
5094
5095	DPRINTF("Before resuming the child process where it left off and "
5096	    "without signal to be sent\n");
5097	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5098
5099	DPRINTF("Before calling %s() for the child - expected stopped "
5100	    "SIGCHLD\n", TWAIT_FNAME);
5101	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5102
5103	validate_status_stopped(status, SIGCHLD);
5104
5105	DPRINTF("Before resuming the child process where it left off and "
5106	    "without signal to be sent\n");
5107	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5108
5109	DPRINTF("Before calling %s() for the child - expected exited\n",
5110	    TWAIT_FNAME);
5111	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5112
5113	validate_status_exited(status, exitval);
5114
5115	DPRINTF("Before calling %s() for the child - expected no process\n",
5116	    TWAIT_FNAME);
5117	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5118}
5119
5120volatile lwpid_t the_lwp_id = 0;
5121
5122static void
5123lwp_main_func(void *arg)
5124{
5125	the_lwp_id = _lwp_self();
5126	_lwp_exit();
5127}
5128
5129ATF_TC(signal9);
5130ATF_TC_HEAD(signal9, tc)
5131{
5132	atf_tc_set_md_var(tc, "descr",
5133	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5134	    "catching PTRACE_LWP_CREATE breakpoint");
5135}
5136
5137ATF_TC_BODY(signal9, tc)
5138{
5139	const int exitval = 5;
5140	const int sigval = SIGSTOP;
5141	const int sigmasked = SIGTRAP;
5142	pid_t child, wpid;
5143#if defined(TWAIT_HAVE_STATUS)
5144	int status;
5145#endif
5146	sigset_t intmask;
5147	ptrace_state_t state;
5148	const int slen = sizeof(state);
5149	ptrace_event_t event;
5150	const int elen = sizeof(event);
5151	ucontext_t uc;
5152	lwpid_t lid;
5153	static const size_t ssize = 16*1024;
5154	void *stack;
5155
5156	atf_tc_expect_fail("PR kern/51918");
5157
5158	DPRINTF("Before forking process PID=%d\n", getpid());
5159	SYSCALL_REQUIRE((child = fork()) != -1);
5160	if (child == 0) {
5161		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5162		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5163
5164		sigemptyset(&intmask);
5165		sigaddset(&intmask, sigmasked);
5166		sigprocmask(SIG_BLOCK, &intmask, NULL);
5167
5168		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5169		FORKEE_ASSERT(raise(sigval) == 0);
5170
5171		DPRINTF("Before allocating memory for stack in child\n");
5172		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5173
5174		DPRINTF("Before making context for new lwp in child\n");
5175		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5176
5177		DPRINTF("Before creating new in child\n");
5178		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5179
5180		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5181		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5182
5183		DPRINTF("Before verifying that reported %d and running lid %d "
5184		    "are the same\n", lid, the_lwp_id);
5185		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5186
5187		DPRINTF("Before exiting of the child process\n");
5188		_exit(exitval);
5189	}
5190	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5191
5192	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5193	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5194
5195	validate_status_stopped(status, sigval);
5196
5197	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
5198	event.pe_set_event = PTRACE_LWP_CREATE;
5199	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5200
5201	DPRINTF("Before resuming the child process where it left off and "
5202	    "without signal to be sent\n");
5203	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5204
5205	DPRINTF("Before calling %s() for the child - expected stopped "
5206	    "SIGTRAP\n", TWAIT_FNAME);
5207	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5208
5209	validate_status_stopped(status, sigmasked);
5210
5211	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5212
5213	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
5214
5215	lid = state.pe_lwp;
5216	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
5217
5218	DPRINTF("Before resuming the child process where it left off and "
5219	    "without signal to be sent\n");
5220	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5221
5222	DPRINTF("Before calling %s() for the child - expected exited\n",
5223	    TWAIT_FNAME);
5224	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5225
5226	validate_status_exited(status, exitval);
5227
5228	DPRINTF("Before calling %s() for the child - expected no process\n",
5229	    TWAIT_FNAME);
5230	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5231}
5232
5233ATF_TC(signal10);
5234ATF_TC_HEAD(signal10, tc)
5235{
5236	atf_tc_set_md_var(tc, "descr",
5237	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5238	    "catching PTRACE_LWP_EXIT breakpoint");
5239}
5240
5241ATF_TC_BODY(signal10, tc)
5242{
5243	const int exitval = 5;
5244	const int sigval = SIGSTOP;
5245	const int sigmasked = SIGTRAP;
5246	pid_t child, wpid;
5247#if defined(TWAIT_HAVE_STATUS)
5248	int status;
5249#endif
5250	sigset_t intmask;
5251	ptrace_state_t state;
5252	const int slen = sizeof(state);
5253	ptrace_event_t event;
5254	const int elen = sizeof(event);
5255	ucontext_t uc;
5256	lwpid_t lid;
5257	static const size_t ssize = 16*1024;
5258	void *stack;
5259
5260	atf_tc_expect_fail("PR kern/51918");
5261
5262	DPRINTF("Before forking process PID=%d\n", getpid());
5263	SYSCALL_REQUIRE((child = fork()) != -1);
5264	if (child == 0) {
5265		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5266		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5267
5268		sigemptyset(&intmask);
5269		sigaddset(&intmask, sigmasked);
5270		sigprocmask(SIG_BLOCK, &intmask, NULL);
5271
5272		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5273		FORKEE_ASSERT(raise(sigval) == 0);
5274
5275		DPRINTF("Before allocating memory for stack in child\n");
5276		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5277
5278		DPRINTF("Before making context for new lwp in child\n");
5279		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5280
5281		DPRINTF("Before creating new in child\n");
5282		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5283
5284		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5285		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5286
5287		DPRINTF("Before verifying that reported %d and running lid %d "
5288		    "are the same\n", lid, the_lwp_id);
5289		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5290
5291		DPRINTF("Before exiting of the child process\n");
5292		_exit(exitval);
5293	}
5294	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5295
5296	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5297	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5298
5299	validate_status_stopped(status, sigval);
5300
5301	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
5302	event.pe_set_event = PTRACE_LWP_EXIT;
5303	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5304
5305	DPRINTF("Before resuming the child process where it left off and "
5306	    "without signal to be sent\n");
5307	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5308
5309	DPRINTF("Before calling %s() for the child - expected stopped "
5310	    "SIGTRAP\n", TWAIT_FNAME);
5311	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5312
5313	validate_status_stopped(status, sigmasked);
5314
5315	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5316
5317	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
5318
5319	lid = state.pe_lwp;
5320	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
5321
5322	DPRINTF("Before resuming the child process where it left off and "
5323	    "without signal to be sent\n");
5324	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5325
5326	DPRINTF("Before calling %s() for the child - expected exited\n",
5327	    TWAIT_FNAME);
5328	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5329
5330	validate_status_exited(status, exitval);
5331
5332	DPRINTF("Before calling %s() for the child - expected no process\n",
5333	    TWAIT_FNAME);
5334	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5335}
5336
5337static void
5338lwp_main_stop(void *arg)
5339{
5340	the_lwp_id = _lwp_self();
5341
5342	raise(SIGTRAP);
5343
5344	_lwp_exit();
5345}
5346
5347ATF_TC(suspend1);
5348ATF_TC_HEAD(suspend1, tc)
5349{
5350	atf_tc_set_md_var(tc, "descr",
5351	    "Verify that a thread can be suspended by a debugger and later "
5352	    "resumed by a tracee");
5353}
5354
5355ATF_TC_BODY(suspend1, tc)
5356{
5357	const int exitval = 5;
5358	const int sigval = SIGSTOP;
5359	pid_t child, wpid;
5360#if defined(TWAIT_HAVE_STATUS)
5361	int status;
5362#endif
5363	ucontext_t uc;
5364	lwpid_t lid;
5365	static const size_t ssize = 16*1024;
5366	void *stack;
5367	struct ptrace_lwpinfo pl;
5368	struct ptrace_siginfo psi;
5369	volatile int go = 0;
5370
5371	// Feature pending for refactoring
5372	atf_tc_expect_fail("PR kern/51995");
5373
5374	// Hangs with qemu
5375	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5376
5377	DPRINTF("Before forking process PID=%d\n", getpid());
5378	SYSCALL_REQUIRE((child = fork()) != -1);
5379	if (child == 0) {
5380		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5381		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5382
5383		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5384		FORKEE_ASSERT(raise(sigval) == 0);
5385
5386		DPRINTF("Before allocating memory for stack in child\n");
5387		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5388
5389		DPRINTF("Before making context for new lwp in child\n");
5390		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
5391
5392		DPRINTF("Before creating new in child\n");
5393		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5394
5395		while (go == 0)
5396			continue;
5397
5398		raise(SIGINT);
5399
5400		FORKEE_ASSERT(_lwp_continue(lid) == 0);
5401
5402		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5403		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5404
5405		DPRINTF("Before verifying that reported %d and running lid %d "
5406		    "are the same\n", lid, the_lwp_id);
5407		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5408
5409		DPRINTF("Before exiting of the child process\n");
5410		_exit(exitval);
5411	}
5412	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5413
5414	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5415	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5416
5417	validate_status_stopped(status, sigval);
5418
5419	DPRINTF("Before resuming the child process where it left off and "
5420	    "without signal to be sent\n");
5421	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5422
5423	DPRINTF("Before calling %s() for the child - expected stopped "
5424	    "SIGTRAP\n", TWAIT_FNAME);
5425	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5426
5427	validate_status_stopped(status, SIGTRAP);
5428
5429	DPRINTF("Before reading siginfo and lwpid_t\n");
5430	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
5431
5432	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
5433	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
5434
5435        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
5436	    child, getpid());
5437	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
5438
5439	DPRINTF("Before resuming the child process where it left off and "
5440	    "without signal to be sent\n");
5441	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5442
5443	DPRINTF("Before calling %s() for the child - expected stopped "
5444	    "SIGINT\n", TWAIT_FNAME);
5445	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5446
5447	validate_status_stopped(status, SIGINT);
5448
5449	pl.pl_lwpid = 0;
5450
5451	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5452	while (pl.pl_lwpid != 0) {
5453
5454		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5455		switch (pl.pl_lwpid) {
5456		case 1:
5457			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
5458			break;
5459		case 2:
5460			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
5461			break;
5462		}
5463	}
5464
5465	DPRINTF("Before resuming the child process where it left off and "
5466	    "without signal to be sent\n");
5467	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5468
5469	DPRINTF("Before calling %s() for the child - expected exited\n",
5470	    TWAIT_FNAME);
5471	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5472
5473	validate_status_exited(status, exitval);
5474
5475	DPRINTF("Before calling %s() for the child - expected no process\n",
5476	    TWAIT_FNAME);
5477	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5478}
5479
5480ATF_TC(suspend2);
5481ATF_TC_HEAD(suspend2, tc)
5482{
5483	atf_tc_set_md_var(tc, "descr",
5484	    "Verify that the while the only thread within a process is "
5485	    "suspended, the whole process cannot be unstopped");
5486}
5487
5488ATF_TC_BODY(suspend2, tc)
5489{
5490	const int exitval = 5;
5491	const int sigval = SIGSTOP;
5492	pid_t child, wpid;
5493#if defined(TWAIT_HAVE_STATUS)
5494	int status;
5495#endif
5496	struct ptrace_siginfo psi;
5497
5498	// Feature pending for refactoring
5499	atf_tc_expect_fail("PR kern/51995");
5500
5501	// Hangs with qemu
5502	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5503
5504	DPRINTF("Before forking process PID=%d\n", getpid());
5505	SYSCALL_REQUIRE((child = fork()) != -1);
5506	if (child == 0) {
5507		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5508		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5509
5510		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5511		FORKEE_ASSERT(raise(sigval) == 0);
5512
5513		DPRINTF("Before exiting of the child process\n");
5514		_exit(exitval);
5515	}
5516	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5517
5518	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5519	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5520
5521	validate_status_stopped(status, sigval);
5522
5523	DPRINTF("Before reading siginfo and lwpid_t\n");
5524	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
5525
5526	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
5527	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
5528
5529	DPRINTF("Before resuming the child process where it left off and "
5530	    "without signal to be sent\n");
5531	ATF_REQUIRE_ERRNO(EDEADLK,
5532	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
5533
5534	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
5535	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
5536
5537	DPRINTF("Before resuming the child process where it left off and "
5538	    "without signal to be sent\n");
5539	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5540
5541	DPRINTF("Before calling %s() for the child - expected exited\n",
5542	    TWAIT_FNAME);
5543	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5544
5545	validate_status_exited(status, exitval);
5546
5547	DPRINTF("Before calling %s() for the child - expected no process\n",
5548	    TWAIT_FNAME);
5549	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5550}
5551
5552ATF_TC(resume1);
5553ATF_TC_HEAD(resume1, tc)
5554{
5555	atf_tc_set_md_var(tc, "timeout", "5");
5556	atf_tc_set_md_var(tc, "descr",
5557	    "Verify that a thread can be suspended by a debugger and later "
5558	    "resumed by the debugger");
5559}
5560
5561ATF_TC_BODY(resume1, tc)
5562{
5563	struct msg_fds fds;
5564	const int exitval = 5;
5565	const int sigval = SIGSTOP;
5566	pid_t child, wpid;
5567	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5568#if defined(TWAIT_HAVE_STATUS)
5569	int status;
5570#endif
5571	ucontext_t uc;
5572	lwpid_t lid;
5573	static const size_t ssize = 16*1024;
5574	void *stack;
5575	struct ptrace_lwpinfo pl;
5576	struct ptrace_siginfo psi;
5577
5578	// Feature pending for refactoring
5579	atf_tc_expect_fail("PR kern/51995");
5580
5581	// Hangs with qemu
5582	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5583
5584	SYSCALL_REQUIRE(msg_open(&fds) == 0);
5585
5586	DPRINTF("Before forking process PID=%d\n", getpid());
5587	SYSCALL_REQUIRE((child = fork()) != -1);
5588	if (child == 0) {
5589		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5590		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5591
5592		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5593		FORKEE_ASSERT(raise(sigval) == 0);
5594
5595		DPRINTF("Before allocating memory for stack in child\n");
5596		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5597
5598		DPRINTF("Before making context for new lwp in child\n");
5599		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
5600
5601		DPRINTF("Before creating new in child\n");
5602		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5603
5604		CHILD_TO_PARENT("Message", fds, msg);
5605
5606		raise(SIGINT);
5607
5608		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5609		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5610
5611		DPRINTF("Before verifying that reported %d and running lid %d "
5612		    "are the same\n", lid, the_lwp_id);
5613		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5614
5615		DPRINTF("Before exiting of the child process\n");
5616		_exit(exitval);
5617	}
5618	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5619
5620	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5621	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5622
5623	validate_status_stopped(status, sigval);
5624
5625	DPRINTF("Before resuming the child process where it left off and "
5626	    "without signal to be sent\n");
5627	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5628
5629	DPRINTF("Before calling %s() for the child - expected stopped "
5630	    "SIGTRAP\n", TWAIT_FNAME);
5631	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5632
5633	validate_status_stopped(status, SIGTRAP);
5634
5635	DPRINTF("Before reading siginfo and lwpid_t\n");
5636	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
5637
5638	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
5639	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
5640
5641	PARENT_FROM_CHILD("Message", fds, msg);
5642
5643	DPRINTF("Before resuming the child process where it left off and "
5644	    "without signal to be sent\n");
5645	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5646
5647	DPRINTF("Before calling %s() for the child - expected stopped "
5648	    "SIGINT\n", TWAIT_FNAME);
5649	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5650
5651	validate_status_stopped(status, SIGINT);
5652
5653	pl.pl_lwpid = 0;
5654
5655	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5656	while (pl.pl_lwpid != 0) {
5657		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5658		switch (pl.pl_lwpid) {
5659		case 1:
5660			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
5661			break;
5662		case 2:
5663			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
5664			break;
5665		}
5666	}
5667
5668	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
5669	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
5670
5671	DPRINTF("Before resuming the child process where it left off and "
5672	    "without signal to be sent\n");
5673	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5674
5675	DPRINTF("Before calling %s() for the child - expected exited\n",
5676	    TWAIT_FNAME);
5677	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5678
5679	validate_status_exited(status, exitval);
5680
5681	DPRINTF("Before calling %s() for the child - expected no process\n",
5682	    TWAIT_FNAME);
5683	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5684
5685	msg_close(&fds);
5686
5687	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
5688	sleep(10);
5689}
5690
5691ATF_TC(syscall1);
5692ATF_TC_HEAD(syscall1, tc)
5693{
5694	atf_tc_set_md_var(tc, "descr",
5695	    "Verify that getpid(2) can be traced with PT_SYSCALL");
5696}
5697
5698ATF_TC_BODY(syscall1, tc)
5699{
5700	const int exitval = 5;
5701	const int sigval = SIGSTOP;
5702	pid_t child, wpid;
5703#if defined(TWAIT_HAVE_STATUS)
5704	int status;
5705#endif
5706	struct ptrace_siginfo info;
5707	memset(&info, 0, sizeof(info));
5708
5709	DPRINTF("Before forking process PID=%d\n", getpid());
5710	SYSCALL_REQUIRE((child = fork()) != -1);
5711	if (child == 0) {
5712		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5713		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5714
5715		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5716		FORKEE_ASSERT(raise(sigval) == 0);
5717
5718		syscall(SYS_getpid);
5719
5720		DPRINTF("Before exiting of the child process\n");
5721		_exit(exitval);
5722	}
5723	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5724
5725	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5726	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5727
5728	validate_status_stopped(status, sigval);
5729
5730	DPRINTF("Before resuming the child process where it left off and "
5731	    "without signal to be sent\n");
5732	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
5733
5734	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5735	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5736
5737	validate_status_stopped(status, SIGTRAP);
5738
5739	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5740	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5741
5742	DPRINTF("Before checking siginfo_t and lwpid\n");
5743	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
5744	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5745	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
5746
5747	DPRINTF("Before resuming the child process where it left off and "
5748	    "without signal to be sent\n");
5749	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
5750
5751	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5752	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5753
5754	validate_status_stopped(status, SIGTRAP);
5755
5756	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5757	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5758
5759	DPRINTF("Before checking siginfo_t and lwpid\n");
5760	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
5761	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5762	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
5763
5764	DPRINTF("Before resuming the child process where it left off and "
5765	    "without signal to be sent\n");
5766	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5767
5768	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5769	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5770
5771	validate_status_exited(status, exitval);
5772
5773	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5774	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5775}
5776
5777ATF_TC(syscallemu1);
5778ATF_TC_HEAD(syscallemu1, tc)
5779{
5780	atf_tc_set_md_var(tc, "descr",
5781	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
5782}
5783
5784ATF_TC_BODY(syscallemu1, tc)
5785{
5786	const int exitval = 5;
5787	const int sigval = SIGSTOP;
5788	pid_t child, wpid;
5789#if defined(TWAIT_HAVE_STATUS)
5790	int status;
5791#endif
5792
5793#if defined(__sparc__) && !defined(__sparc64__)
5794	/* syscallemu does not work on sparc (32-bit) */
5795	atf_tc_expect_fail("PR kern/52166");
5796#endif
5797
5798	DPRINTF("Before forking process PID=%d\n", getpid());
5799	SYSCALL_REQUIRE((child = fork()) != -1);
5800	if (child == 0) {
5801		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5802		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5803
5804		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5805		FORKEE_ASSERT(raise(sigval) == 0);
5806
5807		syscall(SYS_exit, 100);
5808
5809		DPRINTF("Before exiting of the child process\n");
5810		_exit(exitval);
5811	}
5812	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5813
5814	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5815	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5816
5817	validate_status_stopped(status, sigval);
5818
5819	DPRINTF("Before resuming the child process where it left off and "
5820	    "without signal to be sent\n");
5821	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
5822
5823	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5824	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5825
5826	validate_status_stopped(status, SIGTRAP);
5827
5828	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
5829	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
5830
5831	DPRINTF("Before resuming the child process where it left off and "
5832	    "without signal to be sent\n");
5833	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
5834
5835	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5836	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5837
5838	validate_status_stopped(status, SIGTRAP);
5839
5840	DPRINTF("Before resuming the child process where it left off and "
5841	    "without signal to be sent\n");
5842	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5843
5844	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5845	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5846
5847	validate_status_exited(status, exitval);
5848
5849	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5850	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5851}
5852
5853#include "t_ptrace_amd64_wait.h"
5854#include "t_ptrace_i386_wait.h"
5855#include "t_ptrace_x86_wait.h"
5856
5857ATF_TP_ADD_TCS(tp)
5858{
5859	setvbuf(stdout, NULL, _IONBF, 0);
5860	setvbuf(stderr, NULL, _IONBF, 0);
5861
5862	ATF_TP_ADD_TC(tp, traceme_raise1);
5863	ATF_TP_ADD_TC(tp, traceme_raise2);
5864	ATF_TP_ADD_TC(tp, traceme_raise3);
5865	ATF_TP_ADD_TC(tp, traceme_raise4);
5866	ATF_TP_ADD_TC(tp, traceme_raise5);
5867	ATF_TP_ADD_TC(tp, traceme_raise6);
5868	ATF_TP_ADD_TC(tp, traceme_raise7);
5869	ATF_TP_ADD_TC(tp, traceme_raise8);
5870	ATF_TP_ADD_TC(tp, traceme_raise9);
5871	ATF_TP_ADD_TC(tp, traceme_raise10);
5872
5873	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1);
5874	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2);
5875	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3);
5876	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4);
5877	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5);
5878	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6);
5879	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7);
5880	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8);
5881
5882	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1);
5883	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2);
5884	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3);
5885	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4);
5886	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5);
5887	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6);
5888	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7);
5889	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8);
5890
5891	ATF_TP_ADD_TC(tp, traceme_crash_trap);
5892	ATF_TP_ADD_TC(tp, traceme_crash_segv);
5893	ATF_TP_ADD_TC(tp, traceme_crash_ill);
5894	ATF_TP_ADD_TC(tp, traceme_crash_fpe);
5895	ATF_TP_ADD_TC(tp, traceme_crash_bus);
5896
5897	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap);
5898	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv);
5899	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill);
5900	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe);
5901	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus);
5902
5903	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap);
5904	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv);
5905	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill);
5906	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe);
5907	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus);
5908
5909	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1);
5910	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2);
5911	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3);
5912	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4);
5913	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5);
5914	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6);
5915	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7);
5916	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8);
5917
5918	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1);
5919	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2);
5920	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3);
5921	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4);
5922	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5);
5923	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6);
5924	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7);
5925	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8);
5926
5927	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1);
5928	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2);
5929	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3);
5930	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4);
5931	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5);
5932	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6);
5933	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7);
5934	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8);
5935
5936	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1);
5937	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2);
5938	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3);
5939	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4);
5940	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5);
5941	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6);
5942	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7);
5943	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8);
5944	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9);
5945	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10);
5946
5947	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
5948
5949	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
5950	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
5951	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
5952	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
5953	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
5954	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
5955	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
5956	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
5957	ATF_TP_ADD_TC(tp, traceme_vfork_raise9);
5958	ATF_TP_ADD_TC(tp, traceme_vfork_raise10);
5959	ATF_TP_ADD_TC(tp, traceme_vfork_raise11);
5960	ATF_TP_ADD_TC(tp, traceme_vfork_raise12);
5961	ATF_TP_ADD_TC(tp, traceme_vfork_raise13);
5962
5963	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap);
5964	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv);
5965	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill);
5966	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe);
5967	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus);
5968
5969	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap);
5970	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv);
5971	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill);
5972	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe);
5973	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus);
5974
5975	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap);
5976	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv);
5977	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill);
5978	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe);
5979	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus);
5980
5981	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
5982
5983	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap);
5984	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv);
5985	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill);
5986	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe);
5987	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus);
5988
5989	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
5990	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
5991	ATF_TP_ADD_TC_HAVE_PID(tp,
5992		unrelated_tracer_sees_terminaton_before_the_parent);
5993	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
5994
5995	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
5996	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
5997
5998	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
5999	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
6000
6001	ATF_TP_ADD_TC_HAVE_PID(tp,
6002		tracee_sees_its_original_parent_getppid);
6003	ATF_TP_ADD_TC_HAVE_PID(tp,
6004		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
6005	ATF_TP_ADD_TC_HAVE_PID(tp,
6006		tracee_sees_its_original_parent_procfs_status);
6007
6008	ATF_TP_ADD_TC(tp, eventmask_preserved_empty);
6009	ATF_TP_ADD_TC(tp, eventmask_preserved_fork);
6010	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork);
6011	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done);
6012	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create);
6013	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit);
6014
6015	ATF_TP_ADD_TC(tp, fork1);
6016	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
6017	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
6018	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
6019	ATF_TP_ADD_TC(tp, fork5);
6020	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
6021	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
6022	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
6023
6024	ATF_TP_ADD_TC(tp, vfork1);
6025	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
6026	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
6027	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
6028	ATF_TP_ADD_TC(tp, vfork5);
6029	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
6030// thes tests hang on SMP machines, disable them for now
6031//	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
6032//	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
6033
6034	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8);
6035	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16);
6036	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32);
6037	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64);
6038
6039	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8);
6040	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16);
6041	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32);
6042	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64);
6043
6044	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8);
6045	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16);
6046	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32);
6047	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64);
6048
6049	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8);
6050	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16);
6051	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32);
6052	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64);
6053
6054	ATF_TP_ADD_TC(tp, bytes_transfer_read_d);
6055	ATF_TP_ADD_TC(tp, bytes_transfer_read_i);
6056	ATF_TP_ADD_TC(tp, bytes_transfer_write_d);
6057	ATF_TP_ADD_TC(tp, bytes_transfer_write_i);
6058
6059	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text);
6060	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text);
6061	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text);
6062	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text);
6063
6064	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text);
6065	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text);
6066	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text);
6067	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text);
6068
6069	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text);
6070	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text);
6071	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text);
6072	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text);
6073
6074	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text);
6075	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text);
6076	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text);
6077	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text);
6078
6079	ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text);
6080	ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text);
6081	ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text);
6082	ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text);
6083
6084	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv);
6085
6086	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1);
6087	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2);
6088	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3);
6089	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4);
6090	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5);
6091	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6);
6092
6093	ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1);
6094	ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2);
6095
6096	ATF_TP_ADD_TC_PT_STEP(tp, step1);
6097	ATF_TP_ADD_TC_PT_STEP(tp, step2);
6098	ATF_TP_ADD_TC_PT_STEP(tp, step3);
6099	ATF_TP_ADD_TC_PT_STEP(tp, step4);
6100
6101	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
6102	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
6103	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
6104	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
6105
6106	ATF_TP_ADD_TC(tp, kill1);
6107	ATF_TP_ADD_TC(tp, kill2);
6108	ATF_TP_ADD_TC(tp, kill3);
6109
6110	ATF_TP_ADD_TC(tp, traceme_lwpinfo0);
6111	ATF_TP_ADD_TC(tp, traceme_lwpinfo1);
6112	ATF_TP_ADD_TC(tp, traceme_lwpinfo2);
6113	ATF_TP_ADD_TC(tp, traceme_lwpinfo3);
6114
6115	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0);
6116	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1);
6117	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2);
6118	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3);
6119
6120	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
6121	ATF_TP_ADD_TC(tp, siginfo_set_faked);
6122
6123	ATF_TP_ADD_TC(tp, traceme_exec);
6124
6125	ATF_TP_ADD_TC(tp, trace_thread1);
6126	ATF_TP_ADD_TC(tp, trace_thread2);
6127	ATF_TP_ADD_TC(tp, trace_thread3);
6128	ATF_TP_ADD_TC(tp, trace_thread4);
6129
6130	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
6131
6132	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
6133	ATF_TP_ADD_TC(tp, signal5);
6134	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
6135	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
6136	ATF_TP_ADD_TC(tp, signal8);
6137	ATF_TP_ADD_TC(tp, signal9);
6138	ATF_TP_ADD_TC(tp, signal10);
6139
6140	ATF_TP_ADD_TC(tp, suspend1);
6141	ATF_TP_ADD_TC(tp, suspend2);
6142
6143	ATF_TP_ADD_TC(tp, resume1);
6144
6145	ATF_TP_ADD_TC(tp, syscall1);
6146
6147	ATF_TP_ADD_TC(tp, syscallemu1);
6148
6149	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
6150	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
6151	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
6152
6153	return atf_no_error();
6154}
6155