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