xref: /netbsd-src/tests/lib/libc/sys/t_ptrace_signal_wait.h (revision 7f74343bad119fe26eb9b38bcfb9ab4c67fa31b2)
1 /*	$NetBSD: t_ptrace_signal_wait.h,v 1.5 2021/03/19 00:44:09 simonb Exp $	*/
2 
3 /*-
4  * Copyright (c) 2016, 2017, 2018, 2019, 2020 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 
30 static void
traceme_raise(int sigval)31 traceme_raise(int sigval)
32 {
33 	const int exitval = 5;
34 	pid_t child, wpid;
35 #if defined(TWAIT_HAVE_STATUS)
36 	int status;
37 #endif
38 
39 	ptrace_state_t state, zero_state;
40 	const int slen = sizeof(state);
41 	struct ptrace_siginfo info;
42 	memset(&zero_state, 0, sizeof(zero_state));
43 	memset(&info, 0, sizeof(info));
44 
45 	DPRINTF("Before forking process PID=%d\n", getpid());
46 	SYSCALL_REQUIRE((child = fork()) != -1);
47 	if (child == 0) {
48 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50 
51 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52 		FORKEE_ASSERT(raise(sigval) == 0);
53 
54 		switch (sigval) {
55 		case SIGKILL:
56 			/* NOTREACHED */
57 			FORKEE_ASSERTX(0 && "This shall not be reached");
58 			__unreachable();
59 		default:
60 			DPRINTF("Before exiting of the child process\n");
61 			_exit(exitval);
62 		}
63 	}
64 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65 
66 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68 
69 	switch (sigval) {
70 	case SIGKILL:
71 		validate_status_signaled(status, sigval, 0);
72 		SYSCALL_REQUIRE(
73 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) == -1);
74 
75 		break;
76 	default:
77 		validate_status_stopped(status, sigval);
78 
79 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
80 			"child\n");
81 		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
82 			sizeof(info)) != -1);
83 
84 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
85 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
86 			"si_errno=%#x\n",
87 			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
88 			info.psi_siginfo.si_errno);
89 
90 		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
91 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
92 
93 		DPRINTF("Assert that PT_GET_PROCESS_STATE returns non-error\n");
94 		SYSCALL_REQUIRE(
95 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
96 		ATF_REQUIRE(memcmp(&state, &zero_state, slen) == 0);
97 
98 		DPRINTF("Before resuming the child process where it left off "
99 		    "and without signal to be sent\n");
100 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
101 
102 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
103 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
104 		    child);
105 		break;
106 	}
107 
108 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
109 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
110 }
111 
112 #define TRACEME_RAISE(test, sig)					\
113 ATF_TC(test);								\
114 ATF_TC_HEAD(test, tc)							\
115 {									\
116 	atf_tc_set_md_var(tc, "descr",					\
117 	    "Verify " #sig " followed by _exit(2) in a child");		\
118 }									\
119 									\
120 ATF_TC_BODY(test, tc)							\
121 {									\
122 									\
123 	traceme_raise(sig);						\
124 }
125 
TRACEME_RAISE(traceme_raise1,SIGKILL)126 TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
127 TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
128 TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
129 TRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
130 TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
131 TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */
132 TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */
133 TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */
134 TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */
135 TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */
136 
137 /// ----------------------------------------------------------------------------
138 
139 static void
140 traceme_raisesignal_ignored(int sigignored)
141 {
142 	const int exitval = 5;
143 	const int sigval = SIGSTOP;
144 	pid_t child, wpid;
145 	struct sigaction sa;
146 #if defined(TWAIT_HAVE_STATUS)
147 	int status;
148 #endif
149 	struct ptrace_siginfo info;
150 
151 	memset(&info, 0, sizeof(info));
152 
153 	DPRINTF("Before forking process PID=%d\n", getpid());
154 	SYSCALL_REQUIRE((child = fork()) != -1);
155 	if (child == 0) {
156 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
157 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
158 
159 		memset(&sa, 0, sizeof(sa));
160 		sa.sa_handler = SIG_IGN;
161 		sigemptyset(&sa.sa_mask);
162 		FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1);
163 
164 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
165 		FORKEE_ASSERT(raise(sigval) == 0);
166 
167 		DPRINTF("Before raising %s from child\n",
168 		    strsignal(sigignored));
169 		FORKEE_ASSERT(raise(sigignored) == 0);
170 
171 		DPRINTF("Before exiting of the child process\n");
172 		_exit(exitval);
173 	}
174 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
175 
176 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
177 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
178 
179 	validate_status_stopped(status, sigval);
180 
181 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
182 	SYSCALL_REQUIRE(
183 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
184 
185 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
186 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
187 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
188 	    info.psi_siginfo.si_errno);
189 
190 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
191 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
192 
193 	DPRINTF("Before resuming the child process where it left off and "
194 	    "without signal to be sent\n");
195 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
196 
197 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
198 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
199 
200 	validate_status_stopped(status, sigignored);
201 
202 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
203 	SYSCALL_REQUIRE(
204 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
205 
206 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
207 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
208 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
209 	    info.psi_siginfo.si_errno);
210 
211 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored);
212 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
213 
214 	DPRINTF("Before resuming the child process where it left off and "
215 	    "without signal to be sent\n");
216 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
217 
218 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
219 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
220 
221 	validate_status_exited(status, exitval);
222 
223 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
224 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
225 }
226 
227 #define TRACEME_RAISESIGNAL_IGNORED(test, sig)				\
228 ATF_TC(test);								\
229 ATF_TC_HEAD(test, tc)							\
230 {									\
231 	atf_tc_set_md_var(tc, "descr",					\
232 	    "Verify that ignoring (with SIG_IGN) " #sig " in tracee "	\
233 	    "does not stop tracer from catching this raised signal");	\
234 }									\
235 									\
236 ATF_TC_BODY(test, tc)							\
237 {									\
238 									\
239 	traceme_raisesignal_ignored(sig);				\
240 }
241 
242 // A signal handler for SIGKILL and SIGSTOP cannot be ignored.
TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1,SIGABRT)243 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */
244 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP)  /* hangup */
245 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */
246 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */
247 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */
248 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */
249 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */
250 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */
251 
252 /// ----------------------------------------------------------------------------
253 
254 static void
255 traceme_raisesignal_masked(int sigmasked)
256 {
257 	const int exitval = 5;
258 	const int sigval = SIGSTOP;
259 	pid_t child, wpid;
260 #if defined(TWAIT_HAVE_STATUS)
261 	int status;
262 #endif
263 	sigset_t intmask;
264 	struct ptrace_siginfo info;
265 
266 	memset(&info, 0, sizeof(info));
267 
268 	DPRINTF("Before forking process PID=%d\n", getpid());
269 	SYSCALL_REQUIRE((child = fork()) != -1);
270 	if (child == 0) {
271 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
272 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
273 
274 		sigemptyset(&intmask);
275 		sigaddset(&intmask, sigmasked);
276 		sigprocmask(SIG_BLOCK, &intmask, NULL);
277 
278 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
279 		FORKEE_ASSERT(raise(sigval) == 0);
280 
281 		DPRINTF("Before raising %s breakpoint from child\n",
282 		    strsignal(sigmasked));
283 		FORKEE_ASSERT(raise(sigmasked) == 0);
284 
285 		DPRINTF("Before exiting of the child process\n");
286 		_exit(exitval);
287 	}
288 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
289 
290 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
291 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
292 
293 	validate_status_stopped(status, sigval);
294 
295 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
296 	SYSCALL_REQUIRE(
297 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
298 
299 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
300 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
301 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
302 	    info.psi_siginfo.si_errno);
303 
304 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
305 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
306 
307 	DPRINTF("Before resuming the child process where it left off and "
308 	    "without signal to be sent\n");
309 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
310 
311 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
312 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
313 
314 	validate_status_exited(status, exitval);
315 
316 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
317 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
318 }
319 
320 #define TRACEME_RAISESIGNAL_MASKED(test, sig)				\
321 ATF_TC(test);								\
322 ATF_TC_HEAD(test, tc)							\
323 {									\
324 	atf_tc_set_md_var(tc, "descr",					\
325 	    "Verify that masking (with SIG_BLOCK) " #sig " in tracee "	\
326 	    "stops tracer from catching this raised signal");		\
327 }									\
328 									\
329 ATF_TC_BODY(test, tc)							\
330 {									\
331 									\
332 	traceme_raisesignal_masked(sig);				\
333 }
334 
335 // A signal handler for SIGKILL and SIGSTOP cannot be masked.
TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1,SIGABRT)336 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */
337 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP)  /* hangup */
338 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */
339 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */
340 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */
341 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */
342 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */
343 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */
344 
345 /// ----------------------------------------------------------------------------
346 
347 static void
348 traceme_crash(int sig)
349 {
350 	pid_t child, wpid;
351 #if defined(TWAIT_HAVE_STATUS)
352 	int status;
353 #endif
354 	struct ptrace_siginfo info;
355 
356 #ifndef PTRACE_ILLEGAL_ASM
357 	if (sig == SIGILL)
358 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
359 #endif
360 
361 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
362 		atf_tc_skip("FP exceptions are not supported");
363 
364 	memset(&info, 0, sizeof(info));
365 
366 	DPRINTF("Before forking process PID=%d\n", getpid());
367 	SYSCALL_REQUIRE((child = fork()) != -1);
368 	if (child == 0) {
369 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
370 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
371 
372 		DPRINTF("Before executing a trap\n");
373 		switch (sig) {
374 		case SIGTRAP:
375 			trigger_trap();
376 			break;
377 		case SIGSEGV:
378 			trigger_segv();
379 			break;
380 		case SIGILL:
381 			trigger_ill();
382 			break;
383 		case SIGFPE:
384 			trigger_fpe();
385 			break;
386 		case SIGBUS:
387 			trigger_bus();
388 			break;
389 		default:
390 			/* NOTREACHED */
391 			FORKEE_ASSERTX(0 && "This shall not be reached");
392 		}
393 
394 		/* NOTREACHED */
395 		FORKEE_ASSERTX(0 && "This shall not be reached");
396 	}
397 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
398 
399 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
400 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
401 
402 	validate_status_stopped(status, sig);
403 
404 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
405 	SYSCALL_REQUIRE(
406 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
407 
408 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
409 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
410 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
411 	    info.psi_siginfo.si_errno);
412 
413 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
414 	switch (sig) {
415 	case SIGTRAP:
416 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
417 		break;
418 	case SIGSEGV:
419 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
420 		break;
421 	case SIGILL:
422 		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
423 		            info.psi_siginfo.si_code <= ILL_BADSTK);
424 		break;
425 	case SIGFPE:
426 // XXXQEMU	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
427 		break;
428 	case SIGBUS:
429 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
430 		break;
431 	}
432 
433 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
434 
435 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
436 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
437 
438 	validate_status_signaled(status, SIGKILL, 0);
439 
440 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
441 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
442 }
443 
444 #define TRACEME_CRASH(test, sig)					\
445 ATF_TC(test);								\
446 ATF_TC_HEAD(test, tc)							\
447 {									\
448 	atf_tc_set_md_var(tc, "descr",					\
449 	    "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \
450 }									\
451 									\
452 ATF_TC_BODY(test, tc)							\
453 {									\
454 									\
455 	traceme_crash(sig);						\
456 }
457 
TRACEME_CRASH(traceme_crash_trap,SIGTRAP)458 TRACEME_CRASH(traceme_crash_trap, SIGTRAP)
459 TRACEME_CRASH(traceme_crash_segv, SIGSEGV)
460 TRACEME_CRASH(traceme_crash_ill, SIGILL)
461 TRACEME_CRASH(traceme_crash_fpe, SIGFPE)
462 TRACEME_CRASH(traceme_crash_bus, SIGBUS)
463 
464 /// ----------------------------------------------------------------------------
465 
466 static void
467 traceme_signalmasked_crash(int sig)
468 {
469 	const int sigval = SIGSTOP;
470 	pid_t child, wpid;
471 #if defined(TWAIT_HAVE_STATUS)
472 	int status;
473 #endif
474 	struct ptrace_siginfo info;
475 	sigset_t intmask;
476 	struct kinfo_proc2 kp;
477 	size_t len = sizeof(kp);
478 
479 	int name[6];
480 	const size_t namelen = __arraycount(name);
481 	ki_sigset_t kp_sigmask;
482 
483 #ifndef PTRACE_ILLEGAL_ASM
484 	if (sig == SIGILL)
485 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
486 #endif
487 
488 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
489 		atf_tc_skip("FP exceptions are not supported");
490 
491 	memset(&info, 0, sizeof(info));
492 
493 	DPRINTF("Before forking process PID=%d\n", getpid());
494 	SYSCALL_REQUIRE((child = fork()) != -1);
495 	if (child == 0) {
496 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
497 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
498 
499 		sigemptyset(&intmask);
500 		sigaddset(&intmask, sig);
501 		sigprocmask(SIG_BLOCK, &intmask, NULL);
502 
503 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
504 		FORKEE_ASSERT(raise(sigval) == 0);
505 
506 		DPRINTF("Before executing a trap\n");
507 		switch (sig) {
508 		case SIGTRAP:
509 			trigger_trap();
510 			break;
511 		case SIGSEGV:
512 			trigger_segv();
513 			break;
514 		case SIGILL:
515 			trigger_ill();
516 			break;
517 		case SIGFPE:
518 			trigger_fpe();
519 			break;
520 		case SIGBUS:
521 			trigger_bus();
522 			break;
523 		default:
524 			/* NOTREACHED */
525 			FORKEE_ASSERTX(0 && "This shall not be reached");
526 		}
527 
528 		/* NOTREACHED */
529 		FORKEE_ASSERTX(0 && "This shall not be reached");
530 	}
531 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
532 
533 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
534 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
535 
536 	validate_status_stopped(status, sigval);
537 
538 	name[0] = CTL_KERN,
539 	name[1] = KERN_PROC2,
540 	name[2] = KERN_PROC_PID;
541 	name[3] = child;
542 	name[4] = sizeof(kp);
543 	name[5] = 1;
544 
545 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
546 
547 	kp_sigmask = kp.p_sigmask;
548 
549 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
550 	SYSCALL_REQUIRE(
551 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
552 
553 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
554 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
555 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
556 	    info.psi_siginfo.si_errno);
557 
558 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
559 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
560 
561 	DPRINTF("Before resuming the child process where it left off and "
562 	    "without signal to be sent\n");
563 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
564 
565 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
566 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
567 
568 	validate_status_stopped(status, sig);
569 
570 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
571 	SYSCALL_REQUIRE(
572 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
573 
574 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
575 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
576 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
577 	    info.psi_siginfo.si_errno);
578 
579 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
580 
581 	DPRINTF("kp_sigmask="
582 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
583 	    kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2],
584 	    kp_sigmask.__bits[3]);
585 
586 	DPRINTF("kp.p_sigmask="
587 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
588 	    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
589 	    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
590 
591 	ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask)));
592 
593 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
594 	switch (sig) {
595 	case SIGTRAP:
596 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
597 		break;
598 	case SIGSEGV:
599 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
600 		break;
601 	case SIGILL:
602 		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
603 		            info.psi_siginfo.si_code <= ILL_BADSTK);
604 		break;
605 	case SIGFPE:
606 // XXXQEMU	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
607 		break;
608 	case SIGBUS:
609 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
610 		break;
611 	}
612 
613 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
614 
615 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
616 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
617 
618 	validate_status_signaled(status, SIGKILL, 0);
619 
620 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
621 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
622 }
623 
624 #define TRACEME_SIGNALMASKED_CRASH(test, sig)				\
625 ATF_TC(test);								\
626 ATF_TC_HEAD(test, tc)							\
627 {									\
628 	atf_tc_set_md_var(tc, "descr",					\
629 	    "Verify masked crash signal " #sig " in a child after "	\
630 	    "PT_TRACE_ME is delivered to its tracer");			\
631 }									\
632 									\
633 ATF_TC_BODY(test, tc)							\
634 {									\
635 									\
636 	traceme_signalmasked_crash(sig);				\
637 }
638 
TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap,SIGTRAP)639 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP)
640 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV)
641 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL)
642 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE)
643 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS)
644 
645 /// ----------------------------------------------------------------------------
646 
647 static void
648 traceme_signalignored_crash(int sig)
649 {
650 	const int sigval = SIGSTOP;
651 	pid_t child, wpid;
652 #if defined(TWAIT_HAVE_STATUS)
653 	int status;
654 #endif
655 	struct sigaction sa;
656 	struct ptrace_siginfo info;
657 	struct kinfo_proc2 kp;
658 	size_t len = sizeof(kp);
659 
660 	int name[6];
661 	const size_t namelen = __arraycount(name);
662 	ki_sigset_t kp_sigignore;
663 
664 #ifndef PTRACE_ILLEGAL_ASM
665 	if (sig == SIGILL)
666 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
667 #endif
668 
669 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
670 		atf_tc_skip("FP exceptions are not supported");
671 
672 	memset(&info, 0, sizeof(info));
673 
674 	DPRINTF("Before forking process PID=%d\n", getpid());
675 	SYSCALL_REQUIRE((child = fork()) != -1);
676 	if (child == 0) {
677 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
678 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
679 
680 		memset(&sa, 0, sizeof(sa));
681 		sa.sa_handler = SIG_IGN;
682 		sigemptyset(&sa.sa_mask);
683 
684 		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
685 
686 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
687 		FORKEE_ASSERT(raise(sigval) == 0);
688 
689 		DPRINTF("Before executing a trap\n");
690 		switch (sig) {
691 		case SIGTRAP:
692 			trigger_trap();
693 			break;
694 		case SIGSEGV:
695 			trigger_segv();
696 			break;
697 		case SIGILL:
698 			trigger_ill();
699 			break;
700 		case SIGFPE:
701 			trigger_fpe();
702 			break;
703 		case SIGBUS:
704 			trigger_bus();
705 			break;
706 		default:
707 			/* NOTREACHED */
708 			FORKEE_ASSERTX(0 && "This shall not be reached");
709 		}
710 
711 		/* NOTREACHED */
712 		FORKEE_ASSERTX(0 && "This shall not be reached");
713 	}
714 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
715 
716 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
717 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
718 
719 	validate_status_stopped(status, sigval);
720 
721 	name[0] = CTL_KERN,
722 	name[1] = KERN_PROC2,
723 	name[2] = KERN_PROC_PID;
724 	name[3] = child;
725 	name[4] = sizeof(kp);
726 	name[5] = 1;
727 
728 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
729 
730 	kp_sigignore = kp.p_sigignore;
731 
732 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
733 	SYSCALL_REQUIRE(
734 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
735 
736 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
737 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
738 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
739 	    info.psi_siginfo.si_errno);
740 
741 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
742 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
743 
744 	DPRINTF("Before resuming the child process where it left off and "
745 	    "without signal to be sent\n");
746 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
747 
748 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
749 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
750 
751 	validate_status_stopped(status, sig);
752 
753 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
754 	SYSCALL_REQUIRE(
755 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
756 
757 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
758 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
759 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
760 	    info.psi_siginfo.si_errno);
761 
762 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
763 
764 	DPRINTF("kp_sigignore="
765 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
766 	    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
767 	    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
768 
769 	DPRINTF("kp.p_sigignore="
770 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
771 	    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
772 	    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
773 
774 	ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore)));
775 
776 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
777 	switch (sig) {
778 	case SIGTRAP:
779 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
780 		break;
781 	case SIGSEGV:
782 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
783 		break;
784 	case SIGILL:
785 		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
786 		            info.psi_siginfo.si_code <= ILL_BADSTK);
787 		break;
788 	case SIGFPE:
789 // XXXQEMU	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
790 		break;
791 	case SIGBUS:
792 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
793 		break;
794 	}
795 
796 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
797 
798 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
799 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
800 
801 	validate_status_signaled(status, SIGKILL, 0);
802 
803 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
804 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
805 }
806 
807 #define TRACEME_SIGNALIGNORED_CRASH(test, sig)				\
808 ATF_TC(test);								\
809 ATF_TC_HEAD(test, tc)							\
810 {									\
811 	atf_tc_set_md_var(tc, "descr",					\
812 	    "Verify ignored crash signal " #sig " in a child after "	\
813 	    "PT_TRACE_ME is delivered to its tracer"); 			\
814 }									\
815 									\
816 ATF_TC_BODY(test, tc)							\
817 {									\
818 									\
819 	traceme_signalignored_crash(sig);				\
820 }
821 
TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap,SIGTRAP)822 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP)
823 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV)
824 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL)
825 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE)
826 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS)
827 
828 /// ----------------------------------------------------------------------------
829 
830 static void
831 traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught)
832 {
833 	const int exitval = 5;
834 	const int sigval = SIGSTOP;
835 	pid_t child, wpid;
836 	struct sigaction sa;
837 #if defined(TWAIT_HAVE_STATUS)
838 	int status;
839 #endif
840 	struct ptrace_siginfo info;
841 
842 	memset(&info, 0, sizeof(info));
843 
844 	DPRINTF("Before forking process PID=%d\n", getpid());
845 	SYSCALL_REQUIRE((child = fork()) != -1);
846 	if (child == 0) {
847 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
848 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
849 
850 		sa.sa_handler = sah;
851 		sa.sa_flags = SA_SIGINFO;
852 		sigemptyset(&sa.sa_mask);
853 
854 		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
855 
856 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
857 		FORKEE_ASSERT(raise(sigval) == 0);
858 
859 		FORKEE_ASSERT_EQ(*traceme_caught, 1);
860 
861 		DPRINTF("Before exiting of the child process\n");
862 		_exit(exitval);
863 	}
864 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
865 
866 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
867 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
868 
869 	validate_status_stopped(status, sigval);
870 
871 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
872 	SYSCALL_REQUIRE(
873 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
874 
875 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
876 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x 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 and with "
884 	    "signal %s to be sent\n", strsignal(sigsent));
885 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
886 
887 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
888 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
889 
890 	validate_status_exited(status, exitval);
891 
892 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
893 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
894 }
895 
896 #define TRACEME_SENDSIGNAL_HANDLE(test, sig)				\
897 ATF_TC(test);								\
898 ATF_TC_HEAD(test, tc)							\
899 {									\
900 	atf_tc_set_md_var(tc, "descr",					\
901 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
902 	    "handled correctly and caught by a signal handler");	\
903 }									\
904 									\
905 static int test##_caught = 0;						\
906 									\
907 static void								\
908 test##_sighandler(int arg)						\
909 {									\
910 	FORKEE_ASSERT_EQ(arg, sig);					\
911 									\
912 	++ test##_caught;						\
913 }									\
914 									\
915 ATF_TC_BODY(test, tc)							\
916 {									\
917 									\
918 	traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \
919 }
920 
921 // A signal handler for SIGKILL and SIGSTOP cannot be registered.
TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1,SIGABRT)922 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */
923 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP)  /* hangup */
924 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */
925 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */
926 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */
927 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */
928 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */
929 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */
930 
931 /// ----------------------------------------------------------------------------
932 
933 static void
934 traceme_sendsignal_masked(int sigsent)
935 {
936 	const int exitval = 5;
937 	const int sigval = SIGSTOP;
938 	pid_t child, wpid;
939 	sigset_t set;
940 #if defined(TWAIT_HAVE_STATUS)
941 	int status;
942 #endif
943 	struct ptrace_siginfo info;
944 
945 	memset(&info, 0, sizeof(info));
946 
947 	DPRINTF("Before forking process PID=%d\n", getpid());
948 	SYSCALL_REQUIRE((child = fork()) != -1);
949 	if (child == 0) {
950 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
951 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
952 
953 		sigemptyset(&set);
954 		sigaddset(&set, sigsent);
955 		FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
956 
957 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
958 		FORKEE_ASSERT(raise(sigval) == 0);
959 
960 		_exit(exitval);
961 	}
962 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
963 
964 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
965 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
966 
967 	validate_status_stopped(status, sigval);
968 
969 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
970 	SYSCALL_REQUIRE(
971 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
972 
973 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
974 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
975 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
976 	    info.psi_siginfo.si_errno);
977 
978 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
979 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
980 
981 	DPRINTF("Before resuming the child process where it left off and with "
982 	    "signal %s to be sent\n", strsignal(sigsent));
983 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
984 
985 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
986 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
987 
988 	validate_status_exited(status, exitval);
989 
990 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
991 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
992 }
993 
994 #define TRACEME_SENDSIGNAL_MASKED(test, sig)				\
995 ATF_TC(test);								\
996 ATF_TC_HEAD(test, tc)							\
997 {									\
998 	atf_tc_set_md_var(tc, "descr",					\
999 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1000 	    "handled correctly and the signal is masked by SIG_BLOCK");	\
1001 }									\
1002 									\
1003 ATF_TC_BODY(test, tc)							\
1004 {									\
1005 									\
1006 	traceme_sendsignal_masked(sig);					\
1007 }
1008 
1009 // A signal handler for SIGKILL and SIGSTOP cannot be masked.
TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1,SIGABRT)1010 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */
1011 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP)  /* hangup */
1012 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */
1013 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */
1014 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */
1015 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */
1016 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */
1017 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */
1018 
1019 /// ----------------------------------------------------------------------------
1020 
1021 static void
1022 traceme_sendsignal_ignored(int sigsent)
1023 {
1024 	const int exitval = 5;
1025 	const int sigval = SIGSTOP;
1026 	pid_t child, wpid;
1027 	struct sigaction sa;
1028 #if defined(TWAIT_HAVE_STATUS)
1029 	int status;
1030 #endif
1031 	struct ptrace_siginfo info;
1032 
1033 	memset(&info, 0, sizeof(info));
1034 
1035 	DPRINTF("Before forking process PID=%d\n", getpid());
1036 	SYSCALL_REQUIRE((child = fork()) != -1);
1037 	if (child == 0) {
1038 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1039 
1040 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1041 
1042 		memset(&sa, 0, sizeof(sa));
1043 		sa.sa_handler = SIG_IGN;
1044 		sigemptyset(&sa.sa_mask);
1045 		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1046 
1047 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1048 		FORKEE_ASSERT(raise(sigval) == 0);
1049 
1050 		_exit(exitval);
1051 	}
1052 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1053 
1054 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1055 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1056 
1057 	validate_status_stopped(status, sigval);
1058 
1059 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1060 	SYSCALL_REQUIRE(
1061 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1062 
1063 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1064 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1065 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1066 	    info.psi_siginfo.si_errno);
1067 
1068 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1069 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1070 
1071 	DPRINTF("Before resuming the child process where it left off and with "
1072 	    "signal %s to be sent\n", strsignal(sigsent));
1073 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1074 
1075 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1076 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1077 
1078 	validate_status_exited(status, exitval);
1079 
1080 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1081 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1082 }
1083 
1084 #define TRACEME_SENDSIGNAL_IGNORED(test, sig)				\
1085 ATF_TC(test);								\
1086 ATF_TC_HEAD(test, tc)							\
1087 {									\
1088 	atf_tc_set_md_var(tc, "descr",					\
1089 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1090 	    "handled correctly and the signal is masked by SIG_IGN");	\
1091 }									\
1092 									\
1093 ATF_TC_BODY(test, tc)							\
1094 {									\
1095 									\
1096 	traceme_sendsignal_ignored(sig);				\
1097 }
1098 
1099 // A signal handler for SIGKILL and SIGSTOP cannot be ignored.
TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1,SIGABRT)1100 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */
1101 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP)  /* hangup */
1102 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */
1103 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */
1104 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */
1105 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */
1106 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */
1107 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */
1108 
1109 /// ----------------------------------------------------------------------------
1110 
1111 static void
1112 traceme_sendsignal_simple(int sigsent)
1113 {
1114 	const int sigval = SIGSTOP;
1115 	int exitval = 0;
1116 	pid_t child, wpid;
1117 #if defined(TWAIT_HAVE_STATUS)
1118 	int status;
1119 	int expect_core;
1120 
1121 	switch (sigsent) {
1122 	case SIGABRT:
1123 	case SIGTRAP:
1124 	case SIGBUS:
1125 	case SIGILL:
1126 	case SIGFPE:
1127 	case SIGSEGV:
1128 		expect_core = 1;
1129 		break;
1130 	default:
1131 		expect_core = 0;
1132 		break;
1133 	}
1134 #endif
1135 	struct ptrace_siginfo info;
1136 
1137 	memset(&info, 0, sizeof(info));
1138 
1139 	DPRINTF("Before forking process PID=%d\n", getpid());
1140 	SYSCALL_REQUIRE((child = fork()) != -1);
1141 	if (child == 0) {
1142 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1143 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1144 
1145 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1146 		FORKEE_ASSERT(raise(sigval) == 0);
1147 
1148 		switch (sigsent) {
1149 		case SIGCONT:
1150 		case SIGSTOP:
1151 			_exit(exitval);
1152 		default:
1153 			/* NOTREACHED */
1154 			FORKEE_ASSERTX(0 && "This shall not be reached");
1155 		}
1156 	}
1157 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1158 
1159 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1160 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1161 
1162 	validate_status_stopped(status, sigval);
1163 
1164 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1165 	SYSCALL_REQUIRE(
1166 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1167 
1168 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1169 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1170 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1171 	    info.psi_siginfo.si_errno);
1172 
1173 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1174 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1175 
1176 	DPRINTF("Before resuming the child process where it left off and with "
1177 	    "signal %s to be sent\n", strsignal(sigsent));
1178 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1179 
1180 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1181 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1182 
1183 	switch (sigsent) {
1184 	case SIGSTOP:
1185 		validate_status_stopped(status, sigsent);
1186 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1187 		    "child\n");
1188 		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1189 		    sizeof(info)) != -1);
1190 
1191 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1192 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1193 		    "si_errno=%#x\n",
1194 		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1195 		    info.psi_siginfo.si_errno);
1196 
1197 		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1198 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1199 
1200 		DPRINTF("Before resuming the child process where it left off "
1201 		    "and with signal %s to be sent\n", strsignal(sigsent));
1202 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1203 
1204 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1205 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1206 		    child);
1207 		/* FALLTHROUGH */
1208 	case SIGCONT:
1209 		validate_status_exited(status, exitval);
1210 		break;
1211 	default:
1212 		validate_status_signaled(status, sigsent, expect_core);
1213 		break;
1214 	}
1215 
1216 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1217 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1218 }
1219 
1220 #define TRACEME_SENDSIGNAL_SIMPLE(test, sig)				\
1221 ATF_TC(test);								\
1222 ATF_TC_HEAD(test, tc)							\
1223 {									\
1224 	atf_tc_set_md_var(tc, "descr",					\
1225 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1226 	    "handled correctly in a child without a signal handler");	\
1227 }									\
1228 									\
1229 ATF_TC_BODY(test, tc)							\
1230 {									\
1231 									\
1232 	traceme_sendsignal_simple(sig);					\
1233 }
1234 
TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1,SIGKILL)1235 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/
1236 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/
1237 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */
1238 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP)  /* hangup */
1239 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */
1240 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */
1241 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */
1242 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */
1243 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */
1244 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */
1245 
1246 /// ----------------------------------------------------------------------------
1247 
1248 static void
1249 traceme_vfork_raise(int sigval)
1250 {
1251 	const int exitval = 5, exitval_watcher = 10;
1252 	pid_t child, parent, watcher, wpid;
1253 	int rv;
1254 #if defined(TWAIT_HAVE_STATUS)
1255 	int status;
1256 
1257 	/* volatile workarounds GCC -Werror=clobbered */
1258 	volatile int expect_core;
1259 
1260 	switch (sigval) {
1261 	case SIGABRT:
1262 	case SIGTRAP:
1263 	case SIGBUS:
1264 	case SIGILL:
1265 	case SIGFPE:
1266 	case SIGSEGV:
1267 		expect_core = 1;
1268 		break;
1269 	default:
1270 		expect_core = 0;
1271 		break;
1272 	}
1273 #endif
1274 
1275 	/*
1276 	 * Spawn a dedicated thread to watch for a stopped child and emit
1277 	 * the SIGKILL signal to it.
1278 	 *
1279 	 * vfork(2) might clobber watcher, this means that it's safer and
1280 	 * simpler to reparent this process to initproc and forget about it.
1281 	 */
1282 	if (sigval == SIGSTOP) {
1283 		parent = getpid();
1284 
1285 		watcher = fork();
1286 		ATF_REQUIRE(watcher != 1);
1287 		if (watcher == 0) {
1288 			/* Double fork(2) trick to reparent to initproc */
1289 			watcher = fork();
1290 			FORKEE_ASSERT_NEQ(watcher, -1);
1291 			if (watcher != 0)
1292 				_exit(exitval_watcher);
1293 
1294 			child = await_stopped_child(parent);
1295 
1296 			errno = 0;
1297 			rv = kill(child, SIGKILL);
1298 			FORKEE_ASSERT_EQ(rv, 0);
1299 			FORKEE_ASSERT_EQ(errno, 0);
1300 
1301 			/* This exit value will be collected by initproc */
1302 			_exit(0);
1303 		}
1304 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1305 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
1306 		    watcher);
1307 
1308 		validate_status_exited(status, exitval_watcher);
1309 
1310 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1311 		TWAIT_REQUIRE_FAILURE(ECHILD,
1312 		    wpid = TWAIT_GENERIC(watcher, &status, 0));
1313 	}
1314 
1315 	DPRINTF("Before forking process PID=%d\n", getpid());
1316 	SYSCALL_REQUIRE((child = vfork()) != -1);
1317 	if (child == 0) {
1318 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1319 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1320 
1321 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1322 		FORKEE_ASSERT(raise(sigval) == 0);
1323 
1324 		switch (sigval) {
1325 		case SIGSTOP:
1326 		case SIGKILL:
1327 		case SIGABRT:
1328 		case SIGHUP:
1329 		case SIGTRAP:
1330 		case SIGBUS:
1331 		case SIGILL:
1332 		case SIGFPE:
1333 		case SIGSEGV:
1334 			/* NOTREACHED */
1335 			FORKEE_ASSERTX(0 && "This shall not be reached");
1336 			__unreachable();
1337 		default:
1338 			DPRINTF("Before exiting of the child process\n");
1339 			_exit(exitval);
1340 		}
1341 	}
1342 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1343 
1344 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1345 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1346 
1347 	switch (sigval) {
1348 	case SIGKILL:
1349 	case SIGABRT:
1350 	case SIGHUP:
1351 	case SIGTRAP:
1352 	case SIGBUS:
1353 	case SIGILL:
1354 	case SIGFPE:
1355 	case SIGSEGV:
1356 		validate_status_signaled(status, sigval, expect_core);
1357 		break;
1358 	case SIGSTOP:
1359 		validate_status_signaled(status, SIGKILL, 0);
1360 		break;
1361 	case SIGCONT:
1362 	case SIGTSTP:
1363 	case SIGTTIN:
1364 	case SIGTTOU:
1365 		validate_status_exited(status, exitval);
1366 		break;
1367 	default:
1368 		/* NOTREACHED */
1369 		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
1370 		break;
1371 	}
1372 
1373 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1374 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1375 }
1376 
1377 #define TRACEME_VFORK_RAISE(test, sig)					\
1378 ATF_TC(test);								\
1379 ATF_TC_HEAD(test, tc)							\
1380 {									\
1381 	atf_tc_set_md_var(tc, "descr",					\
1382 	    "Verify PT_TRACE_ME followed by raise of " #sig " in a "	\
1383 	    "vfork(2)ed child");					\
1384 }									\
1385 									\
1386 ATF_TC_BODY(test, tc)							\
1387 {									\
1388 									\
1389 	traceme_vfork_raise(sig);					\
1390 }
1391 
TRACEME_VFORK_RAISE(traceme_vfork_raise1,SIGKILL)1392 TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
1393 TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
1394 TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
1395 TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
1396 TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
1397 TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
1398 TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
1399 TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
1400 TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */
1401 TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */
1402 TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */
1403 TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */
1404 TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */
1405 
1406 /// ----------------------------------------------------------------------------
1407 
1408 static void
1409 traceme_vfork_crash(int sig)
1410 {
1411 	pid_t child, wpid;
1412 #if defined(TWAIT_HAVE_STATUS)
1413 	int status;
1414 #endif
1415 
1416 #ifndef PTRACE_ILLEGAL_ASM
1417 	if (sig == SIGILL)
1418 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1419 #endif
1420 
1421 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1422 		atf_tc_skip("FP exceptions are not supported");
1423 
1424 	DPRINTF("Before forking process PID=%d\n", getpid());
1425 	SYSCALL_REQUIRE((child = vfork()) != -1);
1426 	if (child == 0) {
1427 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1428 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1429 
1430 		DPRINTF("Before executing a trap\n");
1431 		switch (sig) {
1432 		case SIGTRAP:
1433 			trigger_trap();
1434 			break;
1435 		case SIGSEGV:
1436 			trigger_segv();
1437 			break;
1438 		case SIGILL:
1439 			trigger_ill();
1440 			break;
1441 		case SIGFPE:
1442 			trigger_fpe();
1443 			break;
1444 		case SIGBUS:
1445 			trigger_bus();
1446 			break;
1447 		default:
1448 			/* NOTREACHED */
1449 			FORKEE_ASSERTX(0 && "This shall not be reached");
1450 		}
1451 
1452 		/* NOTREACHED */
1453 		FORKEE_ASSERTX(0 && "This shall not be reached");
1454 	}
1455 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1456 
1457 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1458 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1459 
1460 	validate_status_signaled(status, sig, 1);
1461 
1462 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1463 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1464 }
1465 
1466 #define TRACEME_VFORK_CRASH(test, sig)					\
1467 ATF_TC(test);								\
1468 ATF_TC_HEAD(test, tc)							\
1469 {									\
1470 	atf_tc_set_md_var(tc, "descr",					\
1471 	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1472 	    "vfork(2)ed child");					\
1473 }									\
1474 									\
1475 ATF_TC_BODY(test, tc)							\
1476 {									\
1477 									\
1478 	traceme_vfork_crash(sig);					\
1479 }
1480 
TRACEME_VFORK_CRASH(traceme_vfork_crash_trap,SIGTRAP)1481 TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP)
1482 TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV)
1483 TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL)
1484 TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE)
1485 TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS)
1486 
1487 /// ----------------------------------------------------------------------------
1488 
1489 static void
1490 traceme_vfork_signalmasked_crash(int sig)
1491 {
1492 	pid_t child, wpid;
1493 #if defined(TWAIT_HAVE_STATUS)
1494 	int status;
1495 #endif
1496 	sigset_t intmask;
1497 
1498 #ifndef PTRACE_ILLEGAL_ASM
1499 	if (sig == SIGILL)
1500 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1501 #endif
1502 
1503 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1504 		atf_tc_skip("FP exceptions are not supported");
1505 
1506 	DPRINTF("Before forking process PID=%d\n", getpid());
1507 	SYSCALL_REQUIRE((child = vfork()) != -1);
1508 	if (child == 0) {
1509 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1510 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1511 
1512 		sigemptyset(&intmask);
1513 		sigaddset(&intmask, sig);
1514 		sigprocmask(SIG_BLOCK, &intmask, NULL);
1515 
1516 		DPRINTF("Before executing a trap\n");
1517 		switch (sig) {
1518 		case SIGTRAP:
1519 			trigger_trap();
1520 			break;
1521 		case SIGSEGV:
1522 			trigger_segv();
1523 			break;
1524 		case SIGILL:
1525 			trigger_ill();
1526 			break;
1527 		case SIGFPE:
1528 			trigger_fpe();
1529 			break;
1530 		case SIGBUS:
1531 			trigger_bus();
1532 			break;
1533 		default:
1534 			/* NOTREACHED */
1535 			FORKEE_ASSERTX(0 && "This shall not be reached");
1536 		}
1537 
1538 		/* NOTREACHED */
1539 		FORKEE_ASSERTX(0 && "This shall not be reached");
1540 	}
1541 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1542 
1543 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1544 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1545 
1546 	validate_status_signaled(status, sig, 1);
1547 
1548 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1549 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1550 }
1551 
1552 #define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig)			\
1553 ATF_TC(test);								\
1554 ATF_TC_HEAD(test, tc)							\
1555 {									\
1556 	atf_tc_set_md_var(tc, "descr",					\
1557 	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1558 	    "vfork(2)ed child with a masked signal");			\
1559 }									\
1560 									\
1561 ATF_TC_BODY(test, tc)							\
1562 {									\
1563 									\
1564 	traceme_vfork_signalmasked_crash(sig);				\
1565 }
1566 
TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap,SIGTRAP)1567 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP)
1568 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV)
1569 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL)
1570 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE)
1571 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS)
1572 
1573 /// ----------------------------------------------------------------------------
1574 
1575 static void
1576 traceme_vfork_signalignored_crash(int sig)
1577 {
1578 	pid_t child, wpid;
1579 #if defined(TWAIT_HAVE_STATUS)
1580 	int status;
1581 #endif
1582 	struct sigaction sa;
1583 
1584 #ifndef PTRACE_ILLEGAL_ASM
1585 	if (sig == SIGILL)
1586 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1587 #endif
1588 
1589 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1590 		atf_tc_skip("FP exceptions are not supported");
1591 
1592 	DPRINTF("Before forking process PID=%d\n", getpid());
1593 	SYSCALL_REQUIRE((child = vfork()) != -1);
1594 	if (child == 0) {
1595 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1596 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1597 
1598 		memset(&sa, 0, sizeof(sa));
1599 		sa.sa_handler = SIG_IGN;
1600 		sigemptyset(&sa.sa_mask);
1601 
1602 		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1603 
1604 		DPRINTF("Before executing a trap\n");
1605 		switch (sig) {
1606 		case SIGTRAP:
1607 			trigger_trap();
1608 			break;
1609 		case SIGSEGV:
1610 			trigger_segv();
1611 			break;
1612 		case SIGILL:
1613 			trigger_ill();
1614 			break;
1615 		case SIGFPE:
1616 			trigger_fpe();
1617 			break;
1618 		case SIGBUS:
1619 			trigger_bus();
1620 			break;
1621 		default:
1622 			/* NOTREACHED */
1623 			FORKEE_ASSERTX(0 && "This shall not be reached");
1624 		}
1625 
1626 		/* NOTREACHED */
1627 		FORKEE_ASSERTX(0 && "This shall not be reached");
1628 	}
1629 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1630 
1631 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1632 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1633 
1634 	validate_status_signaled(status, sig, 1);
1635 
1636 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1637 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1638 }
1639 
1640 #define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig)			\
1641 ATF_TC(test);								\
1642 ATF_TC_HEAD(test, tc)							\
1643 {									\
1644 	atf_tc_set_md_var(tc, "descr",					\
1645 	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1646 	    "vfork(2)ed child with ignored signal");			\
1647 }									\
1648 									\
1649 ATF_TC_BODY(test, tc)							\
1650 {									\
1651 									\
1652 	traceme_vfork_signalignored_crash(sig);				\
1653 }
1654 
TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,SIGTRAP)1655 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,
1656     SIGTRAP)
1657 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv,
1658     SIGSEGV)
1659 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill,
1660     SIGILL)
1661 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe,
1662     SIGFPE)
1663 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus,
1664     SIGBUS)
1665 
1666 /// ----------------------------------------------------------------------------
1667 
1668 #if defined(TWAIT_HAVE_PID)
1669 static void
1670 unrelated_tracer_sees_crash(int sig, bool masked, bool ignored)
1671 {
1672 	const int sigval = SIGSTOP;
1673 	struct msg_fds parent_tracee, parent_tracer;
1674 	const int exitval = 10;
1675 	pid_t tracee, tracer, wpid;
1676 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1677 #if defined(TWAIT_HAVE_STATUS)
1678 	int status;
1679 #endif
1680 	struct sigaction sa;
1681 	struct ptrace_siginfo info;
1682 	sigset_t intmask;
1683 	struct kinfo_proc2 kp;
1684 	size_t len = sizeof(kp);
1685 
1686 	int name[6];
1687 	const size_t namelen = __arraycount(name);
1688 	ki_sigset_t kp_sigmask;
1689 	ki_sigset_t kp_sigignore;
1690 
1691 #ifndef PTRACE_ILLEGAL_ASM
1692 	if (sig == SIGILL)
1693 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1694 #endif
1695 
1696 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1697 		atf_tc_skip("FP exceptions are not supported");
1698 
1699 	memset(&info, 0, sizeof(info));
1700 
1701 	DPRINTF("Spawn tracee\n");
1702 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1703 	tracee = atf_utils_fork();
1704 	if (tracee == 0) {
1705 		// Wait for parent to let us crash
1706 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
1707 
1708 		if (masked) {
1709 			sigemptyset(&intmask);
1710 			sigaddset(&intmask, sig);
1711 			sigprocmask(SIG_BLOCK, &intmask, NULL);
1712 		}
1713 
1714 		if (ignored) {
1715 			memset(&sa, 0, sizeof(sa));
1716 			sa.sa_handler = SIG_IGN;
1717 			sigemptyset(&sa.sa_mask);
1718 			FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1719 		}
1720 
1721 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1722 		FORKEE_ASSERT(raise(sigval) == 0);
1723 
1724 		DPRINTF("Before executing a trap\n");
1725 		switch (sig) {
1726 		case SIGTRAP:
1727 			trigger_trap();
1728 			break;
1729 		case SIGSEGV:
1730 			trigger_segv();
1731 			break;
1732 		case SIGILL:
1733 			trigger_ill();
1734 			break;
1735 		case SIGFPE:
1736 			trigger_fpe();
1737 			break;
1738 		case SIGBUS:
1739 			trigger_bus();
1740 			break;
1741 		default:
1742 			/* NOTREACHED */
1743 			FORKEE_ASSERTX(0 && "This shall not be reached");
1744 		}
1745 
1746 		/* NOTREACHED */
1747 		FORKEE_ASSERTX(0 && "This shall not be reached");
1748 	}
1749 
1750 	DPRINTF("Spawn debugger\n");
1751 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1752 	tracer = atf_utils_fork();
1753 	if (tracer == 0) {
1754 		/* Fork again and drop parent to reattach to PID 1 */
1755 		tracer = atf_utils_fork();
1756 		if (tracer != 0)
1757 			_exit(exitval);
1758 
1759 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1760 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1761 
1762 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1763 		FORKEE_REQUIRE_SUCCESS(
1764 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1765 
1766 		forkee_status_stopped(status, SIGSTOP);
1767 
1768 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1769 		    "traced process\n");
1770 		SYSCALL_REQUIRE(
1771 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1772 
1773 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1774 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1775 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1776 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1777 
1778 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
1779 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
1780 
1781 		/* Resume tracee with PT_CONTINUE */
1782 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1783 
1784 		/* Inform parent that tracer has attached to tracee */
1785 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1786 
1787 		/* Wait for parent to tell use that tracee should have exited */
1788 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
1789 
1790 		/* Wait for tracee and assert that it exited */
1791 		FORKEE_REQUIRE_SUCCESS(
1792 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1793 
1794 		forkee_status_stopped(status, sigval);
1795 
1796 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1797 		    "traced process\n");
1798 		SYSCALL_REQUIRE(
1799 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1800 
1801 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1802 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1803 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1804 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1805 
1806 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
1807 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
1808 
1809 		name[0] = CTL_KERN,
1810 		name[1] = KERN_PROC2,
1811 		name[2] = KERN_PROC_PID;
1812 		name[3] = tracee;
1813 		name[4] = sizeof(kp);
1814 		name[5] = 1;
1815 
1816 		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1817 
1818 		if (masked)
1819 			kp_sigmask = kp.p_sigmask;
1820 
1821 		if (ignored)
1822 			kp_sigignore = kp.p_sigignore;
1823 
1824 		/* Resume tracee with PT_CONTINUE */
1825 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1826 
1827 		/* Wait for tracee and assert that it exited */
1828 		FORKEE_REQUIRE_SUCCESS(
1829 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1830 
1831 		forkee_status_stopped(status, sig);
1832 
1833 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1834 		    "traced process\n");
1835 		SYSCALL_REQUIRE(
1836 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1837 
1838 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1839 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1840 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
1841 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1842 
1843 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig);
1844 
1845 		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1846 
1847 		if (masked) {
1848 			DPRINTF("kp_sigmask="
1849 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1850 			    PRIx32 "\n",
1851 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1852 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1853 
1854 			DPRINTF("kp.p_sigmask="
1855 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1856 			    PRIx32 "\n",
1857 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1858 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1859 
1860 			FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask,
1861 			    sizeof(kp_sigmask)));
1862 		}
1863 
1864 		if (ignored) {
1865 			DPRINTF("kp_sigignore="
1866 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1867 			    PRIx32 "\n",
1868 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1869 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1870 
1871 			DPRINTF("kp.p_sigignore="
1872 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1873 			    PRIx32 "\n",
1874 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1875 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1876 
1877 			FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore,
1878 			    sizeof(kp_sigignore)));
1879 		}
1880 
1881 		switch (sig) {
1882 		case SIGTRAP:
1883 			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
1884 			break;
1885 		case SIGSEGV:
1886 			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
1887 			break;
1888 		case SIGILL:
1889 			FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC &&
1890 			            info.psi_siginfo.si_code <= ILL_BADSTK);
1891 			break;
1892 		case SIGFPE:
1893 // XXXQEMU		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
1894 			break;
1895 		case SIGBUS:
1896 			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
1897 			break;
1898 		}
1899 
1900 		FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1);
1901 		DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME);
1902 		FORKEE_REQUIRE_SUCCESS(
1903 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1904 
1905 		forkee_status_signaled(status, SIGKILL, 0);
1906 
1907 		/* Inform parent that tracer is exiting normally */
1908 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
1909 
1910 		DPRINTF("Before exiting of the tracer process\n");
1911 		_exit(0 /* collect by initproc */);
1912 	}
1913 
1914 	DPRINTF("Wait for the tracer process (direct child) to exit "
1915 	    "calling %s()\n", TWAIT_FNAME);
1916 	TWAIT_REQUIRE_SUCCESS(
1917 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
1918 
1919 	validate_status_exited(status, exitval);
1920 
1921 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
1922 	    TWAIT_FNAME);
1923 	TWAIT_REQUIRE_SUCCESS(
1924 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
1925 
1926 	DPRINTF("Wait for the tracer to attach to the tracee\n");
1927 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
1928 
1929 	DPRINTF("Resume the tracee and let it crash\n");
1930 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
1931 
1932 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
1933 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
1934 
1935 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1936 	    TWAIT_FNAME);
1937 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1938 
1939 	validate_status_signaled(status, SIGKILL, 0);
1940 
1941 	DPRINTF("Await normal exit of tracer\n");
1942 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
1943 
1944 	msg_close(&parent_tracer);
1945 	msg_close(&parent_tracee);
1946 }
1947 
1948 #define UNRELATED_TRACER_SEES_CRASH(test, sig)				\
1949 ATF_TC(test);								\
1950 ATF_TC_HEAD(test, tc)							\
1951 {									\
1952 	atf_tc_set_md_var(tc, "descr",					\
1953 	    "Assert that an unrelated tracer sees crash signal from "	\
1954 	    "the debuggee");						\
1955 }									\
1956 									\
1957 ATF_TC_BODY(test, tc)							\
1958 {									\
1959 									\
1960 	unrelated_tracer_sees_crash(sig, false, false);			\
1961 }
1962 
1963 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP)
1964 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV)
1965 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL)
1966 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE)
1967 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS)
1968 
1969 #define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig)		\
1970 ATF_TC(test);								\
1971 ATF_TC_HEAD(test, tc)							\
1972 {									\
1973 	atf_tc_set_md_var(tc, "descr",					\
1974 	    "Assert that an unrelated tracer sees crash signal from "	\
1975 	    "the debuggee with masked signal");				\
1976 }									\
1977 									\
1978 ATF_TC_BODY(test, tc)							\
1979 {									\
1980 									\
1981 	unrelated_tracer_sees_crash(sig, true, false);			\
1982 }
1983 
1984 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1985     unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP)
1986 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1987     unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV)
1988 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1989     unrelated_tracer_sees_signalmasked_crash_ill, SIGILL)
1990 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1991     unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE)
1992 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1993     unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS)
1994 
1995 #define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig)		\
1996 ATF_TC(test);								\
1997 ATF_TC_HEAD(test, tc)							\
1998 {									\
1999 	atf_tc_set_md_var(tc, "descr",					\
2000 	    "Assert that an unrelated tracer sees crash signal from "	\
2001 	    "the debuggee with signal ignored");			\
2002 }									\
2003 									\
2004 ATF_TC_BODY(test, tc)							\
2005 {									\
2006 									\
2007 	unrelated_tracer_sees_crash(sig, false, true);			\
2008 }
2009 
2010 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2011     unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP)
2012 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2013     unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV)
2014 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2015     unrelated_tracer_sees_signalignored_crash_ill, SIGILL)
2016 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2017     unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE)
2018 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2019     unrelated_tracer_sees_signalignored_crash_bus, SIGBUS)
2020 #endif
2021 
2022 /// ----------------------------------------------------------------------------
2023 
2024 ATF_TC(signal_mask_unrelated);
ATF_TC_HEAD(signal_mask_unrelated,tc)2025 ATF_TC_HEAD(signal_mask_unrelated, tc)
2026 {
2027 	atf_tc_set_md_var(tc, "descr",
2028 	    "Verify that masking single unrelated signal does not stop tracer "
2029 	    "from catching other signals");
2030 }
2031 
ATF_TC_BODY(signal_mask_unrelated,tc)2032 ATF_TC_BODY(signal_mask_unrelated, tc)
2033 {
2034 	const int exitval = 5;
2035 	const int sigval = SIGSTOP;
2036 	const int sigmasked = SIGTRAP;
2037 	const int signotmasked = SIGINT;
2038 	pid_t child, wpid;
2039 #if defined(TWAIT_HAVE_STATUS)
2040 	int status;
2041 #endif
2042 	sigset_t intmask;
2043 
2044 	DPRINTF("Before forking process PID=%d\n", getpid());
2045 	SYSCALL_REQUIRE((child = fork()) != -1);
2046 	if (child == 0) {
2047 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2048 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2049 
2050 		sigemptyset(&intmask);
2051 		sigaddset(&intmask, sigmasked);
2052 		sigprocmask(SIG_BLOCK, &intmask, NULL);
2053 
2054 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2055 		FORKEE_ASSERT(raise(sigval) == 0);
2056 
2057 		DPRINTF("Before raising %s from child\n",
2058 		    strsignal(signotmasked));
2059 		FORKEE_ASSERT(raise(signotmasked) == 0);
2060 
2061 		DPRINTF("Before exiting of the child process\n");
2062 		_exit(exitval);
2063 	}
2064 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2065 
2066 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2067 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2068 
2069 	validate_status_stopped(status, sigval);
2070 
2071 	DPRINTF("Before resuming the child process where it left off and "
2072 	    "without signal to be sent\n");
2073 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2074 
2075 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2076 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2077 
2078 	validate_status_stopped(status, signotmasked);
2079 
2080 	DPRINTF("Before resuming the child process where it left off and "
2081 	    "without signal to be sent\n");
2082 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2083 
2084 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2085 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2086 
2087 	validate_status_exited(status, exitval);
2088 
2089 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2090 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2091 }
2092 
2093 /// ----------------------------------------------------------------------------
2094 
2095 #define ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL() \
2096 	ATF_TP_ADD_TC(tp, traceme_raise1); \
2097 	ATF_TP_ADD_TC(tp, traceme_raise2); \
2098 	ATF_TP_ADD_TC(tp, traceme_raise3); \
2099 	ATF_TP_ADD_TC(tp, traceme_raise4); \
2100 	ATF_TP_ADD_TC(tp, traceme_raise5); \
2101 	ATF_TP_ADD_TC(tp, traceme_raise6); \
2102 	ATF_TP_ADD_TC(tp, traceme_raise7); \
2103 	ATF_TP_ADD_TC(tp, traceme_raise8); \
2104 	ATF_TP_ADD_TC(tp, traceme_raise9); \
2105 	ATF_TP_ADD_TC(tp, traceme_raise10); \
2106 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); \
2107 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); \
2108 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); \
2109 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); \
2110 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); \
2111 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); \
2112 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); \
2113 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); \
2114 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); \
2115 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); \
2116 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); \
2117 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); \
2118 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); \
2119 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); \
2120 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); \
2121 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); \
2122 	ATF_TP_ADD_TC(tp, traceme_crash_trap); \
2123 	ATF_TP_ADD_TC(tp, traceme_crash_segv); \
2124 	ATF_TP_ADD_TC(tp, traceme_crash_ill); \
2125 	ATF_TP_ADD_TC(tp, traceme_crash_fpe); \
2126 	ATF_TP_ADD_TC(tp, traceme_crash_bus); \
2127 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); \
2128 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); \
2129 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); \
2130 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); \
2131 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); \
2132 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); \
2133 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); \
2134 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); \
2135 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); \
2136 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); \
2137 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); \
2138 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); \
2139 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); \
2140 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); \
2141 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); \
2142 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); \
2143 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); \
2144 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); \
2145 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); \
2146 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); \
2147 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); \
2148 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); \
2149 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); \
2150 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); \
2151 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); \
2152 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); \
2153 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); \
2154 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); \
2155 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); \
2156 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); \
2157 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); \
2158 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); \
2159 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); \
2160 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); \
2161 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); \
2162 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); \
2163 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); \
2164 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); \
2165 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); \
2166 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); \
2167 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); \
2168 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); \
2169 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); \
2170 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); \
2171 	ATF_TP_ADD_TC(tp, traceme_vfork_raise1); \
2172 	ATF_TP_ADD_TC(tp, traceme_vfork_raise2); \
2173 	ATF_TP_ADD_TC(tp, traceme_vfork_raise3); \
2174 	ATF_TP_ADD_TC(tp, traceme_vfork_raise4); \
2175 	ATF_TP_ADD_TC(tp, traceme_vfork_raise5); \
2176 	ATF_TP_ADD_TC(tp, traceme_vfork_raise6); \
2177 	ATF_TP_ADD_TC(tp, traceme_vfork_raise7); \
2178 	ATF_TP_ADD_TC(tp, traceme_vfork_raise8); \
2179 	ATF_TP_ADD_TC(tp, traceme_vfork_raise9); \
2180 	ATF_TP_ADD_TC(tp, traceme_vfork_raise10); \
2181 	ATF_TP_ADD_TC(tp, traceme_vfork_raise11); \
2182 	ATF_TP_ADD_TC(tp, traceme_vfork_raise12); \
2183 	ATF_TP_ADD_TC(tp, traceme_vfork_raise13); \
2184 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); \
2185 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); \
2186 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); \
2187 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); \
2188 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); \
2189 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); \
2190 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); \
2191 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); \
2192 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); \
2193 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); \
2194 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); \
2195 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); \
2196 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); \
2197 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); \
2198 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); \
2199 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); \
2200 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); \
2201 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); \
2202 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); \
2203 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); \
2204 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2205 	    unrelated_tracer_sees_signalmasked_crash_trap); \
2206 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2207 	    unrelated_tracer_sees_signalmasked_crash_segv); \
2208 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2209 	    unrelated_tracer_sees_signalmasked_crash_ill); \
2210 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2211 	    unrelated_tracer_sees_signalmasked_crash_fpe); \
2212 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2213 	    unrelated_tracer_sees_signalmasked_crash_bus); \
2214 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2215 	    unrelated_tracer_sees_signalignored_crash_trap); \
2216 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2217 	    unrelated_tracer_sees_signalignored_crash_segv); \
2218 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2219 	    unrelated_tracer_sees_signalignored_crash_ill); \
2220 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2221 	    unrelated_tracer_sees_signalignored_crash_fpe); \
2222 	ATF_TP_ADD_TC_HAVE_PID(tp, \
2223 	    unrelated_tracer_sees_signalignored_crash_bus); \
2224 	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
2225