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