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