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