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