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