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