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