t_ptrace_wait.c revision 1.95
1/*	$NetBSD: t_ptrace_wait.c,v 1.95 2019/02/20 09:25:11 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.95 2019/02/20 09:25:11 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, bool masked, bool ignored)
1826{
1827	const int sigval = SIGSTOP;
1828	struct msg_fds parent_tracee, parent_tracer;
1829	const int exitval = 10;
1830	pid_t tracee, tracer, wpid;
1831	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1832#if defined(TWAIT_HAVE_STATUS)
1833	int status;
1834#endif
1835	struct sigaction sa;
1836	struct ptrace_siginfo info;
1837	sigset_t intmask;
1838	struct kinfo_proc2 kp;
1839	size_t len = sizeof(kp);
1840
1841	int name[6];
1842	const size_t namelen = __arraycount(name);
1843	ki_sigset_t kp_sigmask;
1844	ki_sigset_t kp_sigignore;
1845
1846#ifndef PTRACE_ILLEGAL_ASM
1847	if (sig == SIGILL)
1848		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1849#endif
1850
1851	memset(&info, 0, sizeof(info));
1852
1853	if (masked || ignored)
1854		atf_tc_expect_fail("Unexpected sigmask reset on crash under "
1855		    "debugger");
1856
1857	DPRINTF("Spawn tracee\n");
1858	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1859	tracee = atf_utils_fork();
1860	if (tracee == 0) {
1861		// Wait for parent to let us crash
1862		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
1863
1864		if (masked) {
1865			sigemptyset(&intmask);
1866			sigaddset(&intmask, sig);
1867			sigprocmask(SIG_BLOCK, &intmask, NULL);
1868		}
1869
1870		if (ignored) {
1871			memset(&sa, 0, sizeof(sa));
1872			sa.sa_handler = SIG_IGN;
1873			sigemptyset(&sa.sa_mask);
1874			FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1875		}
1876
1877		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1878		FORKEE_ASSERT(raise(sigval) == 0);
1879
1880		DPRINTF("Before executing a trap\n");
1881		switch (sig) {
1882		case SIGTRAP:
1883			trigger_trap();
1884			break;
1885		case SIGSEGV:
1886			trigger_segv();
1887			break;
1888		case SIGILL:
1889			trigger_ill();
1890			break;
1891		case SIGFPE:
1892			trigger_fpe();
1893			break;
1894		case SIGBUS:
1895			trigger_bus();
1896			break;
1897		default:
1898			/* NOTREACHED */
1899			FORKEE_ASSERTX(0 && "This shall not be reached");
1900		}
1901
1902		/* NOTREACHED */
1903		FORKEE_ASSERTX(0 && "This shall not be reached");
1904	}
1905
1906	DPRINTF("Spawn debugger\n");
1907	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1908	tracer = atf_utils_fork();
1909	if (tracer == 0) {
1910		/* Fork again and drop parent to reattach to PID 1 */
1911		tracer = atf_utils_fork();
1912		if (tracer != 0)
1913			_exit(exitval);
1914
1915		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1916		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1917
1918		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1919		FORKEE_REQUIRE_SUCCESS(
1920		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1921
1922		forkee_status_stopped(status, SIGSTOP);
1923
1924		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1925		    "traced process\n");
1926		SYSCALL_REQUIRE(
1927		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1928
1929		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1930		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1931		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1932		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1933
1934		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
1935		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
1936
1937		/* Resume tracee with PT_CONTINUE */
1938		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1939
1940		/* Inform parent that tracer has attached to tracee */
1941		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1942
1943		/* Wait for parent to tell use that tracee should have exited */
1944		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
1945
1946		/* Wait for tracee and assert that it exited */
1947		FORKEE_REQUIRE_SUCCESS(
1948		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1949
1950		forkee_status_stopped(status, sigval);
1951
1952		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1953		    "traced process\n");
1954		SYSCALL_REQUIRE(
1955		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1956
1957		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1958		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1959		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1960		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1961
1962		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
1963		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
1964
1965		name[0] = CTL_KERN,
1966		name[1] = KERN_PROC2,
1967		name[2] = KERN_PROC_PID;
1968		name[3] = tracee;
1969		name[4] = sizeof(kp);
1970		name[5] = 1;
1971
1972		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1973
1974		if (masked)
1975			kp_sigmask = kp.p_sigmask;
1976
1977		if (ignored)
1978			kp_sigignore = kp.p_sigignore;
1979
1980		/* Resume tracee with PT_CONTINUE */
1981		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1982
1983		/* Wait for tracee and assert that it exited */
1984		FORKEE_REQUIRE_SUCCESS(
1985		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1986
1987		forkee_status_stopped(status, sig);
1988
1989		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1990		    "traced process\n");
1991		SYSCALL_REQUIRE(
1992		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1993
1994		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1995		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1996		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1997		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1998
1999		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig);
2000
2001		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2002
2003		if (masked) {
2004			DPRINTF("kp_sigmask="
2005			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2006			    PRIx32 "\n",
2007			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
2008			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
2009
2010			DPRINTF("kp.p_sigmask="
2011			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2012			    PRIx32 "\n",
2013			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
2014			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
2015
2016			FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask,
2017			    sizeof(kp_sigmask)));
2018		}
2019
2020		if (ignored) {
2021			DPRINTF("kp_sigignore="
2022			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2023			    PRIx32 "\n",
2024			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
2025			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
2026
2027			DPRINTF("kp.p_sigignore="
2028			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2029			    PRIx32 "\n",
2030			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
2031			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
2032
2033			FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore,
2034			    sizeof(kp_sigignore)));
2035		}
2036
2037		switch (sig) {
2038		case SIGTRAP:
2039			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
2040			break;
2041		case SIGSEGV:
2042			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
2043			break;
2044		case SIGILL:
2045			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, ILL_PRVOPC);
2046			break;
2047		case SIGFPE:
2048			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
2049			break;
2050		case SIGBUS:
2051			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
2052			break;
2053		}
2054
2055		FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1);
2056		DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME);
2057		FORKEE_REQUIRE_SUCCESS(
2058		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2059
2060		forkee_status_signaled(status, SIGKILL, 0);
2061
2062		/* Inform parent that tracer is exiting normally */
2063		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
2064
2065		DPRINTF("Before exiting of the tracer process\n");
2066		_exit(0 /* collect by initproc */);
2067	}
2068
2069	DPRINTF("Wait for the tracer process (direct child) to exit "
2070	    "calling %s()\n", TWAIT_FNAME);
2071	TWAIT_REQUIRE_SUCCESS(
2072	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2073
2074	validate_status_exited(status, exitval);
2075
2076	DPRINTF("Wait for the non-exited tracee process with %s()\n",
2077	    TWAIT_FNAME);
2078	TWAIT_REQUIRE_SUCCESS(
2079	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
2080
2081	DPRINTF("Wait for the tracer to attach to the tracee\n");
2082	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
2083
2084	DPRINTF("Resume the tracee and let it crash\n");
2085	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
2086
2087	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
2088	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
2089
2090	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2091	    TWAIT_FNAME);
2092	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2093
2094	validate_status_signaled(status, SIGKILL, 0);
2095
2096	DPRINTF("Await normal exit of tracer\n");
2097	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
2098
2099	msg_close(&parent_tracer);
2100	msg_close(&parent_tracee);
2101}
2102
2103#define UNRELATED_TRACER_SEES_CRASH(test, sig)				\
2104ATF_TC(test);								\
2105ATF_TC_HEAD(test, tc)							\
2106{									\
2107	atf_tc_set_md_var(tc, "descr",					\
2108	    "Assert that an unrelated tracer sees crash signal from "	\
2109	    "the debuggee");						\
2110}									\
2111									\
2112ATF_TC_BODY(test, tc)							\
2113{									\
2114									\
2115	unrelated_tracer_sees_crash(sig, false, false);			\
2116}
2117
2118UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP)
2119UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV)
2120UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL)
2121UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE)
2122UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS)
2123
2124#define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig)		\
2125ATF_TC(test);								\
2126ATF_TC_HEAD(test, tc)							\
2127{									\
2128	atf_tc_set_md_var(tc, "descr",					\
2129	    "Assert that an unrelated tracer sees crash signal from "	\
2130	    "the debuggee with masked signal");				\
2131}									\
2132									\
2133ATF_TC_BODY(test, tc)							\
2134{									\
2135									\
2136	unrelated_tracer_sees_crash(sig, true, false);			\
2137}
2138
2139UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2140    unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP)
2141UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2142    unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV)
2143UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2144    unrelated_tracer_sees_signalmasked_crash_ill, SIGILL)
2145UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2146    unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE)
2147UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2148    unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS)
2149
2150#define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig)		\
2151ATF_TC(test);								\
2152ATF_TC_HEAD(test, tc)							\
2153{									\
2154	atf_tc_set_md_var(tc, "descr",					\
2155	    "Assert that an unrelated tracer sees crash signal from "	\
2156	    "the debuggee with signal ignored");			\
2157}									\
2158									\
2159ATF_TC_BODY(test, tc)							\
2160{									\
2161									\
2162	unrelated_tracer_sees_crash(sig, false, true);			\
2163}
2164
2165UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2166    unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP)
2167UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2168    unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV)
2169UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2170    unrelated_tracer_sees_signalignored_crash_ill, SIGILL)
2171UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2172    unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE)
2173UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2174    unrelated_tracer_sees_signalignored_crash_bus, SIGBUS)
2175#endif
2176
2177/// ----------------------------------------------------------------------------
2178
2179#if defined(TWAIT_HAVE_PID)
2180static void
2181tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated,
2182                                             bool stopped)
2183{
2184	/*
2185	 * notimeout - disable timeout in await zombie function
2186	 * unrelated - attach from unrelated tracer reparented to initproc
2187	 * stopped - attach to a stopped process
2188	 */
2189
2190	struct msg_fds parent_tracee, parent_tracer;
2191	const int exitval_tracee = 5;
2192	const int exitval_tracer = 10;
2193	pid_t tracee, tracer, wpid;
2194	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2195#if defined(TWAIT_HAVE_STATUS)
2196	int status;
2197#endif
2198
2199	/*
2200	 * Only a subset of options are supported.
2201	 */
2202	ATF_REQUIRE((!notimeout && !unrelated && !stopped) ||
2203	            (!notimeout && unrelated && !stopped) ||
2204	            (notimeout && !unrelated && !stopped) ||
2205	            (!notimeout && unrelated && stopped));
2206
2207	DPRINTF("Spawn tracee\n");
2208	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2209	tracee = atf_utils_fork();
2210	if (tracee == 0) {
2211		if (stopped) {
2212			DPRINTF("Stop self PID %d\n", getpid());
2213			raise(SIGSTOP);
2214		}
2215
2216		// Wait for parent to let us exit
2217		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2218		_exit(exitval_tracee);
2219	}
2220
2221	DPRINTF("Spawn debugger\n");
2222	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2223	tracer = atf_utils_fork();
2224	if (tracer == 0) {
2225		if(unrelated) {
2226			/* Fork again and drop parent to reattach to PID 1 */
2227			tracer = atf_utils_fork();
2228			if (tracer != 0)
2229				_exit(exitval_tracer);
2230		}
2231
2232		if (stopped) {
2233			DPRINTF("Await for a stopped parent PID %d\n", tracee);
2234			await_stopped(tracee);
2235		}
2236
2237		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2238		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2239
2240		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2241		FORKEE_REQUIRE_SUCCESS(
2242		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2243
2244		forkee_status_stopped(status, SIGSTOP);
2245
2246		/* Resume tracee with PT_CONTINUE */
2247		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2248
2249		/* Inform parent that tracer has attached to tracee */
2250		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2251
2252		/* Wait for parent to tell use that tracee should have exited */
2253		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2254
2255		/* Wait for tracee and assert that it exited */
2256		FORKEE_REQUIRE_SUCCESS(
2257		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2258
2259		forkee_status_exited(status, exitval_tracee);
2260		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
2261
2262		DPRINTF("Before exiting of the tracer process\n");
2263		_exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer);
2264	}
2265
2266	if (unrelated) {
2267		DPRINTF("Wait for the tracer process (direct child) to exit "
2268		    "calling %s()\n", TWAIT_FNAME);
2269		TWAIT_REQUIRE_SUCCESS(
2270		    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2271
2272		validate_status_exited(status, exitval_tracer);
2273
2274		DPRINTF("Wait for the non-exited tracee process with %s()\n",
2275		    TWAIT_FNAME);
2276		TWAIT_REQUIRE_SUCCESS(
2277		    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
2278	}
2279
2280	DPRINTF("Wait for the tracer to attach to the tracee\n");
2281	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
2282
2283	DPRINTF("Resume the tracee and let it exit\n");
2284	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
2285
2286	DPRINTF("Detect that tracee is zombie\n");
2287	if (notimeout)
2288		await_zombie_raw(tracee, 0);
2289	else
2290		await_zombie(tracee);
2291
2292	DPRINTF("Assert that there is no status about tracee %d - "
2293	    "Tracer must detect zombie first - calling %s()\n", tracee,
2294	    TWAIT_FNAME);
2295	TWAIT_REQUIRE_SUCCESS(
2296	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2297
2298	if (unrelated) {
2299		DPRINTF("Resume the tracer and let it detect exited tracee\n");
2300		PARENT_TO_CHILD("Message 2", parent_tracer, msg);
2301	} else {
2302		DPRINTF("Tell the tracer child should have exited\n");
2303		PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
2304		DPRINTF("Wait for tracer to finish its job and exit - calling "
2305			"%s()\n", TWAIT_FNAME);
2306
2307		DPRINTF("Wait from tracer child to complete waiting for "
2308			"tracee\n");
2309		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2310		    tracer);
2311
2312		validate_status_exited(status, exitval_tracer);
2313	}
2314
2315	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2316	    TWAIT_FNAME);
2317	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2318
2319	validate_status_exited(status, exitval_tracee);
2320
2321	msg_close(&parent_tracer);
2322	msg_close(&parent_tracee);
2323}
2324
2325ATF_TC(tracer_sees_terminaton_before_the_parent);
2326ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc)
2327{
2328	atf_tc_set_md_var(tc, "descr",
2329	    "Assert that tracer sees process termination before the parent");
2330}
2331
2332ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc)
2333{
2334
2335	tracer_sees_terminaton_before_the_parent_raw(false, false, false);
2336}
2337
2338ATF_TC(tracer_sysctl_lookup_without_duplicates);
2339ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc)
2340{
2341	atf_tc_set_md_var(tc, "descr",
2342	    "Assert that await_zombie() in attach1 always finds a single "
2343	    "process and no other error is reported");
2344}
2345
2346ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc)
2347{
2348	time_t start, end;
2349	double diff;
2350	unsigned long N = 0;
2351
2352	/*
2353	 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw().
2354	 * This test body isn't specific to this race, however it's just good
2355	 * enough for this purposes, no need to invent a dedicated code flow.
2356	 */
2357
2358	start = time(NULL);
2359	while (true) {
2360		DPRINTF("Step: %lu\n", N);
2361		tracer_sees_terminaton_before_the_parent_raw(true, false,
2362		                                             false);
2363		end = time(NULL);
2364		diff = difftime(end, start);
2365		if (diff >= 5.0)
2366			break;
2367		++N;
2368	}
2369	DPRINTF("Iterations: %lu\n", N);
2370}
2371
2372ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent);
2373ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2374{
2375	atf_tc_set_md_var(tc, "descr",
2376	    "Assert that tracer sees process termination before the parent");
2377}
2378
2379ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2380{
2381
2382	tracer_sees_terminaton_before_the_parent_raw(false, true, false);
2383}
2384
2385ATF_TC(tracer_attach_to_unrelated_stopped_process);
2386ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc)
2387{
2388	atf_tc_set_md_var(tc, "descr",
2389	    "Assert that tracer can attach to an unrelated stopped process");
2390}
2391
2392ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc)
2393{
2394
2395	tracer_sees_terminaton_before_the_parent_raw(false, true, true);
2396}
2397#endif
2398
2399/// ----------------------------------------------------------------------------
2400
2401static void
2402parent_attach_to_its_child(bool stopped)
2403{
2404	struct msg_fds parent_tracee;
2405	const int exitval_tracee = 5;
2406	pid_t tracee, wpid;
2407	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2408#if defined(TWAIT_HAVE_STATUS)
2409	int status;
2410#endif
2411
2412	DPRINTF("Spawn tracee\n");
2413	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2414	tracee = atf_utils_fork();
2415	if (tracee == 0) {
2416		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2417		DPRINTF("Parent should now attach to tracee\n");
2418
2419		if (stopped) {
2420			DPRINTF("Stop self PID %d\n", getpid());
2421			SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2422		}
2423
2424		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
2425		/* Wait for message from the parent */
2426		_exit(exitval_tracee);
2427	}
2428	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2429
2430	if (stopped) {
2431		DPRINTF("Await for a stopped tracee PID %d\n", tracee);
2432		await_stopped(tracee);
2433	}
2434
2435	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
2436	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2437
2438	DPRINTF("Wait for the stopped tracee process with %s()\n",
2439	    TWAIT_FNAME);
2440	TWAIT_REQUIRE_SUCCESS(
2441	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2442
2443	validate_status_stopped(status, SIGSTOP);
2444
2445	DPRINTF("Resume tracee with PT_CONTINUE\n");
2446	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2447
2448	DPRINTF("Let the tracee exit now\n");
2449	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
2450
2451	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
2452	TWAIT_REQUIRE_SUCCESS(
2453	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2454
2455	validate_status_exited(status, exitval_tracee);
2456
2457	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
2458	TWAIT_REQUIRE_FAILURE(ECHILD,
2459	    wpid = TWAIT_GENERIC(tracee, &status, 0));
2460
2461	msg_close(&parent_tracee);
2462}
2463
2464ATF_TC(parent_attach_to_its_child);
2465ATF_TC_HEAD(parent_attach_to_its_child, tc)
2466{
2467	atf_tc_set_md_var(tc, "descr",
2468	    "Assert that tracer parent can PT_ATTACH to its child");
2469}
2470
2471ATF_TC_BODY(parent_attach_to_its_child, tc)
2472{
2473
2474	parent_attach_to_its_child(false);
2475}
2476
2477ATF_TC(parent_attach_to_its_stopped_child);
2478ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc)
2479{
2480	atf_tc_set_md_var(tc, "descr",
2481	    "Assert that tracer parent can PT_ATTACH to its stopped child");
2482}
2483
2484ATF_TC_BODY(parent_attach_to_its_stopped_child, tc)
2485{
2486
2487	parent_attach_to_its_child(true);
2488}
2489
2490/// ----------------------------------------------------------------------------
2491
2492static void
2493child_attach_to_its_parent(bool stopped)
2494{
2495	struct msg_fds parent_tracee;
2496	const int exitval_tracer = 5;
2497	pid_t tracer, wpid;
2498	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2499#if defined(TWAIT_HAVE_STATUS)
2500	int status;
2501#endif
2502
2503	DPRINTF("Spawn tracer\n");
2504	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2505	tracer = atf_utils_fork();
2506	if (tracer == 0) {
2507		/* Wait for message from the parent */
2508		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2509
2510		if (stopped) {
2511			DPRINTF("Await for a stopped parent PID %d\n",
2512			        getppid());
2513			await_stopped(getppid());
2514		}
2515
2516		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
2517		    getppid());
2518		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
2519
2520		DPRINTF("Wait for the stopped parent process with %s()\n",
2521		    TWAIT_FNAME);
2522		FORKEE_REQUIRE_SUCCESS(
2523		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
2524
2525		forkee_status_stopped(status, SIGSTOP);
2526
2527		DPRINTF("Resume parent with PT_DETACH\n");
2528		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
2529		    != -1);
2530
2531		/* Tell parent we are ready */
2532		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
2533
2534		_exit(exitval_tracer);
2535	}
2536
2537	DPRINTF("Wait for the tracer to become ready\n");
2538	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2539
2540	if (stopped) {
2541		DPRINTF("Stop self PID %d\n", getpid());
2542		SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2543	}
2544
2545	DPRINTF("Allow the tracer to exit now\n");
2546	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
2547
2548	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
2549	TWAIT_REQUIRE_SUCCESS(
2550	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2551
2552	validate_status_exited(status, exitval_tracer);
2553
2554	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
2555	TWAIT_REQUIRE_FAILURE(ECHILD,
2556	    wpid = TWAIT_GENERIC(tracer, &status, 0));
2557
2558	msg_close(&parent_tracee);
2559}
2560
2561ATF_TC(child_attach_to_its_parent);
2562ATF_TC_HEAD(child_attach_to_its_parent, tc)
2563{
2564	atf_tc_set_md_var(tc, "descr",
2565	    "Assert that tracer child can PT_ATTACH to its parent");
2566}
2567
2568ATF_TC_BODY(child_attach_to_its_parent, tc)
2569{
2570
2571	child_attach_to_its_parent(false);
2572}
2573
2574ATF_TC(child_attach_to_its_stopped_parent);
2575ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc)
2576{
2577	atf_tc_set_md_var(tc, "descr",
2578	    "Assert that tracer child can PT_ATTACH to its stopped parent");
2579}
2580
2581ATF_TC_BODY(child_attach_to_its_stopped_parent, tc)
2582{
2583	/*
2584	 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as
2585	 * this causes a pipe (established from atf-run) to be broken.
2586	 * atf-run uses this mechanism to monitor whether a test is alive.
2587	 *
2588	 * As a workaround spawn this test as a subprocess.
2589	 */
2590
2591	const int exitval = 15;
2592	pid_t child, wpid;
2593#if defined(TWAIT_HAVE_STATUS)
2594	int status;
2595#endif
2596
2597	SYSCALL_REQUIRE((child = fork()) != -1);
2598	if (child == 0) {
2599		child_attach_to_its_parent(true);
2600		_exit(exitval);
2601	} else {
2602		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2603		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2604
2605		validate_status_exited(status, exitval);
2606
2607		DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2608		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2609	}
2610}
2611
2612/// ----------------------------------------------------------------------------
2613
2614#if defined(TWAIT_HAVE_PID)
2615
2616enum tracee_sees_its_original_parent_type {
2617	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2618	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2619	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS
2620};
2621
2622static void
2623tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type)
2624{
2625	struct msg_fds parent_tracer, parent_tracee;
2626	const int exitval_tracee = 5;
2627	const int exitval_tracer = 10;
2628	pid_t parent, tracee, tracer, wpid;
2629	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2630#if defined(TWAIT_HAVE_STATUS)
2631	int status;
2632#endif
2633	/* sysctl(3) - kinfo_proc2 */
2634	int name[CTL_MAXNAME];
2635	struct kinfo_proc2 kp;
2636	size_t len = sizeof(kp);
2637	unsigned int namelen;
2638
2639	/* procfs - status  */
2640	FILE *fp;
2641	struct stat st;
2642	const char *fname = "/proc/curproc/status";
2643	char s_executable[MAXPATHLEN];
2644	int s_pid, s_ppid;
2645	int rv;
2646
2647	if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) {
2648		SYSCALL_REQUIRE(
2649		    (rv = stat(fname, &st)) == 0 || (errno == ENOENT));
2650		if (rv != 0)
2651			atf_tc_skip("/proc/curproc/status not found");
2652	}
2653
2654	DPRINTF("Spawn tracee\n");
2655	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2656	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2657	tracee = atf_utils_fork();
2658	if (tracee == 0) {
2659		parent = getppid();
2660
2661		/* Emit message to the parent */
2662		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
2663		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2664
2665		switch (type) {
2666		case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID:
2667			FORKEE_ASSERT_EQ(parent, getppid());
2668			break;
2669		case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2:
2670			namelen = 0;
2671			name[namelen++] = CTL_KERN;
2672			name[namelen++] = KERN_PROC2;
2673			name[namelen++] = KERN_PROC_PID;
2674			name[namelen++] = getpid();
2675			name[namelen++] = len;
2676			name[namelen++] = 1;
2677
2678			FORKEE_ASSERT_EQ(
2679			    sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2680			FORKEE_ASSERT_EQ(parent, kp.p_ppid);
2681			break;
2682		case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS:
2683			/*
2684			 * Format:
2685			 *  EXECUTABLE PID PPID ...
2686			 */
2687			FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
2688			fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
2689			FORKEE_ASSERT_EQ(fclose(fp), 0);
2690			FORKEE_ASSERT_EQ(parent, s_ppid);
2691			break;
2692		}
2693
2694		_exit(exitval_tracee);
2695	}
2696	DPRINTF("Wait for child to record its parent identifier (pid)\n");
2697	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
2698
2699	DPRINTF("Spawn debugger\n");
2700	tracer = atf_utils_fork();
2701	if (tracer == 0) {
2702		/* No IPC to communicate with the child */
2703		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2704		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2705
2706		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2707		FORKEE_REQUIRE_SUCCESS(
2708		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2709
2710		forkee_status_stopped(status, SIGSTOP);
2711
2712		/* Resume tracee with PT_CONTINUE */
2713		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2714
2715		/* Inform parent that tracer has attached to tracee */
2716		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2717
2718		/* Wait for parent to tell use that tracee should have exited */
2719		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2720
2721		/* Wait for tracee and assert that it exited */
2722		FORKEE_REQUIRE_SUCCESS(
2723		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2724
2725		forkee_status_exited(status, exitval_tracee);
2726
2727		DPRINTF("Before exiting of the tracer process\n");
2728		_exit(exitval_tracer);
2729	}
2730
2731	DPRINTF("Wait for the tracer to attach to the tracee\n");
2732	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
2733
2734	DPRINTF("Resume the tracee and let it exit\n");
2735	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
2736
2737	DPRINTF("Detect that tracee is zombie\n");
2738	await_zombie(tracee);
2739
2740	DPRINTF("Assert that there is no status about tracee - "
2741	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
2742	TWAIT_REQUIRE_SUCCESS(
2743	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2744
2745	DPRINTF("Tell the tracer child should have exited\n");
2746	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
2747
2748	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
2749	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2750	    tracer);
2751
2752	validate_status_exited(status, exitval_tracer);
2753
2754	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2755	    TWAIT_FNAME);
2756	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
2757	    tracee);
2758
2759	validate_status_exited(status, exitval_tracee);
2760
2761	msg_close(&parent_tracer);
2762	msg_close(&parent_tracee);
2763}
2764
2765#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr)		\
2766ATF_TC(test);								\
2767ATF_TC_HEAD(test, tc)							\
2768{									\
2769	atf_tc_set_md_var(tc, "descr",					\
2770	    "Assert that tracee sees its original parent when being traced " \
2771	    "(check " descr ")");					\
2772}									\
2773									\
2774ATF_TC_BODY(test, tc)							\
2775{									\
2776									\
2777	tracee_sees_its_original_parent(type);				\
2778}
2779
2780TRACEE_SEES_ITS_ORIGINAL_PARENT(
2781	tracee_sees_its_original_parent_getppid,
2782	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2783	"getppid(2)");
2784TRACEE_SEES_ITS_ORIGINAL_PARENT(
2785	tracee_sees_its_original_parent_sysctl_kinfo_proc2,
2786	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2787	"sysctl(3) and kinfo_proc2");
2788TRACEE_SEES_ITS_ORIGINAL_PARENT(
2789	tracee_sees_its_original_parent_procfs_status,
2790	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS,
2791	"the status file in procfs");
2792#endif
2793
2794/// ----------------------------------------------------------------------------
2795
2796static void
2797eventmask_preserved(int event)
2798{
2799	const int exitval = 5;
2800	const int sigval = SIGSTOP;
2801	pid_t child, wpid;
2802#if defined(TWAIT_HAVE_STATUS)
2803	int status;
2804#endif
2805	ptrace_event_t set_event, get_event;
2806	const int len = sizeof(ptrace_event_t);
2807
2808	DPRINTF("Before forking process PID=%d\n", getpid());
2809	SYSCALL_REQUIRE((child = fork()) != -1);
2810	if (child == 0) {
2811		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2812		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2813
2814		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2815		FORKEE_ASSERT(raise(sigval) == 0);
2816
2817		DPRINTF("Before exiting of the child process\n");
2818		_exit(exitval);
2819	}
2820	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2821
2822	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2823	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2824
2825	validate_status_stopped(status, sigval);
2826
2827	set_event.pe_set_event = event;
2828	SYSCALL_REQUIRE(
2829	    ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
2830	SYSCALL_REQUIRE(
2831	    ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
2832	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
2833
2834	DPRINTF("Before resuming the child process where it left off and "
2835	    "without signal to be sent\n");
2836	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2837
2838	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2839	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2840
2841	validate_status_exited(status, exitval);
2842
2843	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2844	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2845}
2846
2847#define EVENTMASK_PRESERVED(test, event)				\
2848ATF_TC(test);								\
2849ATF_TC_HEAD(test, tc)							\
2850{									\
2851	atf_tc_set_md_var(tc, "descr",					\
2852	    "Verify that eventmask " #event " is preserved");		\
2853}									\
2854									\
2855ATF_TC_BODY(test, tc)							\
2856{									\
2857									\
2858	eventmask_preserved(event);					\
2859}
2860
2861EVENTMASK_PRESERVED(eventmask_preserved_empty, 0)
2862EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK)
2863EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK)
2864EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE)
2865EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE)
2866EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT)
2867
2868/// ----------------------------------------------------------------------------
2869
2870static void
2871fork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
2872    bool trackvforkdone, bool detachchild, bool detachparent)
2873{
2874	const int exitval = 5;
2875	const int exitval2 = 15;
2876	const int sigval = SIGSTOP;
2877	pid_t child, child2 = 0, wpid;
2878#if defined(TWAIT_HAVE_STATUS)
2879	int status;
2880#endif
2881	ptrace_state_t state;
2882	const int slen = sizeof(state);
2883	ptrace_event_t event;
2884	const int elen = sizeof(event);
2885
2886	DPRINTF("Before forking process PID=%d\n", getpid());
2887	SYSCALL_REQUIRE((child = fork()) != -1);
2888	if (child == 0) {
2889		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2890		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2891
2892		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2893		FORKEE_ASSERT(raise(sigval) == 0);
2894
2895		FORKEE_ASSERT((child2 = (fn)()) != -1);
2896
2897		if (child2 == 0)
2898			_exit(exitval2);
2899
2900		FORKEE_REQUIRE_SUCCESS
2901		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
2902
2903		forkee_status_exited(status, exitval2);
2904
2905		DPRINTF("Before exiting of the child process\n");
2906		_exit(exitval);
2907	}
2908	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2909
2910	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2911	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2912
2913	validate_status_stopped(status, sigval);
2914
2915	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
2916	    trackfork ? "|PTRACE_FORK" : "",
2917	    trackvfork ? "|PTRACE_VFORK" : "",
2918	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
2919	event.pe_set_event = 0;
2920	if (trackfork)
2921		event.pe_set_event |= PTRACE_FORK;
2922	if (trackvfork)
2923		event.pe_set_event |= PTRACE_VFORK;
2924	if (trackvforkdone)
2925		event.pe_set_event |= PTRACE_VFORK_DONE;
2926	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
2927
2928	DPRINTF("Before resuming the child process where it left off and "
2929	    "without signal to be sent\n");
2930	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2931
2932#if defined(TWAIT_HAVE_PID)
2933	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
2934		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
2935		    child);
2936		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2937		    child);
2938
2939		validate_status_stopped(status, SIGTRAP);
2940
2941		SYSCALL_REQUIRE(
2942		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2943		if (trackfork && fn == fork) {
2944			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
2945			       PTRACE_FORK);
2946		}
2947		if (trackvfork && fn == vfork) {
2948			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
2949			       PTRACE_VFORK);
2950		}
2951
2952		child2 = state.pe_other_pid;
2953		DPRINTF("Reported ptrace event with forkee %d\n", child2);
2954
2955		DPRINTF("Before calling %s() for the forkee %d of the child "
2956		    "%d\n", TWAIT_FNAME, child2, child);
2957		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
2958		    child2);
2959
2960		validate_status_stopped(status, SIGTRAP);
2961
2962		SYSCALL_REQUIRE(
2963		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
2964		if (trackfork && fn == fork) {
2965			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
2966			       PTRACE_FORK);
2967		}
2968		if (trackvfork && fn == vfork) {
2969			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
2970			       PTRACE_VFORK);
2971		}
2972
2973		ATF_REQUIRE_EQ(state.pe_other_pid, child);
2974
2975		DPRINTF("Before resuming the forkee process where it left off "
2976		    "and without signal to be sent\n");
2977		SYSCALL_REQUIRE(
2978		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
2979
2980		DPRINTF("Before resuming the child process where it left off "
2981		    "and without signal to be sent\n");
2982		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2983	}
2984#endif
2985
2986	if (trackvforkdone && fn == vfork) {
2987		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
2988		    child);
2989		TWAIT_REQUIRE_SUCCESS(
2990		    wpid = TWAIT_GENERIC(child, &status, 0), child);
2991
2992		validate_status_stopped(status, SIGTRAP);
2993
2994		SYSCALL_REQUIRE(
2995		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2996		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
2997
2998		child2 = state.pe_other_pid;
2999		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
3000		    child2);
3001
3002		DPRINTF("Before resuming the child process where it left off "
3003		    "and without signal to be sent\n");
3004		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3005	}
3006
3007#if defined(TWAIT_HAVE_PID)
3008	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
3009		DPRINTF("Before calling %s() for the forkee - expected exited"
3010		    "\n", TWAIT_FNAME);
3011		TWAIT_REQUIRE_SUCCESS(
3012		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3013
3014		validate_status_exited(status, exitval2);
3015
3016		DPRINTF("Before calling %s() for the forkee - expected no "
3017		    "process\n", TWAIT_FNAME);
3018		TWAIT_REQUIRE_FAILURE(ECHILD,
3019		    wpid = TWAIT_GENERIC(child2, &status, 0));
3020	}
3021#endif
3022
3023	DPRINTF("Before calling %s() for the child - expected stopped "
3024	    "SIGCHLD\n", TWAIT_FNAME);
3025	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3026
3027	validate_status_stopped(status, SIGCHLD);
3028
3029	DPRINTF("Before resuming the child process where it left off and "
3030	    "without signal to be sent\n");
3031	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3032
3033	DPRINTF("Before calling %s() for the child - expected exited\n",
3034	    TWAIT_FNAME);
3035	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3036
3037	validate_status_exited(status, exitval);
3038
3039	DPRINTF("Before calling %s() for the child - expected no process\n",
3040	    TWAIT_FNAME);
3041	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3042}
3043
3044#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \
3045ATF_TC(name);								\
3046ATF_TC_HEAD(name, tc)							\
3047{									\
3048	atf_tc_set_md_var(tc, "descr", descr);				\
3049}									\
3050									\
3051ATF_TC_BODY(name, tc)							\
3052{									\
3053									\
3054	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);	\
3055}
3056
3057#define F false
3058#define T true
3059
3060#define F_IF__0(x)
3061#define F_IF__1(x) x
3062#define F_IF__(x,y) F_IF__ ## x (y)
3063#define F_IF_(x,y) F_IF__(x,y)
3064#define F_IF(x,y) F_IF_(x,y)
3065
3066#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \
3067	"Verify " #function "(2) called with 0"				\
3068	F_IF(forkbit,"|PTRACE_FORK")					\
3069	F_IF(vforkbit,"|PTRACE_VFORK")					\
3070	F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")				\
3071	" in EVENT_MASK."						\
3072	F_IF(dchildbit," Detach child in this test.")			\
3073	F_IF(dparentbit," Detach parent in this test.")
3074
3075FORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
3076#if defined(TWAIT_HAVE_PID)
3077FORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
3078FORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
3079FORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
3080#endif
3081FORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
3082#if defined(TWAIT_HAVE_PID)
3083FORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
3084FORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
3085FORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
3086#endif
3087
3088FORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
3089#if defined(TWAIT_HAVE_PID)
3090FORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
3091FORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
3092FORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
3093#endif
3094FORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
3095#if defined(TWAIT_HAVE_PID)
3096FORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
3097FORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
3098FORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
3099#endif
3100
3101/// ----------------------------------------------------------------------------
3102
3103enum bytes_transfer_type {
3104	BYTES_TRANSFER_DATA,
3105	BYTES_TRANSFER_DATAIO,
3106	BYTES_TRANSFER_TEXT,
3107	BYTES_TRANSFER_TEXTIO,
3108	BYTES_TRANSFER_AUXV
3109};
3110
3111static int __used
3112bytes_transfer_dummy(int a, int b, int c, int d)
3113{
3114	int e, f, g, h;
3115
3116	a *= 4;
3117	b += 3;
3118	c -= 2;
3119	d /= 1;
3120
3121	e = strtol("10", NULL, 10);
3122	f = strtol("20", NULL, 10);
3123	g = strtol("30", NULL, 10);
3124	h = strtol("40", NULL, 10);
3125
3126	return (a + b * c - d) + (e * f - g / h);
3127}
3128
3129static void
3130bytes_transfer(int operation, size_t size, enum bytes_transfer_type type)
3131{
3132	const int exitval = 5;
3133	const int sigval = SIGSTOP;
3134	pid_t child, wpid;
3135	bool skip = false;
3136
3137	int lookup_me = 0;
3138	uint8_t lookup_me8 = 0;
3139	uint16_t lookup_me16 = 0;
3140	uint32_t lookup_me32 = 0;
3141	uint64_t lookup_me64 = 0;
3142
3143	int magic = 0x13579246;
3144	uint8_t magic8 = 0xab;
3145	uint16_t magic16 = 0x1234;
3146	uint32_t magic32 = 0x98765432;
3147	uint64_t magic64 = 0xabcdef0123456789;
3148
3149	struct ptrace_io_desc io;
3150#if defined(TWAIT_HAVE_STATUS)
3151	int status;
3152#endif
3153	/* 513 is just enough, for the purposes of ATF it's good enough */
3154	AuxInfo ai[513], *aip;
3155
3156	ATF_REQUIRE(size < sizeof(ai));
3157
3158	/* Prepare variables for .TEXT transfers */
3159	switch (type) {
3160	case BYTES_TRANSFER_TEXT:
3161		memcpy(&magic, bytes_transfer_dummy, sizeof(magic));
3162		break;
3163	case BYTES_TRANSFER_TEXTIO:
3164		switch (size) {
3165		case 8:
3166			memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8));
3167			break;
3168		case 16:
3169			memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16));
3170			break;
3171		case 32:
3172			memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32));
3173			break;
3174		case 64:
3175			memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64));
3176			break;
3177		}
3178		break;
3179	default:
3180		break;
3181	}
3182
3183	/* Prepare variables for PIOD and AUXV transfers */
3184	switch (type) {
3185	case BYTES_TRANSFER_TEXTIO:
3186	case BYTES_TRANSFER_DATAIO:
3187		io.piod_op = operation;
3188		switch (size) {
3189		case 8:
3190			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3191			               (void *)bytes_transfer_dummy :
3192			               &lookup_me8;
3193			io.piod_addr = &lookup_me8;
3194			io.piod_len = sizeof(lookup_me8);
3195			break;
3196		case 16:
3197			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3198			               (void *)bytes_transfer_dummy :
3199			               &lookup_me16;
3200			io.piod_addr = &lookup_me16;
3201			io.piod_len = sizeof(lookup_me16);
3202			break;
3203		case 32:
3204			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3205			               (void *)bytes_transfer_dummy :
3206			               &lookup_me32;
3207			io.piod_addr = &lookup_me32;
3208			io.piod_len = sizeof(lookup_me32);
3209			break;
3210		case 64:
3211			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
3212			               (void *)bytes_transfer_dummy :
3213			               &lookup_me64;
3214			io.piod_addr = &lookup_me64;
3215			io.piod_len = sizeof(lookup_me64);
3216			break;
3217		default:
3218			break;
3219		}
3220		break;
3221	case BYTES_TRANSFER_AUXV:
3222		io.piod_op = operation;
3223		io.piod_offs = 0;
3224		io.piod_addr = ai;
3225		io.piod_len = size;
3226		break;
3227	default:
3228		break;
3229	}
3230
3231	DPRINTF("Before forking process PID=%d\n", getpid());
3232	SYSCALL_REQUIRE((child = fork()) != -1);
3233	if (child == 0) {
3234		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3235		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3236
3237		switch (type) {
3238		case BYTES_TRANSFER_DATA:
3239			switch (operation) {
3240			case PT_READ_D:
3241			case PT_READ_I:
3242				lookup_me = magic;
3243				break;
3244			default:
3245				break;
3246			}
3247			break;
3248		case BYTES_TRANSFER_DATAIO:
3249			switch (operation) {
3250			case PIOD_READ_D:
3251			case PIOD_READ_I:
3252				switch (size) {
3253				case 8:
3254					lookup_me8 = magic8;
3255					break;
3256				case 16:
3257					lookup_me16 = magic16;
3258					break;
3259				case 32:
3260					lookup_me32 = magic32;
3261					break;
3262				case 64:
3263					lookup_me64 = magic64;
3264					break;
3265				default:
3266					break;
3267				}
3268				break;
3269			default:
3270				break;
3271			}
3272		default:
3273			break;
3274		}
3275
3276		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3277		FORKEE_ASSERT(raise(sigval) == 0);
3278
3279		/* Handle PIOD and PT separately as operation values overlap */
3280		switch (type) {
3281		case BYTES_TRANSFER_DATA:
3282			switch (operation) {
3283			case PT_WRITE_D:
3284			case PT_WRITE_I:
3285				FORKEE_ASSERT_EQ(lookup_me, magic);
3286				break;
3287			default:
3288				break;
3289			}
3290			break;
3291		case BYTES_TRANSFER_DATAIO:
3292			switch (operation) {
3293			case PIOD_WRITE_D:
3294			case PIOD_WRITE_I:
3295				switch (size) {
3296				case 8:
3297					FORKEE_ASSERT_EQ(lookup_me8, magic8);
3298					break;
3299				case 16:
3300					FORKEE_ASSERT_EQ(lookup_me16, magic16);
3301					break;
3302				case 32:
3303					FORKEE_ASSERT_EQ(lookup_me32, magic32);
3304					break;
3305				case 64:
3306					FORKEE_ASSERT_EQ(lookup_me64, magic64);
3307					break;
3308				default:
3309					break;
3310				}
3311				break;
3312			default:
3313				break;
3314			}
3315			break;
3316		case BYTES_TRANSFER_TEXT:
3317			FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy,
3318			                     sizeof(magic)) == 0);
3319			break;
3320		case BYTES_TRANSFER_TEXTIO:
3321			switch (size) {
3322			case 8:
3323				FORKEE_ASSERT(memcmp(&magic8,
3324				                     bytes_transfer_dummy,
3325				                     sizeof(magic8)) == 0);
3326				break;
3327			case 16:
3328				FORKEE_ASSERT(memcmp(&magic16,
3329				                     bytes_transfer_dummy,
3330				                     sizeof(magic16)) == 0);
3331				break;
3332			case 32:
3333				FORKEE_ASSERT(memcmp(&magic32,
3334				                     bytes_transfer_dummy,
3335				                     sizeof(magic32)) == 0);
3336				break;
3337			case 64:
3338				FORKEE_ASSERT(memcmp(&magic64,
3339				                     bytes_transfer_dummy,
3340				                     sizeof(magic64)) == 0);
3341				break;
3342			}
3343			break;
3344		default:
3345			break;
3346		}
3347
3348		DPRINTF("Before exiting of the child process\n");
3349		_exit(exitval);
3350	}
3351	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3352
3353	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3354	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3355
3356	validate_status_stopped(status, sigval);
3357
3358	/* Check PaX MPROTECT */
3359	if (!can_we_write_to_text(child)) {
3360		switch (type) {
3361		case BYTES_TRANSFER_TEXTIO:
3362			switch (operation) {
3363			case PIOD_WRITE_D:
3364			case PIOD_WRITE_I:
3365				skip = true;
3366				break;
3367			default:
3368				break;
3369			}
3370			break;
3371		case BYTES_TRANSFER_TEXT:
3372			switch (operation) {
3373			case PT_WRITE_D:
3374			case PT_WRITE_I:
3375				skip = true;
3376				break;
3377			default:
3378				break;
3379			}
3380			break;
3381		default:
3382			break;
3383		}
3384	}
3385
3386	/* Bailout cleanly killing the child process */
3387	if (skip) {
3388		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
3389		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3390		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3391		                      child);
3392
3393		validate_status_signaled(status, SIGKILL, 0);
3394
3395		atf_tc_skip("PaX MPROTECT setup prevents writes to .text");
3396	}
3397
3398	DPRINTF("Calling operation to transfer bytes between child=%d and "
3399	       "parent=%d\n", child, getpid());
3400
3401	switch (type) {
3402	case BYTES_TRANSFER_TEXTIO:
3403	case BYTES_TRANSFER_DATAIO:
3404	case BYTES_TRANSFER_AUXV:
3405		switch (operation) {
3406		case PIOD_WRITE_D:
3407		case PIOD_WRITE_I:
3408			switch (size) {
3409			case 8:
3410				lookup_me8 = magic8;
3411				break;
3412			case 16:
3413				lookup_me16 = magic16;
3414				break;
3415			case 32:
3416				lookup_me32 = magic32;
3417				break;
3418			case 64:
3419				lookup_me64 = magic64;
3420				break;
3421			default:
3422				break;
3423			}
3424			break;
3425		default:
3426			break;
3427		}
3428		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3429		switch (operation) {
3430		case PIOD_READ_D:
3431		case PIOD_READ_I:
3432			switch (size) {
3433			case 8:
3434				ATF_REQUIRE_EQ(lookup_me8, magic8);
3435				break;
3436			case 16:
3437				ATF_REQUIRE_EQ(lookup_me16, magic16);
3438				break;
3439			case 32:
3440				ATF_REQUIRE_EQ(lookup_me32, magic32);
3441				break;
3442			case 64:
3443				ATF_REQUIRE_EQ(lookup_me64, magic64);
3444				break;
3445			default:
3446				break;
3447			}
3448			break;
3449		case PIOD_READ_AUXV:
3450			DPRINTF("Asserting that AUXV length (%zu) is > 0\n",
3451			        io.piod_len);
3452			ATF_REQUIRE(io.piod_len > 0);
3453			for (aip = ai; aip->a_type != AT_NULL; aip++)
3454				DPRINTF("a_type=%#llx a_v=%#llx\n",
3455				    (long long int)aip->a_type,
3456				    (long long int)aip->a_v);
3457			break;
3458		default:
3459			break;
3460		}
3461		break;
3462	case BYTES_TRANSFER_TEXT:
3463		switch (operation) {
3464		case PT_READ_D:
3465		case PT_READ_I:
3466			errno = 0;
3467			lookup_me = ptrace(operation, child,
3468			                   bytes_transfer_dummy, 0);
3469			ATF_REQUIRE_EQ(lookup_me, magic);
3470			SYSCALL_REQUIRE_ERRNO(errno, 0);
3471			break;
3472		case PT_WRITE_D:
3473		case PT_WRITE_I:
3474			SYSCALL_REQUIRE(ptrace(operation, child,
3475			                       bytes_transfer_dummy, magic)
3476			                != -1);
3477			break;
3478		default:
3479			break;
3480		}
3481		break;
3482	case BYTES_TRANSFER_DATA:
3483		switch (operation) {
3484		case PT_READ_D:
3485		case PT_READ_I:
3486			errno = 0;
3487			lookup_me = ptrace(operation, child, &lookup_me, 0);
3488			ATF_REQUIRE_EQ(lookup_me, magic);
3489			SYSCALL_REQUIRE_ERRNO(errno, 0);
3490			break;
3491		case PT_WRITE_D:
3492		case PT_WRITE_I:
3493			lookup_me = magic;
3494			SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me,
3495			                       magic) != -1);
3496			break;
3497		default:
3498			break;
3499		}
3500		break;
3501	default:
3502		break;
3503	}
3504
3505	DPRINTF("Before resuming the child process where it left off and "
3506	    "without signal to be sent\n");
3507	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3508
3509	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3510	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3511
3512	validate_status_exited(status, exitval);
3513
3514	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3515	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3516}
3517
3518#define BYTES_TRANSFER(test, operation, size, type)			\
3519ATF_TC(test);								\
3520ATF_TC_HEAD(test, tc)							\
3521{									\
3522	atf_tc_set_md_var(tc, "descr",					\
3523	    "Verify bytes transfer operation" #operation " and size " #size \
3524	    " of type " #type);						\
3525}									\
3526									\
3527ATF_TC_BODY(test, tc)							\
3528{									\
3529									\
3530	bytes_transfer(operation, size, BYTES_TRANSFER_##type);		\
3531}
3532
3533// DATA
3534
3535BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO)
3536BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO)
3537BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO)
3538BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO)
3539
3540BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO)
3541BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO)
3542BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO)
3543BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO)
3544
3545BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO)
3546BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO)
3547BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO)
3548BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO)
3549
3550BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO)
3551BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO)
3552BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO)
3553BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO)
3554
3555BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA)
3556BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA)
3557BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA)
3558BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA)
3559
3560// TEXT
3561
3562BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO)
3563BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO)
3564BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO)
3565BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO)
3566
3567BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO)
3568BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO)
3569BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO)
3570BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO)
3571
3572BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO)
3573BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO)
3574BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO)
3575BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO)
3576
3577BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO)
3578BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO)
3579BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO)
3580BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO)
3581
3582BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT)
3583BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT)
3584BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT)
3585BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT)
3586
3587// AUXV
3588
3589BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV)
3590
3591/// ----------------------------------------------------------------------------
3592
3593#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS)
3594static void
3595access_regs(const char *regset, const char *aux)
3596{
3597	const int exitval = 5;
3598	const int sigval = SIGSTOP;
3599	pid_t child, wpid;
3600#if defined(TWAIT_HAVE_STATUS)
3601	int status;
3602#endif
3603#if defined(HAVE_GPREGS)
3604	struct reg gpr;
3605	register_t rgstr;
3606#endif
3607#if defined(HAVE_FPREGS)
3608	struct fpreg fpr;
3609#endif
3610
3611#if !defined(HAVE_GPREGS)
3612	if (strcmp(regset, "regs") == 0)
3613		atf_tc_fail("Impossible test scenario!");
3614#endif
3615
3616#if !defined(HAVE_FPREGS)
3617	if (strcmp(regset, "fpregs") == 0)
3618		atf_tc_fail("Impossible test scenario!");
3619#endif
3620
3621	DPRINTF("Before forking process PID=%d\n", getpid());
3622	SYSCALL_REQUIRE((child = fork()) != -1);
3623	if (child == 0) {
3624		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3625		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3626
3627		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3628		FORKEE_ASSERT(raise(sigval) == 0);
3629
3630		DPRINTF("Before exiting of the child process\n");
3631		_exit(exitval);
3632	}
3633	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3634
3635	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3636	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3637
3638	validate_status_stopped(status, sigval);
3639
3640#if defined(HAVE_GPREGS)
3641	if (strcmp(regset, "regs") == 0) {
3642		DPRINTF("Call GETREGS for the child process\n");
3643		SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1);
3644
3645		if (strcmp(aux, "none") == 0) {
3646			DPRINTF("Retrieved registers\n");
3647		} else if (strcmp(aux, "pc") == 0) {
3648			rgstr = PTRACE_REG_PC(&gpr);
3649			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
3650		} else if (strcmp(aux, "set_pc") == 0) {
3651			rgstr = PTRACE_REG_PC(&gpr);
3652			PTRACE_REG_SET_PC(&gpr, rgstr);
3653		} else if (strcmp(aux, "sp") == 0) {
3654			rgstr = PTRACE_REG_SP(&gpr);
3655			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
3656		} else if (strcmp(aux, "intrv") == 0) {
3657			rgstr = PTRACE_REG_INTRV(&gpr);
3658			DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr);
3659		} else if (strcmp(aux, "setregs") == 0) {
3660			DPRINTF("Call SETREGS for the child process\n");
3661			SYSCALL_REQUIRE(
3662			    ptrace(PT_GETREGS, child, &gpr, 0) != -1);
3663		}
3664	}
3665#endif
3666
3667#if defined(HAVE_FPREGS)
3668	if (strcmp(regset, "fpregs") == 0) {
3669		DPRINTF("Call GETFPREGS for the child process\n");
3670		SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1);
3671
3672		if (strcmp(aux, "getfpregs") == 0) {
3673			DPRINTF("Retrieved FP registers\n");
3674		} else if (strcmp(aux, "setfpregs") == 0) {
3675			DPRINTF("Call SETFPREGS for the child\n");
3676			SYSCALL_REQUIRE(
3677			    ptrace(PT_SETFPREGS, child, &fpr, 0) != -1);
3678		}
3679	}
3680#endif
3681
3682	DPRINTF("Before resuming the child process where it left off and "
3683	    "without signal to be sent\n");
3684	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3685
3686	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3687	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3688
3689	validate_status_exited(status, exitval);
3690
3691	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3692	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3693}
3694
3695#define ACCESS_REGS(test, regset, aux)					\
3696ATF_TC(test);								\
3697ATF_TC_HEAD(test, tc)							\
3698{									\
3699        atf_tc_set_md_var(tc, "descr",					\
3700            "Verify " regset " with auxiliary operation: " aux);	\
3701}									\
3702									\
3703ATF_TC_BODY(test, tc)							\
3704{									\
3705									\
3706        access_regs(regset, aux);					\
3707}
3708#endif
3709
3710#if defined(HAVE_GPREGS)
3711ACCESS_REGS(access_regs1, "regs", "none")
3712ACCESS_REGS(access_regs2, "regs", "pc")
3713ACCESS_REGS(access_regs3, "regs", "set_pc")
3714ACCESS_REGS(access_regs4, "regs", "sp")
3715ACCESS_REGS(access_regs5, "regs", "intrv")
3716ACCESS_REGS(access_regs6, "regs", "setregs")
3717#endif
3718#if defined(HAVE_FPREGS)
3719ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs")
3720ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs")
3721#endif
3722
3723/// ----------------------------------------------------------------------------
3724
3725#if defined(PT_STEP)
3726static void
3727ptrace_step(int N, int setstep, bool masked, bool ignored)
3728{
3729	const int exitval = 5;
3730	const int sigval = SIGSTOP;
3731	pid_t child, wpid;
3732#if defined(TWAIT_HAVE_STATUS)
3733	int status;
3734#endif
3735	int happy;
3736	struct sigaction sa;
3737	struct ptrace_siginfo info;
3738	sigset_t intmask;
3739	struct kinfo_proc2 kp;
3740	size_t len = sizeof(kp);
3741
3742	int name[6];
3743	const size_t namelen = __arraycount(name);
3744	ki_sigset_t kp_sigmask;
3745	ki_sigset_t kp_sigignore;
3746
3747#if defined(__arm__)
3748	/* PT_STEP not supported on arm 32-bit */
3749	atf_tc_expect_fail("PR kern/52119");
3750#endif
3751
3752	if (masked || ignored)
3753		atf_tc_expect_fail("Unexpected sigmask reset on crash under "
3754		    "debugger");
3755
3756	DPRINTF("Before forking process PID=%d\n", getpid());
3757	SYSCALL_REQUIRE((child = fork()) != -1);
3758	if (child == 0) {
3759		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3760		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3761
3762		if (masked) {
3763			sigemptyset(&intmask);
3764			sigaddset(&intmask, SIGTRAP);
3765			sigprocmask(SIG_BLOCK, &intmask, NULL);
3766		}
3767
3768		if (ignored) {
3769			memset(&sa, 0, sizeof(sa));
3770			sa.sa_handler = SIG_IGN;
3771			sigemptyset(&sa.sa_mask);
3772			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
3773		}
3774
3775		happy = check_happy(999);
3776
3777		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3778		FORKEE_ASSERT(raise(sigval) == 0);
3779
3780		FORKEE_ASSERT_EQ(happy, check_happy(999));
3781
3782		DPRINTF("Before exiting of the child process\n");
3783		_exit(exitval);
3784	}
3785	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3786
3787	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3788	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3789
3790	validate_status_stopped(status, sigval);
3791
3792	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3793	SYSCALL_REQUIRE(
3794	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3795
3796	DPRINTF("Before checking siginfo_t\n");
3797	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3798	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3799
3800	name[0] = CTL_KERN,
3801	name[1] = KERN_PROC2,
3802	name[2] = KERN_PROC_PID;
3803	name[3] = child;
3804	name[4] = sizeof(kp);
3805	name[5] = 1;
3806
3807	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
3808
3809	if (masked)
3810		kp_sigmask = kp.p_sigmask;
3811
3812	if (ignored)
3813		kp_sigignore = kp.p_sigignore;
3814
3815	while (N --> 0) {
3816		if (setstep) {
3817			DPRINTF("Before resuming the child process where it "
3818			    "left off and without signal to be sent (use "
3819			    "PT_SETSTEP and PT_CONTINUE)\n");
3820			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
3821			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
3822			    != -1);
3823		} else {
3824			DPRINTF("Before resuming the child process where it "
3825			    "left off and without signal to be sent (use "
3826			    "PT_STEP)\n");
3827			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
3828			    != -1);
3829		}
3830
3831		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3832		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3833		    child);
3834
3835		validate_status_stopped(status, SIGTRAP);
3836
3837		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3838		SYSCALL_REQUIRE(
3839		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3840
3841		DPRINTF("Before checking siginfo_t\n");
3842		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
3843		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
3844
3845		if (setstep) {
3846			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
3847		}
3848
3849		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
3850
3851		if (masked) {
3852			DPRINTF("kp_sigmask="
3853			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
3854			    PRIx32 "\n",
3855			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
3856			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
3857
3858			DPRINTF("kp.p_sigmask="
3859			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
3860			    PRIx32 "\n",
3861			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
3862			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
3863
3864			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
3865			    sizeof(kp_sigmask)));
3866		}
3867
3868		if (ignored) {
3869			DPRINTF("kp_sigignore="
3870			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
3871			    PRIx32 "\n",
3872			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
3873			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
3874
3875			DPRINTF("kp.p_sigignore="
3876			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
3877			    PRIx32 "\n",
3878			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
3879			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
3880
3881			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
3882			    sizeof(kp_sigignore)));
3883		}
3884	}
3885
3886	DPRINTF("Before resuming the child process where it left off and "
3887	    "without signal to be sent\n");
3888	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3889
3890	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3891	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3892
3893	validate_status_exited(status, exitval);
3894
3895	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3896	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3897}
3898
3899#define PTRACE_STEP(test, N, setstep)					\
3900ATF_TC(test);								\
3901ATF_TC_HEAD(test, tc)							\
3902{									\
3903        atf_tc_set_md_var(tc, "descr",					\
3904            "Verify " #N " (PT_SETSTEP set to: " #setstep ")");		\
3905}									\
3906									\
3907ATF_TC_BODY(test, tc)							\
3908{									\
3909									\
3910        ptrace_step(N, setstep, false, false);				\
3911}
3912
3913PTRACE_STEP(step1, 1, 0)
3914PTRACE_STEP(step2, 2, 0)
3915PTRACE_STEP(step3, 3, 0)
3916PTRACE_STEP(step4, 4, 0)
3917PTRACE_STEP(setstep1, 1, 1)
3918PTRACE_STEP(setstep2, 2, 1)
3919PTRACE_STEP(setstep3, 3, 1)
3920PTRACE_STEP(setstep4, 4, 1)
3921
3922ATF_TC(step_signalmasked);
3923ATF_TC_HEAD(step_signalmasked, tc)
3924{
3925	atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with masked SIGTRAP");
3926}
3927
3928ATF_TC_BODY(step_signalmasked, tc)
3929{
3930
3931	ptrace_step(1, 0, true, false);
3932}
3933
3934ATF_TC(step_signalignored);
3935ATF_TC_HEAD(step_signalignored, tc)
3936{
3937	atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with ignored SIGTRAP");
3938}
3939
3940ATF_TC_BODY(step_signalignored, tc)
3941{
3942
3943	ptrace_step(1, 0, false, true);
3944}
3945#endif
3946
3947/// ----------------------------------------------------------------------------
3948
3949static void
3950ptrace_kill(const char *type)
3951{
3952	const int sigval = SIGSTOP;
3953	pid_t child, wpid;
3954#if defined(TWAIT_HAVE_STATUS)
3955	int status;
3956#endif
3957
3958	DPRINTF("Before forking process PID=%d\n", getpid());
3959	SYSCALL_REQUIRE((child = fork()) != -1);
3960	if (child == 0) {
3961		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3962		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3963
3964		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3965		FORKEE_ASSERT(raise(sigval) == 0);
3966
3967		/* NOTREACHED */
3968		FORKEE_ASSERTX(0 &&
3969		    "Child should be terminated by a signal from its parent");
3970	}
3971	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3972
3973	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3974	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3975
3976	validate_status_stopped(status, sigval);
3977
3978	DPRINTF("Before killing the child process with %s\n", type);
3979	if (strcmp(type, "ptrace(PT_KILL)") == 0) {
3980		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
3981	} else if (strcmp(type, "kill(SIGKILL)") == 0) {
3982		kill(child, SIGKILL);
3983	} else if (strcmp(type, "killpg(SIGKILL)") == 0) {
3984		setpgid(child, 0);
3985		killpg(getpgid(child), SIGKILL);
3986	}
3987
3988	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3989	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3990
3991	validate_status_signaled(status, SIGKILL, 0);
3992
3993	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3994	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3995}
3996
3997#define PTRACE_KILL(test, type)						\
3998ATF_TC(test);								\
3999ATF_TC_HEAD(test, tc)							\
4000{									\
4001        atf_tc_set_md_var(tc, "descr",					\
4002            "Verify killing the child with " type);			\
4003}									\
4004									\
4005ATF_TC_BODY(test, tc)							\
4006{									\
4007									\
4008        ptrace_kill(type);						\
4009}
4010
4011// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1
4012PTRACE_KILL(kill1, "ptrace(PT_KILL)")
4013PTRACE_KILL(kill2, "kill(SIGKILL)")
4014PTRACE_KILL(kill3, "killpg(SIGKILL)")
4015
4016/// ----------------------------------------------------------------------------
4017
4018static void
4019traceme_lwpinfo(const int threads)
4020{
4021	const int sigval = SIGSTOP;
4022	const int sigval2 = SIGINT;
4023	pid_t child, wpid;
4024#if defined(TWAIT_HAVE_STATUS)
4025	int status;
4026#endif
4027	struct ptrace_lwpinfo lwp = {0, 0};
4028	struct ptrace_siginfo info;
4029
4030	/* Maximum number of supported threads in this test */
4031	pthread_t t[3];
4032	int n, rv;
4033
4034	ATF_REQUIRE((int)__arraycount(t) >= threads);
4035
4036	DPRINTF("Before forking process PID=%d\n", getpid());
4037	SYSCALL_REQUIRE((child = fork()) != -1);
4038	if (child == 0) {
4039		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4040		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4041
4042		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4043		FORKEE_ASSERT(raise(sigval) == 0);
4044
4045		for (n = 0; n < threads; n++) {
4046			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
4047			FORKEE_ASSERT(rv == 0);
4048		}
4049
4050		DPRINTF("Before raising %s from child\n", strsignal(sigval2));
4051		FORKEE_ASSERT(raise(sigval2) == 0);
4052
4053		/* NOTREACHED */
4054		FORKEE_ASSERTX(0 && "Not reached");
4055	}
4056	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4057
4058	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4059	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4060
4061	validate_status_stopped(status, sigval);
4062
4063	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
4064	SYSCALL_REQUIRE(
4065	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4066
4067	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4068	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4069	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4070	    info.psi_siginfo.si_errno);
4071
4072	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4073	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4074
4075	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4076	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4077
4078	DPRINTF("Assert that there exists a single thread only\n");
4079	ATF_REQUIRE(lwp.pl_lwpid > 0);
4080
4081	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
4082	    lwp.pl_lwpid);
4083	FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
4084
4085	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4086	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4087
4088	DPRINTF("Assert that there exists a single thread only\n");
4089	ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
4090
4091	DPRINTF("Before resuming the child process where it left off and "
4092	    "without signal to be sent\n");
4093	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4094
4095	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4096	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4097
4098	validate_status_stopped(status, sigval2);
4099
4100	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
4101	SYSCALL_REQUIRE(
4102	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4103
4104	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4105	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4106	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4107	    info.psi_siginfo.si_errno);
4108
4109	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
4110	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4111
4112	memset(&lwp, 0, sizeof(lwp));
4113
4114	for (n = 0; n <= threads; n++) {
4115		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4116		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4117		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4118
4119		DPRINTF("Assert that the thread exists\n");
4120		ATF_REQUIRE(lwp.pl_lwpid > 0);
4121
4122		DPRINTF("Assert that lwp thread %d received expected event\n",
4123		    lwp.pl_lwpid);
4124		FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ?
4125		    PL_EVENT_SIGNAL : PL_EVENT_NONE);
4126	}
4127	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4128	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
4129	DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4130
4131	DPRINTF("Assert that there are no more threads\n");
4132	ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
4133
4134	DPRINTF("Before resuming the child process where it left off and "
4135	    "without signal to be sent\n");
4136	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1);
4137
4138	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4139	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4140
4141	validate_status_signaled(status, SIGKILL, 0);
4142
4143	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4144	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4145}
4146
4147#define TRACEME_LWPINFO(test, threads)					\
4148ATF_TC(test);								\
4149ATF_TC_HEAD(test, tc)							\
4150{									\
4151	atf_tc_set_md_var(tc, "descr",					\
4152	    "Verify LWPINFO with the child with " #threads		\
4153	    " spawned extra threads");					\
4154}									\
4155									\
4156ATF_TC_BODY(test, tc)							\
4157{									\
4158									\
4159	traceme_lwpinfo(threads);					\
4160}
4161
4162TRACEME_LWPINFO(traceme_lwpinfo0, 0)
4163TRACEME_LWPINFO(traceme_lwpinfo1, 1)
4164TRACEME_LWPINFO(traceme_lwpinfo2, 2)
4165TRACEME_LWPINFO(traceme_lwpinfo3, 3)
4166
4167/// ----------------------------------------------------------------------------
4168
4169#if defined(TWAIT_HAVE_PID)
4170static void
4171attach_lwpinfo(const int threads)
4172{
4173	const int sigval = SIGINT;
4174	struct msg_fds parent_tracee, parent_tracer;
4175	const int exitval_tracer = 10;
4176	pid_t tracee, tracer, wpid;
4177	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4178#if defined(TWAIT_HAVE_STATUS)
4179	int status;
4180#endif
4181	struct ptrace_lwpinfo lwp = {0, 0};
4182	struct ptrace_siginfo info;
4183
4184	/* Maximum number of supported threads in this test */
4185	pthread_t t[3];
4186	int n, rv;
4187
4188	DPRINTF("Spawn tracee\n");
4189	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4190	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4191	tracee = atf_utils_fork();
4192	if (tracee == 0) {
4193		/* Wait for message from the parent */
4194		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
4195
4196		CHILD_FROM_PARENT("spawn threads", parent_tracee, msg);
4197
4198		for (n = 0; n < threads; n++) {
4199			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
4200			FORKEE_ASSERT(rv == 0);
4201		}
4202
4203		CHILD_TO_PARENT("tracee exit", parent_tracee, msg);
4204
4205		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4206		FORKEE_ASSERT(raise(sigval) == 0);
4207
4208		/* NOTREACHED */
4209		FORKEE_ASSERTX(0 && "Not reached");
4210	}
4211	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
4212
4213	DPRINTF("Spawn debugger\n");
4214	tracer = atf_utils_fork();
4215	if (tracer == 0) {
4216		/* No IPC to communicate with the child */
4217		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4218		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4219
4220		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4221		FORKEE_REQUIRE_SUCCESS(
4222		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4223
4224		forkee_status_stopped(status, SIGSTOP);
4225
4226		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4227		    "tracee");
4228		FORKEE_ASSERT(
4229		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
4230
4231		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4232		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4233		    "si_errno=%#x\n",
4234		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4235		    info.psi_siginfo.si_errno);
4236
4237		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
4238		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
4239
4240		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4241		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
4242		    != -1);
4243
4244		DPRINTF("Assert that there exists a thread\n");
4245		FORKEE_ASSERTX(lwp.pl_lwpid > 0);
4246
4247		DPRINTF("Assert that lwp thread %d received event "
4248		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
4249		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
4250
4251		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
4252		    "tracee\n");
4253		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
4254		    != -1);
4255
4256		DPRINTF("Assert that there are no more lwp threads in "
4257		    "tracee\n");
4258		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
4259
4260		/* Resume tracee with PT_CONTINUE */
4261		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4262
4263		/* Inform parent that tracer has attached to tracee */
4264		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
4265
4266		/* Wait for parent */
4267		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
4268
4269		/* Wait for tracee and assert that it raised a signal */
4270		FORKEE_REQUIRE_SUCCESS(
4271		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4272
4273		forkee_status_stopped(status, SIGINT);
4274
4275		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4276		    "child");
4277		FORKEE_ASSERT(
4278		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
4279
4280		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4281		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4282		    "si_errno=%#x\n",
4283		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4284		    info.psi_siginfo.si_errno);
4285
4286		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
4287		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
4288
4289		memset(&lwp, 0, sizeof(lwp));
4290
4291		for (n = 0; n <= threads; n++) {
4292			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
4293			    "child\n");
4294			FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp,
4295			    sizeof(lwp)) != -1);
4296			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4297
4298			DPRINTF("Assert that the thread exists\n");
4299			FORKEE_ASSERT(lwp.pl_lwpid > 0);
4300
4301			DPRINTF("Assert that lwp thread %d received expected "
4302			    "event\n", lwp.pl_lwpid);
4303			FORKEE_ASSERT_EQ(lwp.pl_event,
4304			    info.psi_lwpid == lwp.pl_lwpid ?
4305			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
4306		}
4307		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
4308		    "tracee\n");
4309		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
4310		    != -1);
4311		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
4312
4313		DPRINTF("Assert that there are no more threads\n");
4314		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
4315
4316		DPRINTF("Before resuming the child process where it left off "
4317		    "and without signal to be sent\n");
4318		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL)
4319		    != -1);
4320
4321		/* Wait for tracee and assert that it exited */
4322		FORKEE_REQUIRE_SUCCESS(
4323		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4324
4325		forkee_status_signaled(status, SIGKILL, 0);
4326
4327		DPRINTF("Before exiting of the tracer process\n");
4328		_exit(exitval_tracer);
4329	}
4330
4331	DPRINTF("Wait for the tracer to attach to the tracee\n");
4332	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
4333
4334	DPRINTF("Resume the tracee and spawn threads\n");
4335	PARENT_TO_CHILD("spawn threads", parent_tracee, msg);
4336
4337	DPRINTF("Resume the tracee and let it exit\n");
4338	PARENT_FROM_CHILD("tracee exit", parent_tracee, msg);
4339
4340	DPRINTF("Resume the tracer and let it detect multiple threads\n");
4341	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
4342
4343	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
4344	    TWAIT_FNAME);
4345	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
4346	    tracer);
4347
4348	validate_status_exited(status, exitval_tracer);
4349
4350	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4351	    TWAIT_FNAME);
4352	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4353	    tracee);
4354
4355	validate_status_signaled(status, SIGKILL, 0);
4356
4357	msg_close(&parent_tracer);
4358	msg_close(&parent_tracee);
4359}
4360
4361#define ATTACH_LWPINFO(test, threads)					\
4362ATF_TC(test);								\
4363ATF_TC_HEAD(test, tc)							\
4364{									\
4365	atf_tc_set_md_var(tc, "descr",					\
4366	    "Verify LWPINFO with the child with " #threads		\
4367	    " spawned extra threads (tracer is not the original "	\
4368	    "parent)");							\
4369}									\
4370									\
4371ATF_TC_BODY(test, tc)							\
4372{									\
4373									\
4374	attach_lwpinfo(threads);					\
4375}
4376
4377ATTACH_LWPINFO(attach_lwpinfo0, 0)
4378ATTACH_LWPINFO(attach_lwpinfo1, 1)
4379ATTACH_LWPINFO(attach_lwpinfo2, 2)
4380ATTACH_LWPINFO(attach_lwpinfo3, 3)
4381#endif
4382
4383/// ----------------------------------------------------------------------------
4384
4385static void
4386ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
4387{
4388	const int exitval = 5;
4389	const int sigval = SIGINT;
4390	const int sigfaked = SIGTRAP;
4391	const int sicodefaked = TRAP_BRKPT;
4392	pid_t child, wpid;
4393	struct sigaction sa;
4394#if defined(TWAIT_HAVE_STATUS)
4395	int status;
4396#endif
4397	struct ptrace_siginfo info;
4398	memset(&info, 0, sizeof(info));
4399
4400	DPRINTF("Before forking process PID=%d\n", getpid());
4401	SYSCALL_REQUIRE((child = fork()) != -1);
4402	if (child == 0) {
4403		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4404		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4405
4406		sa.sa_sigaction = sah;
4407		sa.sa_flags = SA_SIGINFO;
4408		sigemptyset(&sa.sa_mask);
4409
4410		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
4411		    != -1);
4412
4413		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4414		FORKEE_ASSERT(raise(sigval) == 0);
4415
4416		FORKEE_ASSERT_EQ(*signal_caught, 1);
4417
4418		DPRINTF("Before exiting of the child process\n");
4419		_exit(exitval);
4420	}
4421	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4422
4423	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4424	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4425
4426	validate_status_stopped(status, sigval);
4427
4428	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4429	SYSCALL_REQUIRE(
4430	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4431
4432	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4433	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4434	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4435	    info.psi_siginfo.si_errno);
4436
4437	if (faked) {
4438		DPRINTF("Before setting new faked signal to signo=%d "
4439		    "si_code=%d\n", sigfaked, sicodefaked);
4440		info.psi_siginfo.si_signo = sigfaked;
4441		info.psi_siginfo.si_code = sicodefaked;
4442	}
4443
4444	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
4445	SYSCALL_REQUIRE(
4446	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
4447
4448	if (faked) {
4449		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4450		    "child\n");
4451		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
4452		    sizeof(info)) != -1);
4453
4454		DPRINTF("Before checking siginfo_t\n");
4455		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
4456		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
4457	}
4458
4459	DPRINTF("Before resuming the child process where it left off and "
4460	    "without signal to be sent\n");
4461	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
4462	    faked ? sigfaked : sigval) != -1);
4463
4464	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4465	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4466
4467	validate_status_exited(status, exitval);
4468
4469	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4470	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4471}
4472
4473#define PTRACE_SIGINFO(test, faked)					\
4474ATF_TC(test);								\
4475ATF_TC_HEAD(test, tc)							\
4476{									\
4477	atf_tc_set_md_var(tc, "descr",					\
4478	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
4479	    "with%s setting signal to new value", faked ? "" : "out");	\
4480}									\
4481									\
4482static int test##_caught = 0;						\
4483									\
4484static void								\
4485test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
4486{									\
4487	if (faked) {							\
4488		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
4489		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
4490		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
4491	} else {							\
4492		FORKEE_ASSERT_EQ(sig, SIGINT);				\
4493		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
4494		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
4495	}								\
4496									\
4497	++ test##_caught;						\
4498}									\
4499									\
4500ATF_TC_BODY(test, tc)							\
4501{									\
4502									\
4503	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
4504}
4505
4506PTRACE_SIGINFO(siginfo_set_unmodified, false)
4507PTRACE_SIGINFO(siginfo_set_faked, true)
4508
4509/// ----------------------------------------------------------------------------
4510
4511ATF_TC(traceme_exec);
4512ATF_TC_HEAD(traceme_exec, tc)
4513{
4514	atf_tc_set_md_var(tc, "descr",
4515	    "Detect SIGTRAP TRAP_EXEC from tracee");
4516}
4517
4518ATF_TC_BODY(traceme_exec, tc)
4519{
4520	const int sigval = SIGTRAP;
4521	pid_t child, wpid;
4522#if defined(TWAIT_HAVE_STATUS)
4523	int status;
4524#endif
4525
4526	struct ptrace_siginfo info;
4527	memset(&info, 0, sizeof(info));
4528
4529	DPRINTF("Before forking process PID=%d\n", getpid());
4530	SYSCALL_REQUIRE((child = fork()) != -1);
4531	if (child == 0) {
4532		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4533		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4534
4535		DPRINTF("Before calling execve(2) from child\n");
4536		execlp("/bin/echo", "/bin/echo", NULL);
4537
4538		FORKEE_ASSERT(0 && "Not reached");
4539	}
4540	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4541
4542	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4543	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4544
4545	validate_status_stopped(status, sigval);
4546
4547	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4548	SYSCALL_REQUIRE(
4549	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4550
4551	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4552	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4553	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4554	    info.psi_siginfo.si_errno);
4555
4556	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4557	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
4558
4559	DPRINTF("Before resuming the child process where it left off and "
4560	    "without signal to be sent\n");
4561	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4562
4563	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4564	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4565
4566	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4567	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4568}
4569
4570/// ----------------------------------------------------------------------------
4571
4572static volatile int done;
4573
4574static void *
4575trace_threads_cb(void *arg __unused)
4576{
4577
4578	done++;
4579
4580	while (done < 3)
4581		continue;
4582
4583	return NULL;
4584}
4585
4586static void
4587trace_threads(bool trace_create, bool trace_exit)
4588{
4589	const int sigval = SIGSTOP;
4590	pid_t child, wpid;
4591#if defined(TWAIT_HAVE_STATUS)
4592	int status;
4593#endif
4594	ptrace_state_t state;
4595	const int slen = sizeof(state);
4596	ptrace_event_t event;
4597	const int elen = sizeof(event);
4598	struct ptrace_siginfo info;
4599
4600	pthread_t t[3];
4601	int rv;
4602	size_t n;
4603	lwpid_t lid;
4604
4605	/* Track created and exited threads */
4606	bool traced_lwps[__arraycount(t)];
4607
4608	atf_tc_skip("PR kern/51995");
4609
4610	DPRINTF("Before forking process PID=%d\n", getpid());
4611	SYSCALL_REQUIRE((child = fork()) != -1);
4612	if (child == 0) {
4613		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4614		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4615
4616		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4617		FORKEE_ASSERT(raise(sigval) == 0);
4618
4619		for (n = 0; n < __arraycount(t); n++) {
4620			rv = pthread_create(&t[n], NULL, trace_threads_cb,
4621			    NULL);
4622			FORKEE_ASSERT(rv == 0);
4623		}
4624
4625		for (n = 0; n < __arraycount(t); n++) {
4626			rv = pthread_join(t[n], NULL);
4627			FORKEE_ASSERT(rv == 0);
4628		}
4629
4630		/*
4631		 * There is race between _exit() and pthread_join() detaching
4632		 * a thread. For simplicity kill the process after detecting
4633		 * LWP events.
4634		 */
4635		while (true)
4636			continue;
4637
4638		FORKEE_ASSERT(0 && "Not reached");
4639	}
4640	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4641
4642	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4643	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4644
4645	validate_status_stopped(status, sigval);
4646
4647	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4648	SYSCALL_REQUIRE(
4649	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4650
4651	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4652	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4653	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4654	    info.psi_siginfo.si_errno);
4655
4656	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4657	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4658
4659	DPRINTF("Set LWP event mask for the child %d\n", child);
4660	memset(&event, 0, sizeof(event));
4661	if (trace_create)
4662		event.pe_set_event |= PTRACE_LWP_CREATE;
4663	if (trace_exit)
4664		event.pe_set_event |= PTRACE_LWP_EXIT;
4665	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
4666
4667	DPRINTF("Before resuming the child process where it left off and "
4668	    "without signal to be sent\n");
4669	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4670
4671	memset(traced_lwps, 0, sizeof(traced_lwps));
4672
4673	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
4674		DPRINTF("Before calling %s() for the child - expected stopped "
4675		    "SIGTRAP\n", TWAIT_FNAME);
4676		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4677		    child);
4678
4679		validate_status_stopped(status, SIGTRAP);
4680
4681		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4682		    "child\n");
4683		SYSCALL_REQUIRE(
4684		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4685
4686		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4687		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4688		    "si_errno=%#x\n",
4689		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4690		    info.psi_siginfo.si_errno);
4691
4692		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4693		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4694
4695		SYSCALL_REQUIRE(
4696		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4697
4698		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
4699		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
4700
4701		lid = state.pe_lwp;
4702		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
4703
4704		traced_lwps[lid - 1] = true;
4705
4706		DPRINTF("Before resuming the child process where it left off "
4707		    "and without signal to be sent\n");
4708		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4709	}
4710
4711	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
4712		DPRINTF("Before calling %s() for the child - expected stopped "
4713		    "SIGTRAP\n", TWAIT_FNAME);
4714		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4715		    child);
4716
4717		validate_status_stopped(status, SIGTRAP);
4718
4719		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4720		    "child\n");
4721		SYSCALL_REQUIRE(
4722		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4723
4724		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4725		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4726		    "si_errno=%#x\n",
4727		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4728		    info.psi_siginfo.si_errno);
4729
4730		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4731		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4732
4733		SYSCALL_REQUIRE(
4734		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4735
4736		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
4737		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
4738
4739		lid = state.pe_lwp;
4740		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
4741
4742		if (trace_create) {
4743			ATF_REQUIRE(traced_lwps[lid - 1] == true);
4744			traced_lwps[lid - 1] = false;
4745		}
4746
4747		DPRINTF("Before resuming the child process where it left off "
4748		    "and without signal to be sent\n");
4749		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4750	}
4751
4752	kill(child, SIGKILL);
4753
4754	DPRINTF("Before calling %s() for the child - expected exited\n",
4755	    TWAIT_FNAME);
4756	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4757
4758	validate_status_signaled(status, SIGKILL, 0);
4759
4760	DPRINTF("Before calling %s() for the child - expected no process\n",
4761	    TWAIT_FNAME);
4762	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4763}
4764
4765#define TRACE_THREADS(test, trace_create, trace_exit)			\
4766ATF_TC(test);								\
4767ATF_TC_HEAD(test, tc)							\
4768{									\
4769        atf_tc_set_md_var(tc, "descr",					\
4770            "Verify spawning threads with%s tracing LWP create and"	\
4771	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
4772	    trace_exit ? "" : "out");					\
4773}									\
4774									\
4775ATF_TC_BODY(test, tc)							\
4776{									\
4777									\
4778        trace_threads(trace_create, trace_exit);			\
4779}
4780
4781TRACE_THREADS(trace_thread1, false, false)
4782TRACE_THREADS(trace_thread2, false, true)
4783TRACE_THREADS(trace_thread3, true, false)
4784TRACE_THREADS(trace_thread4, true, true)
4785
4786/// ----------------------------------------------------------------------------
4787
4788ATF_TC(signal_mask_unrelated);
4789ATF_TC_HEAD(signal_mask_unrelated, tc)
4790{
4791	atf_tc_set_md_var(tc, "descr",
4792	    "Verify that masking single unrelated signal does not stop tracer "
4793	    "from catching other signals");
4794}
4795
4796ATF_TC_BODY(signal_mask_unrelated, tc)
4797{
4798	const int exitval = 5;
4799	const int sigval = SIGSTOP;
4800	const int sigmasked = SIGTRAP;
4801	const int signotmasked = SIGINT;
4802	pid_t child, wpid;
4803#if defined(TWAIT_HAVE_STATUS)
4804	int status;
4805#endif
4806	sigset_t intmask;
4807
4808	DPRINTF("Before forking process PID=%d\n", getpid());
4809	SYSCALL_REQUIRE((child = fork()) != -1);
4810	if (child == 0) {
4811		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4812		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4813
4814		sigemptyset(&intmask);
4815		sigaddset(&intmask, sigmasked);
4816		sigprocmask(SIG_BLOCK, &intmask, NULL);
4817
4818		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4819		FORKEE_ASSERT(raise(sigval) == 0);
4820
4821		DPRINTF("Before raising %s from child\n",
4822		    strsignal(signotmasked));
4823		FORKEE_ASSERT(raise(signotmasked) == 0);
4824
4825		DPRINTF("Before exiting of the child process\n");
4826		_exit(exitval);
4827	}
4828	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4829
4830	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4831	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4832
4833	validate_status_stopped(status, sigval);
4834
4835	DPRINTF("Before resuming the child process where it left off and "
4836	    "without signal to be sent\n");
4837	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4838
4839	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4840	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4841
4842	validate_status_stopped(status, signotmasked);
4843
4844	DPRINTF("Before resuming the child process where it left off and "
4845	    "without signal to be sent\n");
4846	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4847
4848	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4849	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4850
4851	validate_status_exited(status, exitval);
4852
4853	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4854	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4855}
4856
4857/// ----------------------------------------------------------------------------
4858
4859ATF_TC(signal5);
4860ATF_TC_HEAD(signal5, tc)
4861{
4862	atf_tc_set_md_var(tc, "descr",
4863	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
4864	    "catching exec() breakpoint");
4865}
4866
4867ATF_TC_BODY(signal5, tc)
4868{
4869	const int sigval = SIGSTOP;
4870	const int sigmasked = SIGTRAP;
4871	pid_t child, wpid;
4872#if defined(TWAIT_HAVE_STATUS)
4873	int status;
4874#endif
4875	struct ptrace_siginfo info;
4876	sigset_t intmask;
4877
4878	memset(&info, 0, sizeof(info));
4879
4880	DPRINTF("Before forking process PID=%d\n", getpid());
4881	SYSCALL_REQUIRE((child = fork()) != -1);
4882	if (child == 0) {
4883		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4884		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4885
4886		sigemptyset(&intmask);
4887		sigaddset(&intmask, sigmasked);
4888		sigprocmask(SIG_BLOCK, &intmask, NULL);
4889
4890		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4891		FORKEE_ASSERT(raise(sigval) == 0);
4892
4893		DPRINTF("Before calling execve(2) from child\n");
4894		execlp("/bin/echo", "/bin/echo", NULL);
4895
4896		/* NOTREACHED */
4897		FORKEE_ASSERTX(0 && "Not reached");
4898	}
4899	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4900
4901	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4902	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4903
4904	validate_status_stopped(status, sigval);
4905
4906	DPRINTF("Before resuming the child process where it left off and "
4907	    "without signal to be sent\n");
4908	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4909
4910	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4911	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4912
4913	validate_status_stopped(status, sigmasked);
4914
4915	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4916	SYSCALL_REQUIRE(
4917	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4918
4919	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4920	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4921	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4922	    info.psi_siginfo.si_errno);
4923
4924	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked);
4925	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
4926
4927	DPRINTF("Before resuming the child process where it left off and "
4928	    "without signal to be sent\n");
4929	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4930
4931	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4932	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4933
4934	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4935	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4936}
4937
4938#if defined(TWAIT_HAVE_PID)
4939ATF_TC(signal6);
4940ATF_TC_HEAD(signal6, tc)
4941{
4942	atf_tc_set_md_var(tc, "timeout", "5");
4943	atf_tc_set_md_var(tc, "descr",
4944	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
4945	    "catching PTRACE_FORK breakpoint");
4946}
4947
4948ATF_TC_BODY(signal6, tc)
4949{
4950	const int exitval = 5;
4951	const int exitval2 = 15;
4952	const int sigval = SIGSTOP;
4953	const int sigmasked = SIGTRAP;
4954	pid_t child, child2, wpid;
4955#if defined(TWAIT_HAVE_STATUS)
4956	int status;
4957#endif
4958	sigset_t intmask;
4959	ptrace_state_t state;
4960	const int slen = sizeof(state);
4961	ptrace_event_t event;
4962	const int elen = sizeof(event);
4963
4964	atf_tc_expect_fail("PR kern/51918");
4965
4966	DPRINTF("Before forking process PID=%d\n", getpid());
4967	SYSCALL_REQUIRE((child = fork()) != -1);
4968	if (child == 0) {
4969		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4970		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4971
4972		sigemptyset(&intmask);
4973		sigaddset(&intmask, sigmasked);
4974		sigprocmask(SIG_BLOCK, &intmask, NULL);
4975
4976		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4977		FORKEE_ASSERT(raise(sigval) == 0);
4978
4979		FORKEE_ASSERT((child2 = fork()) != -1);
4980
4981		if (child2 == 0)
4982			_exit(exitval2);
4983
4984		FORKEE_REQUIRE_SUCCESS
4985			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
4986
4987		forkee_status_exited(status, exitval2);
4988
4989		DPRINTF("Before exiting of the child process\n");
4990		_exit(exitval);
4991	}
4992	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4993
4994	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4995	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4996
4997	validate_status_stopped(status, sigval);
4998
4999	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
5000	event.pe_set_event = PTRACE_FORK;
5001	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5002
5003	DPRINTF("Before resuming the child process where it left off and "
5004	    "without signal to be sent\n");
5005	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5006
5007	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5008	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5009
5010	validate_status_stopped(status, sigmasked);
5011
5012	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5013	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
5014
5015	child2 = state.pe_other_pid;
5016	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
5017
5018	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
5019	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5020	    child2);
5021
5022	validate_status_stopped(status, SIGTRAP);
5023
5024	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
5025	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
5026	ATF_REQUIRE_EQ(state.pe_other_pid, child);
5027
5028	DPRINTF("Before resuming the forkee process where it left off and "
5029	    "without signal to be sent\n");
5030	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
5031
5032	DPRINTF("Before resuming the child process where it left off and "
5033	    "without signal to be sent\n");
5034	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5035
5036	DPRINTF("Before calling %s() for the forkee - expected exited\n",
5037	    TWAIT_FNAME);
5038	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5039	    child2);
5040
5041	validate_status_exited(status, exitval2);
5042
5043	DPRINTF("Before calling %s() for the forkee - expected no process\n",
5044	    TWAIT_FNAME);
5045	TWAIT_REQUIRE_FAILURE(ECHILD,
5046	    wpid = TWAIT_GENERIC(child2, &status, 0));
5047
5048	DPRINTF("Before calling %s() for the child - expected stopped "
5049	    "SIGCHLD\n", TWAIT_FNAME);
5050	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5051
5052	validate_status_stopped(status, SIGCHLD);
5053
5054	DPRINTF("Before resuming the child process where it left off and "
5055	    "without signal to be sent\n");
5056	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5057
5058	DPRINTF("Before calling %s() for the child - expected exited\n",
5059	    TWAIT_FNAME);
5060	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5061
5062	validate_status_exited(status, exitval);
5063
5064	DPRINTF("Before calling %s() for the child - expected no process\n",
5065	    TWAIT_FNAME);
5066	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5067}
5068#endif
5069
5070#if defined(TWAIT_HAVE_PID)
5071ATF_TC(signal7);
5072ATF_TC_HEAD(signal7, tc)
5073{
5074	atf_tc_set_md_var(tc, "descr",
5075	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5076	    "catching PTRACE_VFORK breakpoint");
5077}
5078
5079ATF_TC_BODY(signal7, tc)
5080{
5081	const int exitval = 5;
5082	const int exitval2 = 15;
5083	const int sigval = SIGSTOP;
5084	const int sigmasked = SIGTRAP;
5085	pid_t child, child2, wpid;
5086#if defined(TWAIT_HAVE_STATUS)
5087	int status;
5088#endif
5089	sigset_t intmask;
5090	ptrace_state_t state;
5091	const int slen = sizeof(state);
5092	ptrace_event_t event;
5093	const int elen = sizeof(event);
5094
5095	atf_tc_expect_fail("PR kern/51918");
5096
5097	DPRINTF("Before forking process PID=%d\n", getpid());
5098	SYSCALL_REQUIRE((child = fork()) != -1);
5099	if (child == 0) {
5100		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5101		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5102
5103		sigemptyset(&intmask);
5104		sigaddset(&intmask, sigmasked);
5105		sigprocmask(SIG_BLOCK, &intmask, NULL);
5106
5107		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5108		FORKEE_ASSERT(raise(sigval) == 0);
5109
5110		FORKEE_ASSERT((child2 = fork()) != -1);
5111
5112		if (child2 == 0)
5113			_exit(exitval2);
5114
5115		FORKEE_REQUIRE_SUCCESS
5116			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
5117
5118		forkee_status_exited(status, exitval2);
5119
5120		DPRINTF("Before exiting of the child process\n");
5121		_exit(exitval);
5122	}
5123	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5124
5125	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5126	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5127
5128	validate_status_stopped(status, sigval);
5129
5130	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
5131	event.pe_set_event = PTRACE_VFORK;
5132	SYSCALL_REQUIRE(
5133	    ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 ||
5134	    errno == ENOTSUP);
5135
5136	DPRINTF("Before resuming the child process where it left off and "
5137	    "without signal to be sent\n");
5138	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5139
5140	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5141	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5142
5143	validate_status_stopped(status, sigmasked);
5144
5145	SYSCALL_REQUIRE(
5146	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5147	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
5148
5149	child2 = state.pe_other_pid;
5150	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
5151
5152	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
5153	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5154	    child2);
5155
5156	validate_status_stopped(status, SIGTRAP);
5157
5158	SYSCALL_REQUIRE(
5159	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
5160	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
5161	ATF_REQUIRE_EQ(state.pe_other_pid, child);
5162
5163	DPRINTF("Before resuming the forkee process where it left off and "
5164	    "without signal to be sent\n");
5165	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
5166
5167	DPRINTF("Before resuming the child process where it left off and "
5168	    "without signal to be sent\n");
5169	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5170
5171	DPRINTF("Before calling %s() for the forkee - expected exited\n",
5172	    TWAIT_FNAME);
5173	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5174	    child2);
5175
5176	validate_status_exited(status, exitval2);
5177
5178	DPRINTF("Before calling %s() for the forkee - expected no process\n",
5179	    TWAIT_FNAME);
5180	TWAIT_REQUIRE_FAILURE(ECHILD,
5181	    wpid = TWAIT_GENERIC(child2, &status, 0));
5182
5183	DPRINTF("Before calling %s() for the child - expected stopped "
5184	    "SIGCHLD\n", TWAIT_FNAME);
5185	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5186
5187	validate_status_stopped(status, SIGCHLD);
5188
5189	DPRINTF("Before resuming the child process where it left off and "
5190	    "without signal to be sent\n");
5191	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5192
5193	DPRINTF("Before calling %s() for the child - expected exited\n",
5194	    TWAIT_FNAME);
5195	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5196
5197	validate_status_exited(status, exitval);
5198
5199	DPRINTF("Before calling %s() for the child - expected no process\n",
5200	    TWAIT_FNAME);
5201	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5202}
5203#endif
5204
5205ATF_TC(signal8);
5206ATF_TC_HEAD(signal8, tc)
5207{
5208	atf_tc_set_md_var(tc, "descr",
5209	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5210	    "catching PTRACE_VFORK_DONE breakpoint");
5211}
5212
5213ATF_TC_BODY(signal8, tc)
5214{
5215	const int exitval = 5;
5216	const int exitval2 = 15;
5217	const int sigval = SIGSTOP;
5218	const int sigmasked = SIGTRAP;
5219	pid_t child, child2, wpid;
5220#if defined(TWAIT_HAVE_STATUS)
5221	int status;
5222#endif
5223	sigset_t intmask;
5224	ptrace_state_t state;
5225	const int slen = sizeof(state);
5226	ptrace_event_t event;
5227	const int elen = sizeof(event);
5228
5229	atf_tc_expect_fail("PR kern/51918");
5230
5231	DPRINTF("Before forking process PID=%d\n", getpid());
5232	SYSCALL_REQUIRE((child = fork()) != -1);
5233	if (child == 0) {
5234		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5235		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5236
5237		sigemptyset(&intmask);
5238		sigaddset(&intmask, sigmasked);
5239		sigprocmask(SIG_BLOCK, &intmask, NULL);
5240
5241		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5242		FORKEE_ASSERT(raise(sigval) == 0);
5243
5244		FORKEE_ASSERT((child2 = vfork()) != -1);
5245
5246		if (child2 == 0)
5247			_exit(exitval2);
5248
5249		FORKEE_REQUIRE_SUCCESS
5250			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
5251
5252		forkee_status_exited(status, exitval2);
5253
5254		DPRINTF("Before exiting of the child process\n");
5255		_exit(exitval);
5256	}
5257	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5258
5259	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5260	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5261
5262	validate_status_stopped(status, sigval);
5263
5264	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
5265	    child);
5266	event.pe_set_event = PTRACE_VFORK_DONE;
5267	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5268
5269	DPRINTF("Before resuming the child process where it left off and "
5270	    "without signal to be sent\n");
5271	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5272
5273	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5274	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5275
5276	validate_status_stopped(status, sigmasked);
5277
5278	SYSCALL_REQUIRE(
5279	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5280	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
5281
5282	child2 = state.pe_other_pid;
5283	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
5284
5285	DPRINTF("Before resuming the child process where it left off and "
5286	    "without signal to be sent\n");
5287	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5288
5289	DPRINTF("Before calling %s() for the child - expected stopped "
5290	    "SIGCHLD\n", TWAIT_FNAME);
5291	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5292
5293	validate_status_stopped(status, SIGCHLD);
5294
5295	DPRINTF("Before resuming the child process where it left off and "
5296	    "without signal to be sent\n");
5297	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5298
5299	DPRINTF("Before calling %s() for the child - expected exited\n",
5300	    TWAIT_FNAME);
5301	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5302
5303	validate_status_exited(status, exitval);
5304
5305	DPRINTF("Before calling %s() for the child - expected no process\n",
5306	    TWAIT_FNAME);
5307	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5308}
5309
5310volatile lwpid_t the_lwp_id = 0;
5311
5312static void
5313lwp_main_func(void *arg)
5314{
5315	the_lwp_id = _lwp_self();
5316	_lwp_exit();
5317}
5318
5319ATF_TC(signal9);
5320ATF_TC_HEAD(signal9, tc)
5321{
5322	atf_tc_set_md_var(tc, "descr",
5323	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5324	    "catching PTRACE_LWP_CREATE breakpoint");
5325}
5326
5327ATF_TC_BODY(signal9, tc)
5328{
5329	const int exitval = 5;
5330	const int sigval = SIGSTOP;
5331	const int sigmasked = SIGTRAP;
5332	pid_t child, wpid;
5333#if defined(TWAIT_HAVE_STATUS)
5334	int status;
5335#endif
5336	sigset_t intmask;
5337	ptrace_state_t state;
5338	const int slen = sizeof(state);
5339	ptrace_event_t event;
5340	const int elen = sizeof(event);
5341	ucontext_t uc;
5342	lwpid_t lid;
5343	static const size_t ssize = 16*1024;
5344	void *stack;
5345
5346	atf_tc_expect_fail("PR kern/51918");
5347
5348	DPRINTF("Before forking process PID=%d\n", getpid());
5349	SYSCALL_REQUIRE((child = fork()) != -1);
5350	if (child == 0) {
5351		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5352		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5353
5354		sigemptyset(&intmask);
5355		sigaddset(&intmask, sigmasked);
5356		sigprocmask(SIG_BLOCK, &intmask, NULL);
5357
5358		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5359		FORKEE_ASSERT(raise(sigval) == 0);
5360
5361		DPRINTF("Before allocating memory for stack in child\n");
5362		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5363
5364		DPRINTF("Before making context for new lwp in child\n");
5365		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5366
5367		DPRINTF("Before creating new in child\n");
5368		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5369
5370		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5371		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5372
5373		DPRINTF("Before verifying that reported %d and running lid %d "
5374		    "are the same\n", lid, the_lwp_id);
5375		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5376
5377		DPRINTF("Before exiting of the child process\n");
5378		_exit(exitval);
5379	}
5380	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5381
5382	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5383	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5384
5385	validate_status_stopped(status, sigval);
5386
5387	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
5388	event.pe_set_event = PTRACE_LWP_CREATE;
5389	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5390
5391	DPRINTF("Before resuming the child process where it left off and "
5392	    "without signal to be sent\n");
5393	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5394
5395	DPRINTF("Before calling %s() for the child - expected stopped "
5396	    "SIGTRAP\n", TWAIT_FNAME);
5397	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5398
5399	validate_status_stopped(status, sigmasked);
5400
5401	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5402
5403	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
5404
5405	lid = state.pe_lwp;
5406	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
5407
5408	DPRINTF("Before resuming the child process where it left off and "
5409	    "without signal to be sent\n");
5410	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5411
5412	DPRINTF("Before calling %s() for the child - expected exited\n",
5413	    TWAIT_FNAME);
5414	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5415
5416	validate_status_exited(status, exitval);
5417
5418	DPRINTF("Before calling %s() for the child - expected no process\n",
5419	    TWAIT_FNAME);
5420	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5421}
5422
5423ATF_TC(signal10);
5424ATF_TC_HEAD(signal10, tc)
5425{
5426	atf_tc_set_md_var(tc, "descr",
5427	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5428	    "catching PTRACE_LWP_EXIT breakpoint");
5429}
5430
5431ATF_TC_BODY(signal10, tc)
5432{
5433	const int exitval = 5;
5434	const int sigval = SIGSTOP;
5435	const int sigmasked = SIGTRAP;
5436	pid_t child, wpid;
5437#if defined(TWAIT_HAVE_STATUS)
5438	int status;
5439#endif
5440	sigset_t intmask;
5441	ptrace_state_t state;
5442	const int slen = sizeof(state);
5443	ptrace_event_t event;
5444	const int elen = sizeof(event);
5445	ucontext_t uc;
5446	lwpid_t lid;
5447	static const size_t ssize = 16*1024;
5448	void *stack;
5449
5450	atf_tc_expect_fail("PR kern/51918");
5451
5452	DPRINTF("Before forking process PID=%d\n", getpid());
5453	SYSCALL_REQUIRE((child = fork()) != -1);
5454	if (child == 0) {
5455		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5456		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5457
5458		sigemptyset(&intmask);
5459		sigaddset(&intmask, sigmasked);
5460		sigprocmask(SIG_BLOCK, &intmask, NULL);
5461
5462		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5463		FORKEE_ASSERT(raise(sigval) == 0);
5464
5465		DPRINTF("Before allocating memory for stack in child\n");
5466		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5467
5468		DPRINTF("Before making context for new lwp in child\n");
5469		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5470
5471		DPRINTF("Before creating new in child\n");
5472		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5473
5474		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5475		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5476
5477		DPRINTF("Before verifying that reported %d and running lid %d "
5478		    "are the same\n", lid, the_lwp_id);
5479		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5480
5481		DPRINTF("Before exiting of the child process\n");
5482		_exit(exitval);
5483	}
5484	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5485
5486	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5487	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5488
5489	validate_status_stopped(status, sigval);
5490
5491	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
5492	event.pe_set_event = PTRACE_LWP_EXIT;
5493	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5494
5495	DPRINTF("Before resuming the child process where it left off and "
5496	    "without signal to be sent\n");
5497	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5498
5499	DPRINTF("Before calling %s() for the child - expected stopped "
5500	    "SIGTRAP\n", TWAIT_FNAME);
5501	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5502
5503	validate_status_stopped(status, sigmasked);
5504
5505	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5506
5507	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
5508
5509	lid = state.pe_lwp;
5510	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
5511
5512	DPRINTF("Before resuming the child process where it left off and "
5513	    "without signal to be sent\n");
5514	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5515
5516	DPRINTF("Before calling %s() for the child - expected exited\n",
5517	    TWAIT_FNAME);
5518	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5519
5520	validate_status_exited(status, exitval);
5521
5522	DPRINTF("Before calling %s() for the child - expected no process\n",
5523	    TWAIT_FNAME);
5524	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5525}
5526
5527static void
5528lwp_main_stop(void *arg)
5529{
5530	the_lwp_id = _lwp_self();
5531
5532	raise(SIGTRAP);
5533
5534	_lwp_exit();
5535}
5536
5537ATF_TC(suspend1);
5538ATF_TC_HEAD(suspend1, tc)
5539{
5540	atf_tc_set_md_var(tc, "descr",
5541	    "Verify that a thread can be suspended by a debugger and later "
5542	    "resumed by a tracee");
5543}
5544
5545ATF_TC_BODY(suspend1, tc)
5546{
5547	const int exitval = 5;
5548	const int sigval = SIGSTOP;
5549	pid_t child, wpid;
5550#if defined(TWAIT_HAVE_STATUS)
5551	int status;
5552#endif
5553	ucontext_t uc;
5554	lwpid_t lid;
5555	static const size_t ssize = 16*1024;
5556	void *stack;
5557	struct ptrace_lwpinfo pl;
5558	struct ptrace_siginfo psi;
5559	volatile int go = 0;
5560
5561	// Feature pending for refactoring
5562	atf_tc_expect_fail("PR kern/51995");
5563
5564	// Hangs with qemu
5565	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5566
5567	DPRINTF("Before forking process PID=%d\n", getpid());
5568	SYSCALL_REQUIRE((child = fork()) != -1);
5569	if (child == 0) {
5570		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5571		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5572
5573		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5574		FORKEE_ASSERT(raise(sigval) == 0);
5575
5576		DPRINTF("Before allocating memory for stack in child\n");
5577		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5578
5579		DPRINTF("Before making context for new lwp in child\n");
5580		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
5581
5582		DPRINTF("Before creating new in child\n");
5583		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5584
5585		while (go == 0)
5586			continue;
5587
5588		raise(SIGINT);
5589
5590		FORKEE_ASSERT(_lwp_continue(lid) == 0);
5591
5592		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5593		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5594
5595		DPRINTF("Before verifying that reported %d and running lid %d "
5596		    "are the same\n", lid, the_lwp_id);
5597		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5598
5599		DPRINTF("Before exiting of the child process\n");
5600		_exit(exitval);
5601	}
5602	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5603
5604	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5605	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5606
5607	validate_status_stopped(status, sigval);
5608
5609	DPRINTF("Before resuming the child process where it left off and "
5610	    "without signal to be sent\n");
5611	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5612
5613	DPRINTF("Before calling %s() for the child - expected stopped "
5614	    "SIGTRAP\n", TWAIT_FNAME);
5615	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5616
5617	validate_status_stopped(status, SIGTRAP);
5618
5619	DPRINTF("Before reading siginfo and lwpid_t\n");
5620	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
5621
5622	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
5623	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
5624
5625        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
5626	    child, getpid());
5627	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
5628
5629	DPRINTF("Before resuming the child process where it left off and "
5630	    "without signal to be sent\n");
5631	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5632
5633	DPRINTF("Before calling %s() for the child - expected stopped "
5634	    "SIGINT\n", TWAIT_FNAME);
5635	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5636
5637	validate_status_stopped(status, SIGINT);
5638
5639	pl.pl_lwpid = 0;
5640
5641	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5642	while (pl.pl_lwpid != 0) {
5643
5644		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5645		switch (pl.pl_lwpid) {
5646		case 1:
5647			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
5648			break;
5649		case 2:
5650			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
5651			break;
5652		}
5653	}
5654
5655	DPRINTF("Before resuming the child process where it left off and "
5656	    "without signal to be sent\n");
5657	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5658
5659	DPRINTF("Before calling %s() for the child - expected exited\n",
5660	    TWAIT_FNAME);
5661	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5662
5663	validate_status_exited(status, exitval);
5664
5665	DPRINTF("Before calling %s() for the child - expected no process\n",
5666	    TWAIT_FNAME);
5667	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5668}
5669
5670ATF_TC(suspend2);
5671ATF_TC_HEAD(suspend2, tc)
5672{
5673	atf_tc_set_md_var(tc, "descr",
5674	    "Verify that the while the only thread within a process is "
5675	    "suspended, the whole process cannot be unstopped");
5676}
5677
5678ATF_TC_BODY(suspend2, tc)
5679{
5680	const int exitval = 5;
5681	const int sigval = SIGSTOP;
5682	pid_t child, wpid;
5683#if defined(TWAIT_HAVE_STATUS)
5684	int status;
5685#endif
5686	struct ptrace_siginfo psi;
5687
5688	// Feature pending for refactoring
5689	atf_tc_expect_fail("PR kern/51995");
5690
5691	// Hangs with qemu
5692	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5693
5694	DPRINTF("Before forking process PID=%d\n", getpid());
5695	SYSCALL_REQUIRE((child = fork()) != -1);
5696	if (child == 0) {
5697		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5698		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5699
5700		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5701		FORKEE_ASSERT(raise(sigval) == 0);
5702
5703		DPRINTF("Before exiting of the child process\n");
5704		_exit(exitval);
5705	}
5706	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5707
5708	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5709	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5710
5711	validate_status_stopped(status, sigval);
5712
5713	DPRINTF("Before reading siginfo and lwpid_t\n");
5714	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
5715
5716	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
5717	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
5718
5719	DPRINTF("Before resuming the child process where it left off and "
5720	    "without signal to be sent\n");
5721	ATF_REQUIRE_ERRNO(EDEADLK,
5722	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
5723
5724	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
5725	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
5726
5727	DPRINTF("Before resuming the child process where it left off and "
5728	    "without signal to be sent\n");
5729	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5730
5731	DPRINTF("Before calling %s() for the child - expected exited\n",
5732	    TWAIT_FNAME);
5733	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5734
5735	validate_status_exited(status, exitval);
5736
5737	DPRINTF("Before calling %s() for the child - expected no process\n",
5738	    TWAIT_FNAME);
5739	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5740}
5741
5742ATF_TC(resume1);
5743ATF_TC_HEAD(resume1, tc)
5744{
5745	atf_tc_set_md_var(tc, "timeout", "5");
5746	atf_tc_set_md_var(tc, "descr",
5747	    "Verify that a thread can be suspended by a debugger and later "
5748	    "resumed by the debugger");
5749}
5750
5751ATF_TC_BODY(resume1, tc)
5752{
5753	struct msg_fds fds;
5754	const int exitval = 5;
5755	const int sigval = SIGSTOP;
5756	pid_t child, wpid;
5757	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5758#if defined(TWAIT_HAVE_STATUS)
5759	int status;
5760#endif
5761	ucontext_t uc;
5762	lwpid_t lid;
5763	static const size_t ssize = 16*1024;
5764	void *stack;
5765	struct ptrace_lwpinfo pl;
5766	struct ptrace_siginfo psi;
5767
5768	// Feature pending for refactoring
5769	atf_tc_expect_fail("PR kern/51995");
5770
5771	// Hangs with qemu
5772	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5773
5774	SYSCALL_REQUIRE(msg_open(&fds) == 0);
5775
5776	DPRINTF("Before forking process PID=%d\n", getpid());
5777	SYSCALL_REQUIRE((child = fork()) != -1);
5778	if (child == 0) {
5779		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5780		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5781
5782		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5783		FORKEE_ASSERT(raise(sigval) == 0);
5784
5785		DPRINTF("Before allocating memory for stack in child\n");
5786		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5787
5788		DPRINTF("Before making context for new lwp in child\n");
5789		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
5790
5791		DPRINTF("Before creating new in child\n");
5792		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5793
5794		CHILD_TO_PARENT("Message", fds, msg);
5795
5796		raise(SIGINT);
5797
5798		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5799		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5800
5801		DPRINTF("Before verifying that reported %d and running lid %d "
5802		    "are the same\n", lid, the_lwp_id);
5803		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5804
5805		DPRINTF("Before exiting of the child process\n");
5806		_exit(exitval);
5807	}
5808	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5809
5810	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5811	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5812
5813	validate_status_stopped(status, sigval);
5814
5815	DPRINTF("Before resuming the child process where it left off and "
5816	    "without signal to be sent\n");
5817	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5818
5819	DPRINTF("Before calling %s() for the child - expected stopped "
5820	    "SIGTRAP\n", TWAIT_FNAME);
5821	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5822
5823	validate_status_stopped(status, SIGTRAP);
5824
5825	DPRINTF("Before reading siginfo and lwpid_t\n");
5826	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
5827
5828	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
5829	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
5830
5831	PARENT_FROM_CHILD("Message", fds, msg);
5832
5833	DPRINTF("Before resuming the child process where it left off and "
5834	    "without signal to be sent\n");
5835	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5836
5837	DPRINTF("Before calling %s() for the child - expected stopped "
5838	    "SIGINT\n", TWAIT_FNAME);
5839	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5840
5841	validate_status_stopped(status, SIGINT);
5842
5843	pl.pl_lwpid = 0;
5844
5845	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5846	while (pl.pl_lwpid != 0) {
5847		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
5848		switch (pl.pl_lwpid) {
5849		case 1:
5850			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
5851			break;
5852		case 2:
5853			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
5854			break;
5855		}
5856	}
5857
5858	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
5859	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
5860
5861	DPRINTF("Before resuming the child process where it left off and "
5862	    "without signal to be sent\n");
5863	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5864
5865	DPRINTF("Before calling %s() for the child - expected exited\n",
5866	    TWAIT_FNAME);
5867	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5868
5869	validate_status_exited(status, exitval);
5870
5871	DPRINTF("Before calling %s() for the child - expected no process\n",
5872	    TWAIT_FNAME);
5873	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5874
5875	msg_close(&fds);
5876
5877	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
5878	sleep(10);
5879}
5880
5881ATF_TC(syscall1);
5882ATF_TC_HEAD(syscall1, tc)
5883{
5884	atf_tc_set_md_var(tc, "descr",
5885	    "Verify that getpid(2) can be traced with PT_SYSCALL");
5886}
5887
5888ATF_TC_BODY(syscall1, tc)
5889{
5890	const int exitval = 5;
5891	const int sigval = SIGSTOP;
5892	pid_t child, wpid;
5893#if defined(TWAIT_HAVE_STATUS)
5894	int status;
5895#endif
5896	struct ptrace_siginfo info;
5897	memset(&info, 0, sizeof(info));
5898
5899	DPRINTF("Before forking process PID=%d\n", getpid());
5900	SYSCALL_REQUIRE((child = fork()) != -1);
5901	if (child == 0) {
5902		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5903		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5904
5905		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5906		FORKEE_ASSERT(raise(sigval) == 0);
5907
5908		syscall(SYS_getpid);
5909
5910		DPRINTF("Before exiting of the child process\n");
5911		_exit(exitval);
5912	}
5913	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5914
5915	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5916	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5917
5918	validate_status_stopped(status, sigval);
5919
5920	DPRINTF("Before resuming the child process where it left off and "
5921	    "without signal to be sent\n");
5922	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
5923
5924	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5925	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5926
5927	validate_status_stopped(status, SIGTRAP);
5928
5929	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5930	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5931
5932	DPRINTF("Before checking siginfo_t and lwpid\n");
5933	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
5934	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5935	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
5936
5937	DPRINTF("Before resuming the child process where it left off and "
5938	    "without signal to be sent\n");
5939	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
5940
5941	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5942	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5943
5944	validate_status_stopped(status, SIGTRAP);
5945
5946	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5947	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5948
5949	DPRINTF("Before checking siginfo_t and lwpid\n");
5950	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
5951	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5952	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
5953
5954	DPRINTF("Before resuming the child process where it left off and "
5955	    "without signal to be sent\n");
5956	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5957
5958	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5959	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5960
5961	validate_status_exited(status, exitval);
5962
5963	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5964	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5965}
5966
5967ATF_TC(syscallemu1);
5968ATF_TC_HEAD(syscallemu1, tc)
5969{
5970	atf_tc_set_md_var(tc, "descr",
5971	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
5972}
5973
5974ATF_TC_BODY(syscallemu1, tc)
5975{
5976	const int exitval = 5;
5977	const int sigval = SIGSTOP;
5978	pid_t child, wpid;
5979#if defined(TWAIT_HAVE_STATUS)
5980	int status;
5981#endif
5982
5983#if defined(__sparc__) && !defined(__sparc64__)
5984	/* syscallemu does not work on sparc (32-bit) */
5985	atf_tc_expect_fail("PR kern/52166");
5986#endif
5987
5988	DPRINTF("Before forking process PID=%d\n", getpid());
5989	SYSCALL_REQUIRE((child = fork()) != -1);
5990	if (child == 0) {
5991		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5992		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5993
5994		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5995		FORKEE_ASSERT(raise(sigval) == 0);
5996
5997		syscall(SYS_exit, 100);
5998
5999		DPRINTF("Before exiting of the child process\n");
6000		_exit(exitval);
6001	}
6002	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6003
6004	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6005	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6006
6007	validate_status_stopped(status, sigval);
6008
6009	DPRINTF("Before resuming the child process where it left off and "
6010	    "without signal to be sent\n");
6011	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6012
6013	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6014	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6015
6016	validate_status_stopped(status, SIGTRAP);
6017
6018	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
6019	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
6020
6021	DPRINTF("Before resuming the child process where it left off and "
6022	    "without signal to be sent\n");
6023	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6024
6025	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6026	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6027
6028	validate_status_stopped(status, SIGTRAP);
6029
6030	DPRINTF("Before resuming the child process where it left off and "
6031	    "without signal to be sent\n");
6032	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6033
6034	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6035	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6036
6037	validate_status_exited(status, exitval);
6038
6039	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6040	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6041}
6042
6043#include "t_ptrace_amd64_wait.h"
6044#include "t_ptrace_i386_wait.h"
6045#include "t_ptrace_x86_wait.h"
6046
6047ATF_TP_ADD_TCS(tp)
6048{
6049	setvbuf(stdout, NULL, _IONBF, 0);
6050	setvbuf(stderr, NULL, _IONBF, 0);
6051
6052	ATF_TP_ADD_TC(tp, traceme_raise1);
6053	ATF_TP_ADD_TC(tp, traceme_raise2);
6054	ATF_TP_ADD_TC(tp, traceme_raise3);
6055	ATF_TP_ADD_TC(tp, traceme_raise4);
6056	ATF_TP_ADD_TC(tp, traceme_raise5);
6057	ATF_TP_ADD_TC(tp, traceme_raise6);
6058	ATF_TP_ADD_TC(tp, traceme_raise7);
6059	ATF_TP_ADD_TC(tp, traceme_raise8);
6060	ATF_TP_ADD_TC(tp, traceme_raise9);
6061	ATF_TP_ADD_TC(tp, traceme_raise10);
6062
6063	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1);
6064	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2);
6065	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3);
6066	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4);
6067	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5);
6068	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6);
6069	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7);
6070	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8);
6071
6072	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1);
6073	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2);
6074	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3);
6075	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4);
6076	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5);
6077	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6);
6078	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7);
6079	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8);
6080
6081	ATF_TP_ADD_TC(tp, traceme_crash_trap);
6082	ATF_TP_ADD_TC(tp, traceme_crash_segv);
6083	ATF_TP_ADD_TC(tp, traceme_crash_ill);
6084	ATF_TP_ADD_TC(tp, traceme_crash_fpe);
6085	ATF_TP_ADD_TC(tp, traceme_crash_bus);
6086
6087	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap);
6088	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv);
6089	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill);
6090	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe);
6091	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus);
6092
6093	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap);
6094	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv);
6095	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill);
6096	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe);
6097	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus);
6098
6099	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1);
6100	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2);
6101	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3);
6102	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4);
6103	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5);
6104	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6);
6105	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7);
6106	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8);
6107
6108	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1);
6109	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2);
6110	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3);
6111	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4);
6112	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5);
6113	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6);
6114	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7);
6115	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8);
6116
6117	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1);
6118	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2);
6119	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3);
6120	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4);
6121	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5);
6122	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6);
6123	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7);
6124	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8);
6125
6126	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1);
6127	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2);
6128	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3);
6129	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4);
6130	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5);
6131	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6);
6132	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7);
6133	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8);
6134	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9);
6135	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10);
6136
6137	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
6138
6139	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
6140	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
6141	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
6142	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
6143	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
6144	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
6145	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
6146	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
6147	ATF_TP_ADD_TC(tp, traceme_vfork_raise9);
6148	ATF_TP_ADD_TC(tp, traceme_vfork_raise10);
6149	ATF_TP_ADD_TC(tp, traceme_vfork_raise11);
6150	ATF_TP_ADD_TC(tp, traceme_vfork_raise12);
6151	ATF_TP_ADD_TC(tp, traceme_vfork_raise13);
6152
6153	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap);
6154	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv);
6155	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill);
6156	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe);
6157	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus);
6158
6159	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap);
6160	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv);
6161	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill);
6162	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe);
6163	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus);
6164
6165	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap);
6166	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv);
6167	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill);
6168	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe);
6169	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus);
6170
6171	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
6172
6173	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap);
6174	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv);
6175	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill);
6176	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe);
6177	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus);
6178
6179	ATF_TP_ADD_TC_HAVE_PID(tp,
6180	    unrelated_tracer_sees_signalmasked_crash_trap);
6181	ATF_TP_ADD_TC_HAVE_PID(tp,
6182	    unrelated_tracer_sees_signalmasked_crash_segv);
6183	ATF_TP_ADD_TC_HAVE_PID(tp,
6184	    unrelated_tracer_sees_signalmasked_crash_ill);
6185	ATF_TP_ADD_TC_HAVE_PID(tp,
6186	    unrelated_tracer_sees_signalmasked_crash_fpe);
6187	ATF_TP_ADD_TC_HAVE_PID(tp,
6188	    unrelated_tracer_sees_signalmasked_crash_bus);
6189
6190	ATF_TP_ADD_TC_HAVE_PID(tp,
6191	    unrelated_tracer_sees_signalignored_crash_trap);
6192	ATF_TP_ADD_TC_HAVE_PID(tp,
6193	    unrelated_tracer_sees_signalignored_crash_segv);
6194	ATF_TP_ADD_TC_HAVE_PID(tp,
6195	    unrelated_tracer_sees_signalignored_crash_ill);
6196	ATF_TP_ADD_TC_HAVE_PID(tp,
6197	    unrelated_tracer_sees_signalignored_crash_fpe);
6198	ATF_TP_ADD_TC_HAVE_PID(tp,
6199	    unrelated_tracer_sees_signalignored_crash_bus);
6200
6201	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
6202	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
6203	ATF_TP_ADD_TC_HAVE_PID(tp,
6204		unrelated_tracer_sees_terminaton_before_the_parent);
6205	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
6206
6207	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
6208	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
6209
6210	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
6211	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
6212
6213	ATF_TP_ADD_TC_HAVE_PID(tp,
6214		tracee_sees_its_original_parent_getppid);
6215	ATF_TP_ADD_TC_HAVE_PID(tp,
6216		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
6217	ATF_TP_ADD_TC_HAVE_PID(tp,
6218		tracee_sees_its_original_parent_procfs_status);
6219
6220	ATF_TP_ADD_TC(tp, eventmask_preserved_empty);
6221	ATF_TP_ADD_TC(tp, eventmask_preserved_fork);
6222	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork);
6223	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done);
6224	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create);
6225	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit);
6226
6227	ATF_TP_ADD_TC(tp, fork1);
6228	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
6229	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
6230	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
6231	ATF_TP_ADD_TC(tp, fork5);
6232	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
6233	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
6234	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
6235
6236	ATF_TP_ADD_TC(tp, vfork1);
6237	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
6238	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
6239	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
6240	ATF_TP_ADD_TC(tp, vfork5);
6241	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
6242// thes tests hang on SMP machines, disable them for now
6243//	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
6244//	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
6245
6246	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8);
6247	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16);
6248	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32);
6249	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64);
6250
6251	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8);
6252	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16);
6253	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32);
6254	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64);
6255
6256	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8);
6257	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16);
6258	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32);
6259	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64);
6260
6261	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8);
6262	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16);
6263	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32);
6264	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64);
6265
6266	ATF_TP_ADD_TC(tp, bytes_transfer_read_d);
6267	ATF_TP_ADD_TC(tp, bytes_transfer_read_i);
6268	ATF_TP_ADD_TC(tp, bytes_transfer_write_d);
6269	ATF_TP_ADD_TC(tp, bytes_transfer_write_i);
6270
6271	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text);
6272	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text);
6273	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text);
6274	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text);
6275
6276	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text);
6277	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text);
6278	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text);
6279	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text);
6280
6281	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text);
6282	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text);
6283	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text);
6284	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text);
6285
6286	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text);
6287	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text);
6288	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text);
6289	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text);
6290
6291	ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text);
6292	ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text);
6293	ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text);
6294	ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text);
6295
6296	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv);
6297
6298	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1);
6299	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2);
6300	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3);
6301	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4);
6302	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5);
6303	ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6);
6304
6305	ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1);
6306	ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2);
6307
6308	ATF_TP_ADD_TC_PT_STEP(tp, step1);
6309	ATF_TP_ADD_TC_PT_STEP(tp, step2);
6310	ATF_TP_ADD_TC_PT_STEP(tp, step3);
6311	ATF_TP_ADD_TC_PT_STEP(tp, step4);
6312
6313	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
6314	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
6315	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
6316	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
6317
6318	ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked);
6319	ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored);
6320
6321	ATF_TP_ADD_TC(tp, kill1);
6322	ATF_TP_ADD_TC(tp, kill2);
6323	ATF_TP_ADD_TC(tp, kill3);
6324
6325	ATF_TP_ADD_TC(tp, traceme_lwpinfo0);
6326	ATF_TP_ADD_TC(tp, traceme_lwpinfo1);
6327	ATF_TP_ADD_TC(tp, traceme_lwpinfo2);
6328	ATF_TP_ADD_TC(tp, traceme_lwpinfo3);
6329
6330	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0);
6331	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1);
6332	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2);
6333	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3);
6334
6335	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
6336	ATF_TP_ADD_TC(tp, siginfo_set_faked);
6337
6338	ATF_TP_ADD_TC(tp, traceme_exec);
6339
6340	ATF_TP_ADD_TC(tp, trace_thread1);
6341	ATF_TP_ADD_TC(tp, trace_thread2);
6342	ATF_TP_ADD_TC(tp, trace_thread3);
6343	ATF_TP_ADD_TC(tp, trace_thread4);
6344
6345	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
6346
6347	ATF_TP_ADD_TC(tp, signal5);
6348	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
6349	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
6350	ATF_TP_ADD_TC(tp, signal8);
6351	ATF_TP_ADD_TC(tp, signal9);
6352	ATF_TP_ADD_TC(tp, signal10);
6353
6354	ATF_TP_ADD_TC(tp, suspend1);
6355	ATF_TP_ADD_TC(tp, suspend2);
6356
6357	ATF_TP_ADD_TC(tp, resume1);
6358
6359	ATF_TP_ADD_TC(tp, syscall1);
6360
6361	ATF_TP_ADD_TC(tp, syscallemu1);
6362
6363	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
6364	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
6365	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
6366
6367	return atf_no_error();
6368}
6369