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