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