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