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