1 /* $NetBSD: t_ptrace_wait.c,v 1.169 2020/03/07 14:53:14 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2016, 2017, 2018, 2019 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 #include <sys/cdefs.h> 30 __RCSID("$NetBSD: t_ptrace_wait.c,v 1.169 2020/03/07 14:53:14 christos Exp $"); 31 32 #define __LEGACY_PT_LWPINFO 33 34 #include <sys/param.h> 35 #include <sys/types.h> 36 #include <sys/exec_elf.h> 37 #include <sys/mman.h> 38 #include <sys/ptrace.h> 39 #include <sys/resource.h> 40 #include <sys/stat.h> 41 #include <sys/syscall.h> 42 #include <sys/sysctl.h> 43 #include <sys/uio.h> 44 #include <sys/wait.h> 45 #include <machine/reg.h> 46 #include <assert.h> 47 #include <elf.h> 48 #include <err.h> 49 #include <errno.h> 50 #include <fcntl.h> 51 #include <lwp.h> 52 #include <pthread.h> 53 #include <sched.h> 54 #include <signal.h> 55 #include <spawn.h> 56 #include <stdint.h> 57 #include <stdio.h> 58 #include <stdlib.h> 59 #include <strings.h> 60 #include <time.h> 61 #include <unistd.h> 62 63 #if defined(__i386__) || defined(__x86_64__) 64 #include <cpuid.h> 65 #include <x86/cpu_extended_state.h> 66 #include <x86/specialreg.h> 67 #endif 68 69 #include <libelf.h> 70 #include <gelf.h> 71 72 #include <atf-c.h> 73 74 #ifdef ENABLE_TESTS 75 76 /* Assumptions in the kernel code that must be kept. */ 77 static_assert(sizeof(((struct ptrace_state *)0)->pe_report_event) == 78 sizeof(((siginfo_t *)0)->si_pe_report_event), 79 "pe_report_event and si_pe_report_event must be of the same size"); 80 static_assert(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 81 sizeof(((siginfo_t *)0)->si_pe_other_pid), 82 "pe_other_pid and si_pe_other_pid must be of the same size"); 83 static_assert(sizeof(((struct ptrace_state *)0)->pe_lwp) == 84 sizeof(((siginfo_t *)0)->si_pe_lwp), 85 "pe_lwp and si_pe_lwp must be of the same size"); 86 static_assert(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 87 sizeof(((struct ptrace_state *)0)->pe_lwp), 88 "pe_other_pid and pe_lwp must be of the same size"); 89 90 #include "h_macros.h" 91 92 #include "t_ptrace_wait.h" 93 #include "msg.h" 94 95 #define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 96 strerror(errno)) 97 #define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 98 "%d(%s) != %d", res, strerror(res), exp) 99 100 static int debug = 0; 101 102 #define DPRINTF(a, ...) do \ 103 if (debug) \ 104 printf("%s() %d.%d %s:%d " a, \ 105 __func__, getpid(), _lwp_self(), __FILE__, __LINE__, ##__VA_ARGS__); \ 106 while (/*CONSTCOND*/0) 107 108 /// ---------------------------------------------------------------------------- 109 110 static void 111 traceme_raise(int sigval) 112 { 113 const int exitval = 5; 114 pid_t child, wpid; 115 #if defined(TWAIT_HAVE_STATUS) 116 int status; 117 #endif 118 119 ptrace_state_t state, zero_state; 120 const int slen = sizeof(state); 121 struct ptrace_siginfo info; 122 memset(&zero_state, 0, sizeof(zero_state)); 123 memset(&info, 0, sizeof(info)); 124 125 DPRINTF("Before forking process PID=%d\n", getpid()); 126 SYSCALL_REQUIRE((child = fork()) != -1); 127 if (child == 0) { 128 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 129 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 130 131 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 132 FORKEE_ASSERT(raise(sigval) == 0); 133 134 switch (sigval) { 135 case SIGKILL: 136 /* NOTREACHED */ 137 FORKEE_ASSERTX(0 && "This shall not be reached"); 138 __unreachable(); 139 default: 140 DPRINTF("Before exiting of the child process\n"); 141 _exit(exitval); 142 } 143 } 144 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 145 146 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 147 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 148 149 switch (sigval) { 150 case SIGKILL: 151 validate_status_signaled(status, sigval, 0); 152 SYSCALL_REQUIRE( 153 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) == -1); 154 155 break; 156 default: 157 validate_status_stopped(status, sigval); 158 159 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 160 "child\n"); 161 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 162 sizeof(info)) != -1); 163 164 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 165 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 166 "si_errno=%#x\n", 167 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 168 info.psi_siginfo.si_errno); 169 170 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 171 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 172 173 DPRINTF("Assert that PT_GET_PROCESS_STATE returns non-error"); 174 SYSCALL_REQUIRE( 175 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 176 ATF_REQUIRE(memcmp(&state, &zero_state, slen) == 0); 177 178 DPRINTF("Before resuming the child process where it left off " 179 "and without signal to be sent\n"); 180 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 181 182 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 183 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 184 child); 185 break; 186 } 187 188 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 189 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 190 } 191 192 #define TRACEME_RAISE(test, sig) \ 193 ATF_TC(test); \ 194 ATF_TC_HEAD(test, tc) \ 195 { \ 196 atf_tc_set_md_var(tc, "descr", \ 197 "Verify " #sig " followed by _exit(2) in a child"); \ 198 } \ 199 \ 200 ATF_TC_BODY(test, tc) \ 201 { \ 202 \ 203 traceme_raise(sig); \ 204 } 205 206 TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ 207 TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */ 208 TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */ 209 TRACEME_RAISE(traceme_raise4, SIGHUP) /* hangup */ 210 TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */ 211 TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */ 212 TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */ 213 TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */ 214 TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */ 215 TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */ 216 217 /// ---------------------------------------------------------------------------- 218 219 static void 220 traceme_raisesignal_ignored(int sigignored) 221 { 222 const int exitval = 5; 223 const int sigval = SIGSTOP; 224 pid_t child, wpid; 225 struct sigaction sa; 226 #if defined(TWAIT_HAVE_STATUS) 227 int status; 228 #endif 229 struct ptrace_siginfo info; 230 231 memset(&info, 0, sizeof(info)); 232 233 DPRINTF("Before forking process PID=%d\n", getpid()); 234 SYSCALL_REQUIRE((child = fork()) != -1); 235 if (child == 0) { 236 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 237 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 238 239 memset(&sa, 0, sizeof(sa)); 240 sa.sa_handler = SIG_IGN; 241 sigemptyset(&sa.sa_mask); 242 FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1); 243 244 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 245 FORKEE_ASSERT(raise(sigval) == 0); 246 247 DPRINTF("Before raising %s from child\n", 248 strsignal(sigignored)); 249 FORKEE_ASSERT(raise(sigignored) == 0); 250 251 DPRINTF("Before exiting of the child process\n"); 252 _exit(exitval); 253 } 254 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 255 256 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 257 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 258 259 validate_status_stopped(status, sigval); 260 261 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 262 SYSCALL_REQUIRE( 263 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 264 265 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 266 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 267 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 268 info.psi_siginfo.si_errno); 269 270 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 271 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 272 273 DPRINTF("Before resuming the child process where it left off and " 274 "without signal to be sent\n"); 275 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 276 277 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 278 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 279 280 validate_status_stopped(status, sigignored); 281 282 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 283 SYSCALL_REQUIRE( 284 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 285 286 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 287 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 288 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 289 info.psi_siginfo.si_errno); 290 291 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored); 292 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 293 294 DPRINTF("Before resuming the child process where it left off and " 295 "without signal to be sent\n"); 296 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 297 298 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 299 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 300 301 validate_status_exited(status, exitval); 302 303 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 304 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 305 } 306 307 #define TRACEME_RAISESIGNAL_IGNORED(test, sig) \ 308 ATF_TC(test); \ 309 ATF_TC_HEAD(test, tc) \ 310 { \ 311 atf_tc_set_md_var(tc, "descr", \ 312 "Verify that ignoring (with SIG_IGN) " #sig " in tracee " \ 313 "does not stop tracer from catching this raised signal"); \ 314 } \ 315 \ 316 ATF_TC_BODY(test, tc) \ 317 { \ 318 \ 319 traceme_raisesignal_ignored(sig); \ 320 } 321 322 // A signal handler for SIGKILL and SIGSTOP cannot be ignored. 323 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */ 324 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP) /* hangup */ 325 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */ 326 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */ 327 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */ 328 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */ 329 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */ 330 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */ 331 332 /// ---------------------------------------------------------------------------- 333 334 static void 335 traceme_raisesignal_masked(int sigmasked) 336 { 337 const int exitval = 5; 338 const int sigval = SIGSTOP; 339 pid_t child, wpid; 340 #if defined(TWAIT_HAVE_STATUS) 341 int status; 342 #endif 343 sigset_t intmask; 344 struct ptrace_siginfo info; 345 346 memset(&info, 0, sizeof(info)); 347 348 DPRINTF("Before forking process PID=%d\n", getpid()); 349 SYSCALL_REQUIRE((child = fork()) != -1); 350 if (child == 0) { 351 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 352 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 353 354 sigemptyset(&intmask); 355 sigaddset(&intmask, sigmasked); 356 sigprocmask(SIG_BLOCK, &intmask, NULL); 357 358 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 359 FORKEE_ASSERT(raise(sigval) == 0); 360 361 DPRINTF("Before raising %s breakpoint from child\n", 362 strsignal(sigmasked)); 363 FORKEE_ASSERT(raise(sigmasked) == 0); 364 365 DPRINTF("Before exiting of the child process\n"); 366 _exit(exitval); 367 } 368 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 369 370 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 371 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 372 373 validate_status_stopped(status, sigval); 374 375 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 376 SYSCALL_REQUIRE( 377 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 378 379 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 380 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 381 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 382 info.psi_siginfo.si_errno); 383 384 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 385 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 386 387 DPRINTF("Before resuming the child process where it left off and " 388 "without signal to be sent\n"); 389 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 390 391 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 392 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 393 394 validate_status_exited(status, exitval); 395 396 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 397 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 398 } 399 400 #define TRACEME_RAISESIGNAL_MASKED(test, sig) \ 401 ATF_TC(test); \ 402 ATF_TC_HEAD(test, tc) \ 403 { \ 404 atf_tc_set_md_var(tc, "descr", \ 405 "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \ 406 "stops tracer from catching this raised signal"); \ 407 } \ 408 \ 409 ATF_TC_BODY(test, tc) \ 410 { \ 411 \ 412 traceme_raisesignal_masked(sig); \ 413 } 414 415 // A signal handler for SIGKILL and SIGSTOP cannot be masked. 416 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */ 417 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */ 418 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */ 419 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */ 420 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */ 421 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */ 422 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */ 423 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */ 424 425 /// ---------------------------------------------------------------------------- 426 427 static void 428 traceme_crash(int sig) 429 { 430 pid_t child, wpid; 431 #if defined(TWAIT_HAVE_STATUS) 432 int status; 433 #endif 434 struct ptrace_siginfo info; 435 436 #ifndef PTRACE_ILLEGAL_ASM 437 if (sig == SIGILL) 438 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 439 #endif 440 441 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 442 atf_tc_skip("FP exceptions are not supported"); 443 444 memset(&info, 0, sizeof(info)); 445 446 DPRINTF("Before forking process PID=%d\n", getpid()); 447 SYSCALL_REQUIRE((child = fork()) != -1); 448 if (child == 0) { 449 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 450 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 451 452 DPRINTF("Before executing a trap\n"); 453 switch (sig) { 454 case SIGTRAP: 455 trigger_trap(); 456 break; 457 case SIGSEGV: 458 trigger_segv(); 459 break; 460 case SIGILL: 461 trigger_ill(); 462 break; 463 case SIGFPE: 464 trigger_fpe(); 465 break; 466 case SIGBUS: 467 trigger_bus(); 468 break; 469 default: 470 /* NOTREACHED */ 471 FORKEE_ASSERTX(0 && "This shall not be reached"); 472 } 473 474 /* NOTREACHED */ 475 FORKEE_ASSERTX(0 && "This shall not be reached"); 476 } 477 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 478 479 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 480 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 481 482 validate_status_stopped(status, sig); 483 484 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 485 SYSCALL_REQUIRE( 486 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 487 488 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 489 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 490 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 491 info.psi_siginfo.si_errno); 492 493 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 494 switch (sig) { 495 case SIGTRAP: 496 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 497 break; 498 case SIGSEGV: 499 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 500 break; 501 case SIGILL: 502 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 503 info.psi_siginfo.si_code <= ILL_BADSTK); 504 break; 505 case SIGFPE: 506 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 507 break; 508 case SIGBUS: 509 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 510 break; 511 } 512 513 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 514 515 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 516 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 517 518 validate_status_signaled(status, SIGKILL, 0); 519 520 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 521 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 522 } 523 524 #define TRACEME_CRASH(test, sig) \ 525 ATF_TC(test); \ 526 ATF_TC_HEAD(test, tc) \ 527 { \ 528 atf_tc_set_md_var(tc, "descr", \ 529 "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \ 530 } \ 531 \ 532 ATF_TC_BODY(test, tc) \ 533 { \ 534 \ 535 traceme_crash(sig); \ 536 } 537 538 TRACEME_CRASH(traceme_crash_trap, SIGTRAP) 539 TRACEME_CRASH(traceme_crash_segv, SIGSEGV) 540 TRACEME_CRASH(traceme_crash_ill, SIGILL) 541 TRACEME_CRASH(traceme_crash_fpe, SIGFPE) 542 TRACEME_CRASH(traceme_crash_bus, SIGBUS) 543 544 /// ---------------------------------------------------------------------------- 545 546 static void 547 traceme_signalmasked_crash(int sig) 548 { 549 const int sigval = SIGSTOP; 550 pid_t child, wpid; 551 #if defined(TWAIT_HAVE_STATUS) 552 int status; 553 #endif 554 struct ptrace_siginfo info; 555 sigset_t intmask; 556 struct kinfo_proc2 kp; 557 size_t len = sizeof(kp); 558 559 int name[6]; 560 const size_t namelen = __arraycount(name); 561 ki_sigset_t kp_sigmask; 562 563 #ifndef PTRACE_ILLEGAL_ASM 564 if (sig == SIGILL) 565 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 566 #endif 567 568 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 569 atf_tc_skip("FP exceptions are not supported"); 570 571 memset(&info, 0, sizeof(info)); 572 573 DPRINTF("Before forking process PID=%d\n", getpid()); 574 SYSCALL_REQUIRE((child = fork()) != -1); 575 if (child == 0) { 576 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 577 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 578 579 sigemptyset(&intmask); 580 sigaddset(&intmask, sig); 581 sigprocmask(SIG_BLOCK, &intmask, NULL); 582 583 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 584 FORKEE_ASSERT(raise(sigval) == 0); 585 586 DPRINTF("Before executing a trap\n"); 587 switch (sig) { 588 case SIGTRAP: 589 trigger_trap(); 590 break; 591 case SIGSEGV: 592 trigger_segv(); 593 break; 594 case SIGILL: 595 trigger_ill(); 596 break; 597 case SIGFPE: 598 trigger_fpe(); 599 break; 600 case SIGBUS: 601 trigger_bus(); 602 break; 603 default: 604 /* NOTREACHED */ 605 FORKEE_ASSERTX(0 && "This shall not be reached"); 606 } 607 608 /* NOTREACHED */ 609 FORKEE_ASSERTX(0 && "This shall not be reached"); 610 } 611 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 612 613 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 614 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 615 616 validate_status_stopped(status, sigval); 617 618 name[0] = CTL_KERN, 619 name[1] = KERN_PROC2, 620 name[2] = KERN_PROC_PID; 621 name[3] = child; 622 name[4] = sizeof(kp); 623 name[5] = 1; 624 625 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 626 627 kp_sigmask = kp.p_sigmask; 628 629 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 630 SYSCALL_REQUIRE( 631 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 632 633 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 634 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 635 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 636 info.psi_siginfo.si_errno); 637 638 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 639 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 640 641 DPRINTF("Before resuming the child process where it left off and " 642 "without signal to be sent\n"); 643 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 644 645 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 646 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 647 648 validate_status_stopped(status, sig); 649 650 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 651 SYSCALL_REQUIRE( 652 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 653 654 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 655 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 656 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 657 info.psi_siginfo.si_errno); 658 659 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 660 661 DPRINTF("kp_sigmask=" 662 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 663 kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2], 664 kp_sigmask.__bits[3]); 665 666 DPRINTF("kp.p_sigmask=" 667 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 668 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 669 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 670 671 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask))); 672 673 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 674 switch (sig) { 675 case SIGTRAP: 676 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 677 break; 678 case SIGSEGV: 679 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 680 break; 681 case SIGILL: 682 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 683 info.psi_siginfo.si_code <= ILL_BADSTK); 684 break; 685 case SIGFPE: 686 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 687 break; 688 case SIGBUS: 689 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 690 break; 691 } 692 693 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 694 695 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 696 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 697 698 validate_status_signaled(status, SIGKILL, 0); 699 700 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 701 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 702 } 703 704 #define TRACEME_SIGNALMASKED_CRASH(test, sig) \ 705 ATF_TC(test); \ 706 ATF_TC_HEAD(test, tc) \ 707 { \ 708 atf_tc_set_md_var(tc, "descr", \ 709 "Verify masked crash signal " #sig " in a child after " \ 710 "PT_TRACE_ME is delivered to its tracer"); \ 711 } \ 712 \ 713 ATF_TC_BODY(test, tc) \ 714 { \ 715 \ 716 traceme_signalmasked_crash(sig); \ 717 } 718 719 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP) 720 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV) 721 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL) 722 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE) 723 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS) 724 725 /// ---------------------------------------------------------------------------- 726 727 static void 728 traceme_signalignored_crash(int sig) 729 { 730 const int sigval = SIGSTOP; 731 pid_t child, wpid; 732 #if defined(TWAIT_HAVE_STATUS) 733 int status; 734 #endif 735 struct sigaction sa; 736 struct ptrace_siginfo info; 737 struct kinfo_proc2 kp; 738 size_t len = sizeof(kp); 739 740 int name[6]; 741 const size_t namelen = __arraycount(name); 742 ki_sigset_t kp_sigignore; 743 744 #ifndef PTRACE_ILLEGAL_ASM 745 if (sig == SIGILL) 746 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 747 #endif 748 749 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 750 atf_tc_skip("FP exceptions are not supported"); 751 752 memset(&info, 0, sizeof(info)); 753 754 DPRINTF("Before forking process PID=%d\n", getpid()); 755 SYSCALL_REQUIRE((child = fork()) != -1); 756 if (child == 0) { 757 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 758 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 759 760 memset(&sa, 0, sizeof(sa)); 761 sa.sa_handler = SIG_IGN; 762 sigemptyset(&sa.sa_mask); 763 764 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 765 766 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 767 FORKEE_ASSERT(raise(sigval) == 0); 768 769 DPRINTF("Before executing a trap\n"); 770 switch (sig) { 771 case SIGTRAP: 772 trigger_trap(); 773 break; 774 case SIGSEGV: 775 trigger_segv(); 776 break; 777 case SIGILL: 778 trigger_ill(); 779 break; 780 case SIGFPE: 781 trigger_fpe(); 782 break; 783 case SIGBUS: 784 trigger_bus(); 785 break; 786 default: 787 /* NOTREACHED */ 788 FORKEE_ASSERTX(0 && "This shall not be reached"); 789 } 790 791 /* NOTREACHED */ 792 FORKEE_ASSERTX(0 && "This shall not be reached"); 793 } 794 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 795 796 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 797 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 798 799 validate_status_stopped(status, sigval); 800 801 name[0] = CTL_KERN, 802 name[1] = KERN_PROC2, 803 name[2] = KERN_PROC_PID; 804 name[3] = child; 805 name[4] = sizeof(kp); 806 name[5] = 1; 807 808 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 809 810 kp_sigignore = kp.p_sigignore; 811 812 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 813 SYSCALL_REQUIRE( 814 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 815 816 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 817 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 818 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 819 info.psi_siginfo.si_errno); 820 821 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 822 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 823 824 DPRINTF("Before resuming the child process where it left off and " 825 "without signal to be sent\n"); 826 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 827 828 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 829 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 830 831 validate_status_stopped(status, sig); 832 833 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 834 SYSCALL_REQUIRE( 835 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 836 837 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 838 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 839 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 840 info.psi_siginfo.si_errno); 841 842 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 843 844 DPRINTF("kp_sigignore=" 845 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 846 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 847 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 848 849 DPRINTF("kp.p_sigignore=" 850 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 851 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 852 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 853 854 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore))); 855 856 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 857 switch (sig) { 858 case SIGTRAP: 859 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 860 break; 861 case SIGSEGV: 862 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 863 break; 864 case SIGILL: 865 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 866 info.psi_siginfo.si_code <= ILL_BADSTK); 867 break; 868 case SIGFPE: 869 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 870 break; 871 case SIGBUS: 872 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 873 break; 874 } 875 876 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 877 878 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 879 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 880 881 validate_status_signaled(status, SIGKILL, 0); 882 883 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 884 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 885 } 886 887 #define TRACEME_SIGNALIGNORED_CRASH(test, sig) \ 888 ATF_TC(test); \ 889 ATF_TC_HEAD(test, tc) \ 890 { \ 891 atf_tc_set_md_var(tc, "descr", \ 892 "Verify ignored crash signal " #sig " in a child after " \ 893 "PT_TRACE_ME is delivered to its tracer"); \ 894 } \ 895 \ 896 ATF_TC_BODY(test, tc) \ 897 { \ 898 \ 899 traceme_signalignored_crash(sig); \ 900 } 901 902 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP) 903 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV) 904 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL) 905 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE) 906 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS) 907 908 /// ---------------------------------------------------------------------------- 909 910 static void 911 traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 912 { 913 const int exitval = 5; 914 const int sigval = SIGSTOP; 915 pid_t child, wpid; 916 struct sigaction sa; 917 #if defined(TWAIT_HAVE_STATUS) 918 int status; 919 #endif 920 struct ptrace_siginfo info; 921 922 memset(&info, 0, sizeof(info)); 923 924 DPRINTF("Before forking process PID=%d\n", getpid()); 925 SYSCALL_REQUIRE((child = fork()) != -1); 926 if (child == 0) { 927 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 928 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 929 930 sa.sa_handler = sah; 931 sa.sa_flags = SA_SIGINFO; 932 sigemptyset(&sa.sa_mask); 933 934 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 935 936 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 937 FORKEE_ASSERT(raise(sigval) == 0); 938 939 FORKEE_ASSERT_EQ(*traceme_caught, 1); 940 941 DPRINTF("Before exiting of the child process\n"); 942 _exit(exitval); 943 } 944 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 945 946 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 947 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 948 949 validate_status_stopped(status, sigval); 950 951 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 952 SYSCALL_REQUIRE( 953 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 954 955 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 956 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 957 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 958 info.psi_siginfo.si_errno); 959 960 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 961 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 962 963 DPRINTF("Before resuming the child process where it left off and with " 964 "signal %s to be sent\n", strsignal(sigsent)); 965 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 966 967 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 968 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 969 970 validate_status_exited(status, exitval); 971 972 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 973 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 974 } 975 976 #define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 977 ATF_TC(test); \ 978 ATF_TC_HEAD(test, tc) \ 979 { \ 980 atf_tc_set_md_var(tc, "descr", \ 981 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 982 "handled correctly and caught by a signal handler"); \ 983 } \ 984 \ 985 static int test##_caught = 0; \ 986 \ 987 static void \ 988 test##_sighandler(int arg) \ 989 { \ 990 FORKEE_ASSERT_EQ(arg, sig); \ 991 \ 992 ++ test##_caught; \ 993 } \ 994 \ 995 ATF_TC_BODY(test, tc) \ 996 { \ 997 \ 998 traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 999 } 1000 1001 // A signal handler for SIGKILL and SIGSTOP cannot be registered. 1002 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 1003 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 1004 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 1005 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 1006 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 1007 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 1008 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 1009 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 1010 1011 /// ---------------------------------------------------------------------------- 1012 1013 static void 1014 traceme_sendsignal_masked(int sigsent) 1015 { 1016 const int exitval = 5; 1017 const int sigval = SIGSTOP; 1018 pid_t child, wpid; 1019 sigset_t set; 1020 #if defined(TWAIT_HAVE_STATUS) 1021 int status; 1022 #endif 1023 struct ptrace_siginfo info; 1024 1025 memset(&info, 0, sizeof(info)); 1026 1027 DPRINTF("Before forking process PID=%d\n", getpid()); 1028 SYSCALL_REQUIRE((child = fork()) != -1); 1029 if (child == 0) { 1030 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1031 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1032 1033 sigemptyset(&set); 1034 sigaddset(&set, sigsent); 1035 FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 1036 1037 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1038 FORKEE_ASSERT(raise(sigval) == 0); 1039 1040 _exit(exitval); 1041 } 1042 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1043 1044 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1045 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1046 1047 validate_status_stopped(status, sigval); 1048 1049 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1050 SYSCALL_REQUIRE( 1051 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1052 1053 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1054 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1055 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1056 info.psi_siginfo.si_errno); 1057 1058 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1059 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1060 1061 DPRINTF("Before resuming the child process where it left off and with " 1062 "signal %s to be sent\n", strsignal(sigsent)); 1063 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1064 1065 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1066 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1067 1068 validate_status_exited(status, exitval); 1069 1070 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1071 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1072 } 1073 1074 #define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 1075 ATF_TC(test); \ 1076 ATF_TC_HEAD(test, tc) \ 1077 { \ 1078 atf_tc_set_md_var(tc, "descr", \ 1079 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1080 "handled correctly and the signal is masked by SIG_BLOCK"); \ 1081 } \ 1082 \ 1083 ATF_TC_BODY(test, tc) \ 1084 { \ 1085 \ 1086 traceme_sendsignal_masked(sig); \ 1087 } 1088 1089 // A signal handler for SIGKILL and SIGSTOP cannot be masked. 1090 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 1091 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 1092 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 1093 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 1094 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 1095 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 1096 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 1097 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 1098 1099 /// ---------------------------------------------------------------------------- 1100 1101 static void 1102 traceme_sendsignal_ignored(int sigsent) 1103 { 1104 const int exitval = 5; 1105 const int sigval = SIGSTOP; 1106 pid_t child, wpid; 1107 struct sigaction sa; 1108 #if defined(TWAIT_HAVE_STATUS) 1109 int status; 1110 #endif 1111 struct ptrace_siginfo info; 1112 1113 memset(&info, 0, sizeof(info)); 1114 1115 DPRINTF("Before forking process PID=%d\n", getpid()); 1116 SYSCALL_REQUIRE((child = fork()) != -1); 1117 if (child == 0) { 1118 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1119 1120 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1121 1122 memset(&sa, 0, sizeof(sa)); 1123 sa.sa_handler = SIG_IGN; 1124 sigemptyset(&sa.sa_mask); 1125 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 1126 1127 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1128 FORKEE_ASSERT(raise(sigval) == 0); 1129 1130 _exit(exitval); 1131 } 1132 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1133 1134 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1135 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1136 1137 validate_status_stopped(status, sigval); 1138 1139 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1140 SYSCALL_REQUIRE( 1141 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1142 1143 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1144 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1145 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1146 info.psi_siginfo.si_errno); 1147 1148 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1149 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1150 1151 DPRINTF("Before resuming the child process where it left off and with " 1152 "signal %s to be sent\n", strsignal(sigsent)); 1153 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1154 1155 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1156 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1157 1158 validate_status_exited(status, exitval); 1159 1160 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1161 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1162 } 1163 1164 #define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 1165 ATF_TC(test); \ 1166 ATF_TC_HEAD(test, tc) \ 1167 { \ 1168 atf_tc_set_md_var(tc, "descr", \ 1169 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1170 "handled correctly and the signal is masked by SIG_IGN"); \ 1171 } \ 1172 \ 1173 ATF_TC_BODY(test, tc) \ 1174 { \ 1175 \ 1176 traceme_sendsignal_ignored(sig); \ 1177 } 1178 1179 // A signal handler for SIGKILL and SIGSTOP cannot be ignored. 1180 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 1181 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 1182 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 1183 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 1184 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 1185 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 1186 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 1187 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 1188 1189 /// ---------------------------------------------------------------------------- 1190 1191 static void 1192 traceme_sendsignal_simple(int sigsent) 1193 { 1194 const int sigval = SIGSTOP; 1195 int exitval = 0; 1196 pid_t child, wpid; 1197 #if defined(TWAIT_HAVE_STATUS) 1198 int status; 1199 int expect_core; 1200 1201 switch (sigsent) { 1202 case SIGABRT: 1203 case SIGTRAP: 1204 case SIGBUS: 1205 case SIGILL: 1206 case SIGFPE: 1207 case SIGSEGV: 1208 expect_core = 1; 1209 break; 1210 default: 1211 expect_core = 0; 1212 break; 1213 } 1214 #endif 1215 struct ptrace_siginfo info; 1216 1217 memset(&info, 0, sizeof(info)); 1218 1219 DPRINTF("Before forking process PID=%d\n", getpid()); 1220 SYSCALL_REQUIRE((child = fork()) != -1); 1221 if (child == 0) { 1222 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1223 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1224 1225 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1226 FORKEE_ASSERT(raise(sigval) == 0); 1227 1228 switch (sigsent) { 1229 case SIGCONT: 1230 case SIGSTOP: 1231 _exit(exitval); 1232 default: 1233 /* NOTREACHED */ 1234 FORKEE_ASSERTX(0 && "This shall not be reached"); 1235 } 1236 } 1237 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1238 1239 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1240 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1241 1242 validate_status_stopped(status, sigval); 1243 1244 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1245 SYSCALL_REQUIRE( 1246 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1247 1248 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1249 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1250 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1251 info.psi_siginfo.si_errno); 1252 1253 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1254 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1255 1256 DPRINTF("Before resuming the child process where it left off and with " 1257 "signal %s to be sent\n", strsignal(sigsent)); 1258 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1259 1260 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1262 1263 switch (sigsent) { 1264 case SIGSTOP: 1265 validate_status_stopped(status, sigsent); 1266 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1267 "child\n"); 1268 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1269 sizeof(info)) != -1); 1270 1271 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1272 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1273 "si_errno=%#x\n", 1274 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1275 info.psi_siginfo.si_errno); 1276 1277 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1278 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1279 1280 DPRINTF("Before resuming the child process where it left off " 1281 "and with signal %s to be sent\n", strsignal(sigsent)); 1282 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1283 1284 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1285 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1286 child); 1287 /* FALLTHROUGH */ 1288 case SIGCONT: 1289 validate_status_exited(status, exitval); 1290 break; 1291 default: 1292 validate_status_signaled(status, sigsent, expect_core); 1293 break; 1294 } 1295 1296 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1297 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1298 } 1299 1300 #define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 1301 ATF_TC(test); \ 1302 ATF_TC_HEAD(test, tc) \ 1303 { \ 1304 atf_tc_set_md_var(tc, "descr", \ 1305 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1306 "handled correctly in a child without a signal handler"); \ 1307 } \ 1308 \ 1309 ATF_TC_BODY(test, tc) \ 1310 { \ 1311 \ 1312 traceme_sendsignal_simple(sig); \ 1313 } 1314 1315 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 1316 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 1317 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 1318 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 1319 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 1320 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 1321 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 1322 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 1323 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 1324 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 1325 1326 /// ---------------------------------------------------------------------------- 1327 1328 ATF_TC(traceme_pid1_parent); 1329 ATF_TC_HEAD(traceme_pid1_parent, tc) 1330 { 1331 atf_tc_set_md_var(tc, "descr", 1332 "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 1333 } 1334 1335 ATF_TC_BODY(traceme_pid1_parent, tc) 1336 { 1337 struct msg_fds parent_child; 1338 int exitval_child1 = 1, exitval_child2 = 2; 1339 pid_t child1, child2, wpid; 1340 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1341 #if defined(TWAIT_HAVE_STATUS) 1342 int status; 1343 #endif 1344 1345 SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 1346 1347 DPRINTF("Before forking process PID=%d\n", getpid()); 1348 SYSCALL_REQUIRE((child1 = fork()) != -1); 1349 if (child1 == 0) { 1350 DPRINTF("Before forking process PID=%d\n", getpid()); 1351 SYSCALL_REQUIRE((child2 = fork()) != -1); 1352 if (child2 != 0) { 1353 DPRINTF("Parent process PID=%d, child2's PID=%d\n", 1354 getpid(), child2); 1355 _exit(exitval_child1); 1356 } 1357 CHILD_FROM_PARENT("exit child1", parent_child, msg); 1358 1359 DPRINTF("Assert that our parent is PID1 (initproc)\n"); 1360 FORKEE_ASSERT_EQ(getppid(), 1); 1361 1362 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1363 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 1364 SYSCALL_REQUIRE_ERRNO(errno, EPERM); 1365 1366 CHILD_TO_PARENT("child2 exiting", parent_child, msg); 1367 1368 _exit(exitval_child2); 1369 } 1370 DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 1371 1372 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1373 TWAIT_REQUIRE_SUCCESS( 1374 wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 1375 1376 validate_status_exited(status, exitval_child1); 1377 1378 DPRINTF("Notify that child1 is dead\n"); 1379 PARENT_TO_CHILD("exit child1", parent_child, msg); 1380 1381 DPRINTF("Wait for exiting of child2\n"); 1382 PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 1383 } 1384 1385 /// ---------------------------------------------------------------------------- 1386 1387 static void 1388 traceme_vfork_raise(int sigval) 1389 { 1390 const int exitval = 5, exitval_watcher = 10; 1391 pid_t child, parent, watcher, wpid; 1392 int rv; 1393 #if defined(TWAIT_HAVE_STATUS) 1394 int status; 1395 1396 /* volatile workarounds GCC -Werror=clobbered */ 1397 volatile int expect_core; 1398 1399 switch (sigval) { 1400 case SIGABRT: 1401 case SIGTRAP: 1402 case SIGBUS: 1403 case SIGILL: 1404 case SIGFPE: 1405 case SIGSEGV: 1406 expect_core = 1; 1407 break; 1408 default: 1409 expect_core = 0; 1410 break; 1411 } 1412 #endif 1413 1414 /* 1415 * Spawn a dedicated thread to watch for a stopped child and emit 1416 * the SIGKILL signal to it. 1417 * 1418 * vfork(2) might clobber watcher, this means that it's safer and 1419 * simpler to reparent this process to initproc and forget about it. 1420 */ 1421 if (sigval == SIGSTOP) { 1422 parent = getpid(); 1423 1424 watcher = fork(); 1425 ATF_REQUIRE(watcher != 1); 1426 if (watcher == 0) { 1427 /* Double fork(2) trick to reparent to initproc */ 1428 watcher = fork(); 1429 FORKEE_ASSERT_NEQ(watcher, -1); 1430 if (watcher != 0) 1431 _exit(exitval_watcher); 1432 1433 child = await_stopped_child(parent); 1434 1435 errno = 0; 1436 rv = kill(child, SIGKILL); 1437 FORKEE_ASSERT_EQ(rv, 0); 1438 FORKEE_ASSERT_EQ(errno, 0); 1439 1440 /* This exit value will be collected by initproc */ 1441 _exit(0); 1442 } 1443 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1444 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 1445 watcher); 1446 1447 validate_status_exited(status, exitval_watcher); 1448 1449 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1450 TWAIT_REQUIRE_FAILURE(ECHILD, 1451 wpid = TWAIT_GENERIC(watcher, &status, 0)); 1452 } 1453 1454 DPRINTF("Before forking process PID=%d\n", getpid()); 1455 SYSCALL_REQUIRE((child = vfork()) != -1); 1456 if (child == 0) { 1457 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1458 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1459 1460 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1461 FORKEE_ASSERT(raise(sigval) == 0); 1462 1463 switch (sigval) { 1464 case SIGSTOP: 1465 case SIGKILL: 1466 case SIGABRT: 1467 case SIGHUP: 1468 case SIGTRAP: 1469 case SIGBUS: 1470 case SIGILL: 1471 case SIGFPE: 1472 case SIGSEGV: 1473 /* NOTREACHED */ 1474 FORKEE_ASSERTX(0 && "This shall not be reached"); 1475 __unreachable(); 1476 default: 1477 DPRINTF("Before exiting of the child process\n"); 1478 _exit(exitval); 1479 } 1480 } 1481 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1482 1483 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1484 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1485 1486 switch (sigval) { 1487 case SIGKILL: 1488 case SIGABRT: 1489 case SIGHUP: 1490 case SIGTRAP: 1491 case SIGBUS: 1492 case SIGILL: 1493 case SIGFPE: 1494 case SIGSEGV: 1495 validate_status_signaled(status, sigval, expect_core); 1496 break; 1497 case SIGSTOP: 1498 validate_status_signaled(status, SIGKILL, 0); 1499 break; 1500 case SIGCONT: 1501 case SIGTSTP: 1502 case SIGTTIN: 1503 case SIGTTOU: 1504 validate_status_exited(status, exitval); 1505 break; 1506 default: 1507 /* NOTREACHED */ 1508 ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 1509 break; 1510 } 1511 1512 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1513 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1514 } 1515 1516 #define TRACEME_VFORK_RAISE(test, sig) \ 1517 ATF_TC(test); \ 1518 ATF_TC_HEAD(test, tc) \ 1519 { \ 1520 atf_tc_set_md_var(tc, "descr", \ 1521 "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 1522 "vfork(2)ed child"); \ 1523 } \ 1524 \ 1525 ATF_TC_BODY(test, tc) \ 1526 { \ 1527 \ 1528 traceme_vfork_raise(sig); \ 1529 } 1530 1531 TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 1532 TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 1533 TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 1534 TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 1535 TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 1536 TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 1537 TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 1538 TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 1539 TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 1540 TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 1541 TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 1542 TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 1543 TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 1544 1545 /// ---------------------------------------------------------------------------- 1546 1547 static void 1548 traceme_vfork_crash(int sig) 1549 { 1550 pid_t child, wpid; 1551 #if defined(TWAIT_HAVE_STATUS) 1552 int status; 1553 #endif 1554 1555 #ifndef PTRACE_ILLEGAL_ASM 1556 if (sig == SIGILL) 1557 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1558 #endif 1559 1560 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1561 atf_tc_skip("FP exceptions are not supported"); 1562 1563 DPRINTF("Before forking process PID=%d\n", getpid()); 1564 SYSCALL_REQUIRE((child = vfork()) != -1); 1565 if (child == 0) { 1566 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1567 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1568 1569 DPRINTF("Before executing a trap\n"); 1570 switch (sig) { 1571 case SIGTRAP: 1572 trigger_trap(); 1573 break; 1574 case SIGSEGV: 1575 trigger_segv(); 1576 break; 1577 case SIGILL: 1578 trigger_ill(); 1579 break; 1580 case SIGFPE: 1581 trigger_fpe(); 1582 break; 1583 case SIGBUS: 1584 trigger_bus(); 1585 break; 1586 default: 1587 /* NOTREACHED */ 1588 FORKEE_ASSERTX(0 && "This shall not be reached"); 1589 } 1590 1591 /* NOTREACHED */ 1592 FORKEE_ASSERTX(0 && "This shall not be reached"); 1593 } 1594 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1595 1596 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1597 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1598 1599 validate_status_signaled(status, sig, 1); 1600 1601 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1602 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1603 } 1604 1605 #define TRACEME_VFORK_CRASH(test, sig) \ 1606 ATF_TC(test); \ 1607 ATF_TC_HEAD(test, tc) \ 1608 { \ 1609 atf_tc_set_md_var(tc, "descr", \ 1610 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1611 "vfork(2)ed child"); \ 1612 } \ 1613 \ 1614 ATF_TC_BODY(test, tc) \ 1615 { \ 1616 \ 1617 traceme_vfork_crash(sig); \ 1618 } 1619 1620 TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 1621 TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 1622 TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 1623 TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 1624 TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 1625 1626 /// ---------------------------------------------------------------------------- 1627 1628 static void 1629 traceme_vfork_signalmasked_crash(int sig) 1630 { 1631 pid_t child, wpid; 1632 #if defined(TWAIT_HAVE_STATUS) 1633 int status; 1634 #endif 1635 sigset_t intmask; 1636 1637 #ifndef PTRACE_ILLEGAL_ASM 1638 if (sig == SIGILL) 1639 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1640 #endif 1641 1642 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1643 atf_tc_skip("FP exceptions are not supported"); 1644 1645 DPRINTF("Before forking process PID=%d\n", getpid()); 1646 SYSCALL_REQUIRE((child = vfork()) != -1); 1647 if (child == 0) { 1648 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1649 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1650 1651 sigemptyset(&intmask); 1652 sigaddset(&intmask, sig); 1653 sigprocmask(SIG_BLOCK, &intmask, NULL); 1654 1655 DPRINTF("Before executing a trap\n"); 1656 switch (sig) { 1657 case SIGTRAP: 1658 trigger_trap(); 1659 break; 1660 case SIGSEGV: 1661 trigger_segv(); 1662 break; 1663 case SIGILL: 1664 trigger_ill(); 1665 break; 1666 case SIGFPE: 1667 trigger_fpe(); 1668 break; 1669 case SIGBUS: 1670 trigger_bus(); 1671 break; 1672 default: 1673 /* NOTREACHED */ 1674 FORKEE_ASSERTX(0 && "This shall not be reached"); 1675 } 1676 1677 /* NOTREACHED */ 1678 FORKEE_ASSERTX(0 && "This shall not be reached"); 1679 } 1680 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1681 1682 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1683 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1684 1685 validate_status_signaled(status, sig, 1); 1686 1687 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1688 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1689 } 1690 1691 #define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig) \ 1692 ATF_TC(test); \ 1693 ATF_TC_HEAD(test, tc) \ 1694 { \ 1695 atf_tc_set_md_var(tc, "descr", \ 1696 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1697 "vfork(2)ed child with a masked signal"); \ 1698 } \ 1699 \ 1700 ATF_TC_BODY(test, tc) \ 1701 { \ 1702 \ 1703 traceme_vfork_signalmasked_crash(sig); \ 1704 } 1705 1706 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP) 1707 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV) 1708 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL) 1709 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE) 1710 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS) 1711 1712 /// ---------------------------------------------------------------------------- 1713 1714 static void 1715 traceme_vfork_signalignored_crash(int sig) 1716 { 1717 pid_t child, wpid; 1718 #if defined(TWAIT_HAVE_STATUS) 1719 int status; 1720 #endif 1721 struct sigaction sa; 1722 1723 #ifndef PTRACE_ILLEGAL_ASM 1724 if (sig == SIGILL) 1725 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1726 #endif 1727 1728 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1729 atf_tc_skip("FP exceptions are not supported"); 1730 1731 DPRINTF("Before forking process PID=%d\n", getpid()); 1732 SYSCALL_REQUIRE((child = vfork()) != -1); 1733 if (child == 0) { 1734 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1735 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1736 1737 memset(&sa, 0, sizeof(sa)); 1738 sa.sa_handler = SIG_IGN; 1739 sigemptyset(&sa.sa_mask); 1740 1741 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 1742 1743 DPRINTF("Before executing a trap\n"); 1744 switch (sig) { 1745 case SIGTRAP: 1746 trigger_trap(); 1747 break; 1748 case SIGSEGV: 1749 trigger_segv(); 1750 break; 1751 case SIGILL: 1752 trigger_ill(); 1753 break; 1754 case SIGFPE: 1755 trigger_fpe(); 1756 break; 1757 case SIGBUS: 1758 trigger_bus(); 1759 break; 1760 default: 1761 /* NOTREACHED */ 1762 FORKEE_ASSERTX(0 && "This shall not be reached"); 1763 } 1764 1765 /* NOTREACHED */ 1766 FORKEE_ASSERTX(0 && "This shall not be reached"); 1767 } 1768 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1769 1770 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1771 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1772 1773 validate_status_signaled(status, sig, 1); 1774 1775 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1776 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1777 } 1778 1779 #define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig) \ 1780 ATF_TC(test); \ 1781 ATF_TC_HEAD(test, tc) \ 1782 { \ 1783 atf_tc_set_md_var(tc, "descr", \ 1784 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1785 "vfork(2)ed child with ignored signal"); \ 1786 } \ 1787 \ 1788 ATF_TC_BODY(test, tc) \ 1789 { \ 1790 \ 1791 traceme_vfork_signalignored_crash(sig); \ 1792 } 1793 1794 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap, 1795 SIGTRAP) 1796 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv, 1797 SIGSEGV) 1798 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill, 1799 SIGILL) 1800 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe, 1801 SIGFPE) 1802 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus, 1803 SIGBUS) 1804 1805 /// ---------------------------------------------------------------------------- 1806 1807 static void 1808 traceme_vfork_exec(bool masked, bool ignored) 1809 { 1810 const int sigval = SIGTRAP; 1811 pid_t child, wpid; 1812 #if defined(TWAIT_HAVE_STATUS) 1813 int status; 1814 #endif 1815 struct sigaction sa; 1816 struct ptrace_siginfo info; 1817 sigset_t intmask; 1818 struct kinfo_proc2 kp; 1819 size_t len = sizeof(kp); 1820 1821 int name[6]; 1822 const size_t namelen = __arraycount(name); 1823 ki_sigset_t kp_sigmask; 1824 ki_sigset_t kp_sigignore; 1825 1826 memset(&info, 0, sizeof(info)); 1827 1828 DPRINTF("Before forking process PID=%d\n", getpid()); 1829 SYSCALL_REQUIRE((child = vfork()) != -1); 1830 if (child == 0) { 1831 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1832 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1833 1834 if (masked) { 1835 sigemptyset(&intmask); 1836 sigaddset(&intmask, sigval); 1837 sigprocmask(SIG_BLOCK, &intmask, NULL); 1838 } 1839 1840 if (ignored) { 1841 memset(&sa, 0, sizeof(sa)); 1842 sa.sa_handler = SIG_IGN; 1843 sigemptyset(&sa.sa_mask); 1844 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 1845 } 1846 1847 DPRINTF("Before calling execve(2) from child\n"); 1848 execlp("/bin/echo", "/bin/echo", NULL); 1849 1850 /* NOTREACHED */ 1851 FORKEE_ASSERTX(0 && "Not reached"); 1852 } 1853 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1854 1855 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1856 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1857 1858 validate_status_stopped(status, sigval); 1859 1860 name[0] = CTL_KERN, 1861 name[1] = KERN_PROC2, 1862 name[2] = KERN_PROC_PID; 1863 name[3] = getpid(); 1864 name[4] = sizeof(kp); 1865 name[5] = 1; 1866 1867 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1868 1869 if (masked) 1870 kp_sigmask = kp.p_sigmask; 1871 1872 if (ignored) 1873 kp_sigignore = kp.p_sigignore; 1874 1875 name[3] = getpid(); 1876 1877 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1878 1879 if (masked) { 1880 DPRINTF("kp_sigmask=" 1881 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1882 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1883 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1884 1885 DPRINTF("kp.p_sigmask=" 1886 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1887 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1888 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1889 1890 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 1891 sizeof(kp_sigmask))); 1892 } 1893 1894 if (ignored) { 1895 DPRINTF("kp_sigignore=" 1896 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1897 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1898 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1899 1900 DPRINTF("kp.p_sigignore=" 1901 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1902 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1903 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1904 1905 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 1906 sizeof(kp_sigignore))); 1907 } 1908 1909 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1910 SYSCALL_REQUIRE( 1911 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1912 1913 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1914 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1915 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1916 info.psi_siginfo.si_errno); 1917 1918 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1919 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1920 1921 DPRINTF("Before resuming the child process where it left off and " 1922 "without signal to be sent\n"); 1923 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1924 1925 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1926 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1927 1928 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1929 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1930 } 1931 1932 #define TRACEME_VFORK_EXEC(test, masked, ignored) \ 1933 ATF_TC(test); \ 1934 ATF_TC_HEAD(test, tc) \ 1935 { \ 1936 atf_tc_set_md_var(tc, "descr", \ 1937 "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed " \ 1938 "child%s%s", masked ? " with masked signal" : "", \ 1939 masked ? " with ignored signal" : ""); \ 1940 } \ 1941 \ 1942 ATF_TC_BODY(test, tc) \ 1943 { \ 1944 \ 1945 traceme_vfork_exec(masked, ignored); \ 1946 } 1947 1948 TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false) 1949 TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false) 1950 TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true) 1951 1952 /// ---------------------------------------------------------------------------- 1953 1954 #if defined(TWAIT_HAVE_PID) 1955 static void 1956 unrelated_tracer_sees_crash(int sig, bool masked, bool ignored) 1957 { 1958 const int sigval = SIGSTOP; 1959 struct msg_fds parent_tracee, parent_tracer; 1960 const int exitval = 10; 1961 pid_t tracee, tracer, wpid; 1962 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1963 #if defined(TWAIT_HAVE_STATUS) 1964 int status; 1965 #endif 1966 struct sigaction sa; 1967 struct ptrace_siginfo info; 1968 sigset_t intmask; 1969 struct kinfo_proc2 kp; 1970 size_t len = sizeof(kp); 1971 1972 int name[6]; 1973 const size_t namelen = __arraycount(name); 1974 ki_sigset_t kp_sigmask; 1975 ki_sigset_t kp_sigignore; 1976 1977 #ifndef PTRACE_ILLEGAL_ASM 1978 if (sig == SIGILL) 1979 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1980 #endif 1981 1982 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1983 atf_tc_skip("FP exceptions are not supported"); 1984 1985 memset(&info, 0, sizeof(info)); 1986 1987 DPRINTF("Spawn tracee\n"); 1988 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1989 tracee = atf_utils_fork(); 1990 if (tracee == 0) { 1991 // Wait for parent to let us crash 1992 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 1993 1994 if (masked) { 1995 sigemptyset(&intmask); 1996 sigaddset(&intmask, sig); 1997 sigprocmask(SIG_BLOCK, &intmask, NULL); 1998 } 1999 2000 if (ignored) { 2001 memset(&sa, 0, sizeof(sa)); 2002 sa.sa_handler = SIG_IGN; 2003 sigemptyset(&sa.sa_mask); 2004 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 2005 } 2006 2007 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2008 FORKEE_ASSERT(raise(sigval) == 0); 2009 2010 DPRINTF("Before executing a trap\n"); 2011 switch (sig) { 2012 case SIGTRAP: 2013 trigger_trap(); 2014 break; 2015 case SIGSEGV: 2016 trigger_segv(); 2017 break; 2018 case SIGILL: 2019 trigger_ill(); 2020 break; 2021 case SIGFPE: 2022 trigger_fpe(); 2023 break; 2024 case SIGBUS: 2025 trigger_bus(); 2026 break; 2027 default: 2028 /* NOTREACHED */ 2029 FORKEE_ASSERTX(0 && "This shall not be reached"); 2030 } 2031 2032 /* NOTREACHED */ 2033 FORKEE_ASSERTX(0 && "This shall not be reached"); 2034 } 2035 2036 DPRINTF("Spawn debugger\n"); 2037 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2038 tracer = atf_utils_fork(); 2039 if (tracer == 0) { 2040 /* Fork again and drop parent to reattach to PID 1 */ 2041 tracer = atf_utils_fork(); 2042 if (tracer != 0) 2043 _exit(exitval); 2044 2045 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2046 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2047 2048 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2049 FORKEE_REQUIRE_SUCCESS( 2050 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2051 2052 forkee_status_stopped(status, SIGSTOP); 2053 2054 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2055 "traced process\n"); 2056 SYSCALL_REQUIRE( 2057 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2058 2059 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2060 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2061 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2062 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2063 2064 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 2065 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 2066 2067 /* Resume tracee with PT_CONTINUE */ 2068 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2069 2070 /* Inform parent that tracer has attached to tracee */ 2071 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2072 2073 /* Wait for parent to tell use that tracee should have exited */ 2074 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2075 2076 /* Wait for tracee and assert that it exited */ 2077 FORKEE_REQUIRE_SUCCESS( 2078 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2079 2080 forkee_status_stopped(status, sigval); 2081 2082 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2083 "traced process\n"); 2084 SYSCALL_REQUIRE( 2085 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2086 2087 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2088 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2089 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2090 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2091 2092 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 2093 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 2094 2095 name[0] = CTL_KERN, 2096 name[1] = KERN_PROC2, 2097 name[2] = KERN_PROC_PID; 2098 name[3] = tracee; 2099 name[4] = sizeof(kp); 2100 name[5] = 1; 2101 2102 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2103 2104 if (masked) 2105 kp_sigmask = kp.p_sigmask; 2106 2107 if (ignored) 2108 kp_sigignore = kp.p_sigignore; 2109 2110 /* Resume tracee with PT_CONTINUE */ 2111 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2112 2113 /* Wait for tracee and assert that it exited */ 2114 FORKEE_REQUIRE_SUCCESS( 2115 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2116 2117 forkee_status_stopped(status, sig); 2118 2119 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2120 "traced process\n"); 2121 SYSCALL_REQUIRE( 2122 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2123 2124 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2125 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2126 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2127 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2128 2129 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig); 2130 2131 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2132 2133 if (masked) { 2134 DPRINTF("kp_sigmask=" 2135 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2136 PRIx32 "\n", 2137 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 2138 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 2139 2140 DPRINTF("kp.p_sigmask=" 2141 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2142 PRIx32 "\n", 2143 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 2144 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 2145 2146 FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask, 2147 sizeof(kp_sigmask))); 2148 } 2149 2150 if (ignored) { 2151 DPRINTF("kp_sigignore=" 2152 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2153 PRIx32 "\n", 2154 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 2155 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 2156 2157 DPRINTF("kp.p_sigignore=" 2158 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2159 PRIx32 "\n", 2160 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 2161 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 2162 2163 FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore, 2164 sizeof(kp_sigignore))); 2165 } 2166 2167 switch (sig) { 2168 case SIGTRAP: 2169 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 2170 break; 2171 case SIGSEGV: 2172 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 2173 break; 2174 case SIGILL: 2175 FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC && 2176 info.psi_siginfo.si_code <= ILL_BADSTK); 2177 break; 2178 case SIGFPE: 2179 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 2180 break; 2181 case SIGBUS: 2182 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 2183 break; 2184 } 2185 2186 FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 2187 DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 2188 FORKEE_REQUIRE_SUCCESS( 2189 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2190 2191 forkee_status_signaled(status, SIGKILL, 0); 2192 2193 /* Inform parent that tracer is exiting normally */ 2194 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 2195 2196 DPRINTF("Before exiting of the tracer process\n"); 2197 _exit(0 /* collect by initproc */); 2198 } 2199 2200 DPRINTF("Wait for the tracer process (direct child) to exit " 2201 "calling %s()\n", TWAIT_FNAME); 2202 TWAIT_REQUIRE_SUCCESS( 2203 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2204 2205 validate_status_exited(status, exitval); 2206 2207 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2208 TWAIT_FNAME); 2209 TWAIT_REQUIRE_SUCCESS( 2210 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2211 2212 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2213 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2214 2215 DPRINTF("Resume the tracee and let it crash\n"); 2216 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2217 2218 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 2219 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2220 2221 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2222 TWAIT_FNAME); 2223 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2224 2225 validate_status_signaled(status, SIGKILL, 0); 2226 2227 DPRINTF("Await normal exit of tracer\n"); 2228 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 2229 2230 msg_close(&parent_tracer); 2231 msg_close(&parent_tracee); 2232 } 2233 2234 #define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 2235 ATF_TC(test); \ 2236 ATF_TC_HEAD(test, tc) \ 2237 { \ 2238 atf_tc_set_md_var(tc, "descr", \ 2239 "Assert that an unrelated tracer sees crash signal from " \ 2240 "the debuggee"); \ 2241 } \ 2242 \ 2243 ATF_TC_BODY(test, tc) \ 2244 { \ 2245 \ 2246 unrelated_tracer_sees_crash(sig, false, false); \ 2247 } 2248 2249 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 2250 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 2251 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 2252 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 2253 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 2254 2255 #define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig) \ 2256 ATF_TC(test); \ 2257 ATF_TC_HEAD(test, tc) \ 2258 { \ 2259 atf_tc_set_md_var(tc, "descr", \ 2260 "Assert that an unrelated tracer sees crash signal from " \ 2261 "the debuggee with masked signal"); \ 2262 } \ 2263 \ 2264 ATF_TC_BODY(test, tc) \ 2265 { \ 2266 \ 2267 unrelated_tracer_sees_crash(sig, true, false); \ 2268 } 2269 2270 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2271 unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP) 2272 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2273 unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV) 2274 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2275 unrelated_tracer_sees_signalmasked_crash_ill, SIGILL) 2276 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2277 unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE) 2278 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2279 unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS) 2280 2281 #define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig) \ 2282 ATF_TC(test); \ 2283 ATF_TC_HEAD(test, tc) \ 2284 { \ 2285 atf_tc_set_md_var(tc, "descr", \ 2286 "Assert that an unrelated tracer sees crash signal from " \ 2287 "the debuggee with signal ignored"); \ 2288 } \ 2289 \ 2290 ATF_TC_BODY(test, tc) \ 2291 { \ 2292 \ 2293 unrelated_tracer_sees_crash(sig, false, true); \ 2294 } 2295 2296 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2297 unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP) 2298 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2299 unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV) 2300 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2301 unrelated_tracer_sees_signalignored_crash_ill, SIGILL) 2302 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2303 unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE) 2304 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2305 unrelated_tracer_sees_signalignored_crash_bus, SIGBUS) 2306 #endif 2307 2308 /// ---------------------------------------------------------------------------- 2309 2310 #if defined(TWAIT_HAVE_PID) 2311 static void 2312 tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 2313 bool stopped) 2314 { 2315 /* 2316 * notimeout - disable timeout in await zombie function 2317 * unrelated - attach from unrelated tracer reparented to initproc 2318 * stopped - attach to a stopped process 2319 */ 2320 2321 struct msg_fds parent_tracee, parent_tracer; 2322 const int exitval_tracee = 5; 2323 const int exitval_tracer = 10; 2324 pid_t tracee, tracer, wpid; 2325 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2326 #if defined(TWAIT_HAVE_STATUS) 2327 int status; 2328 #endif 2329 2330 /* 2331 * Only a subset of options are supported. 2332 */ 2333 ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 2334 (!notimeout && unrelated && !stopped) || 2335 (notimeout && !unrelated && !stopped) || 2336 (!notimeout && unrelated && stopped)); 2337 2338 DPRINTF("Spawn tracee\n"); 2339 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2340 tracee = atf_utils_fork(); 2341 if (tracee == 0) { 2342 if (stopped) { 2343 DPRINTF("Stop self PID %d\n", getpid()); 2344 raise(SIGSTOP); 2345 } 2346 2347 // Wait for parent to let us exit 2348 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2349 _exit(exitval_tracee); 2350 } 2351 2352 DPRINTF("Spawn debugger\n"); 2353 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2354 tracer = atf_utils_fork(); 2355 if (tracer == 0) { 2356 if(unrelated) { 2357 /* Fork again and drop parent to reattach to PID 1 */ 2358 tracer = atf_utils_fork(); 2359 if (tracer != 0) 2360 _exit(exitval_tracer); 2361 } 2362 2363 if (stopped) { 2364 DPRINTF("Await for a stopped parent PID %d\n", tracee); 2365 await_stopped(tracee); 2366 } 2367 2368 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2369 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2370 2371 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2372 FORKEE_REQUIRE_SUCCESS( 2373 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2374 2375 forkee_status_stopped(status, SIGSTOP); 2376 2377 /* Resume tracee with PT_CONTINUE */ 2378 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2379 2380 /* Inform parent that tracer has attached to tracee */ 2381 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2382 2383 /* Wait for parent to tell use that tracee should have exited */ 2384 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2385 2386 /* Wait for tracee and assert that it exited */ 2387 FORKEE_REQUIRE_SUCCESS( 2388 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2389 2390 forkee_status_exited(status, exitval_tracee); 2391 DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 2392 2393 DPRINTF("Before exiting of the tracer process\n"); 2394 _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 2395 } 2396 2397 if (unrelated) { 2398 DPRINTF("Wait for the tracer process (direct child) to exit " 2399 "calling %s()\n", TWAIT_FNAME); 2400 TWAIT_REQUIRE_SUCCESS( 2401 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2402 2403 validate_status_exited(status, exitval_tracer); 2404 2405 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2406 TWAIT_FNAME); 2407 TWAIT_REQUIRE_SUCCESS( 2408 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2409 } 2410 2411 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2412 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2413 2414 DPRINTF("Resume the tracee and let it exit\n"); 2415 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2416 2417 DPRINTF("Detect that tracee is zombie\n"); 2418 if (notimeout) 2419 await_zombie_raw(tracee, 0); 2420 else 2421 await_zombie(tracee); 2422 2423 DPRINTF("Assert that there is no status about tracee %d - " 2424 "Tracer must detect zombie first - calling %s()\n", tracee, 2425 TWAIT_FNAME); 2426 TWAIT_REQUIRE_SUCCESS( 2427 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2428 2429 if (unrelated) { 2430 DPRINTF("Resume the tracer and let it detect exited tracee\n"); 2431 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2432 } else { 2433 DPRINTF("Tell the tracer child should have exited\n"); 2434 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2435 DPRINTF("Wait for tracer to finish its job and exit - calling " 2436 "%s()\n", TWAIT_FNAME); 2437 2438 DPRINTF("Wait from tracer child to complete waiting for " 2439 "tracee\n"); 2440 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2441 tracer); 2442 2443 validate_status_exited(status, exitval_tracer); 2444 } 2445 2446 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2447 TWAIT_FNAME); 2448 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2449 2450 validate_status_exited(status, exitval_tracee); 2451 2452 msg_close(&parent_tracer); 2453 msg_close(&parent_tracee); 2454 } 2455 2456 ATF_TC(tracer_sees_terminaton_before_the_parent); 2457 ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 2458 { 2459 atf_tc_set_md_var(tc, "descr", 2460 "Assert that tracer sees process termination before the parent"); 2461 } 2462 2463 ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 2464 { 2465 2466 tracer_sees_terminaton_before_the_parent_raw(false, false, false); 2467 } 2468 2469 ATF_TC(tracer_sysctl_lookup_without_duplicates); 2470 ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 2471 { 2472 atf_tc_set_md_var(tc, "timeout", "15"); 2473 atf_tc_set_md_var(tc, "descr", 2474 "Assert that await_zombie() in attach1 always finds a single " 2475 "process and no other error is reported"); 2476 } 2477 2478 ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 2479 { 2480 time_t start, end; 2481 double diff; 2482 unsigned long N = 0; 2483 2484 /* 2485 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 2486 * This test body isn't specific to this race, however it's just good 2487 * enough for this purposes, no need to invent a dedicated code flow. 2488 */ 2489 2490 start = time(NULL); 2491 while (true) { 2492 DPRINTF("Step: %lu\n", N); 2493 tracer_sees_terminaton_before_the_parent_raw(true, false, 2494 false); 2495 end = time(NULL); 2496 diff = difftime(end, start); 2497 if (diff >= 5.0) 2498 break; 2499 ++N; 2500 } 2501 DPRINTF("Iterations: %lu\n", N); 2502 } 2503 2504 ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 2505 ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2506 { 2507 atf_tc_set_md_var(tc, "descr", 2508 "Assert that tracer sees process termination before the parent"); 2509 } 2510 2511 ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2512 { 2513 2514 tracer_sees_terminaton_before_the_parent_raw(false, true, false); 2515 } 2516 2517 ATF_TC(tracer_attach_to_unrelated_stopped_process); 2518 ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 2519 { 2520 atf_tc_set_md_var(tc, "descr", 2521 "Assert that tracer can attach to an unrelated stopped process"); 2522 } 2523 2524 ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 2525 { 2526 2527 tracer_sees_terminaton_before_the_parent_raw(false, true, true); 2528 } 2529 #endif 2530 2531 /// ---------------------------------------------------------------------------- 2532 2533 static void 2534 parent_attach_to_its_child(bool stopped) 2535 { 2536 struct msg_fds parent_tracee; 2537 const int exitval_tracee = 5; 2538 pid_t tracee, wpid; 2539 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2540 #if defined(TWAIT_HAVE_STATUS) 2541 int status; 2542 #endif 2543 2544 DPRINTF("Spawn tracee\n"); 2545 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2546 tracee = atf_utils_fork(); 2547 if (tracee == 0) { 2548 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2549 DPRINTF("Parent should now attach to tracee\n"); 2550 2551 if (stopped) { 2552 DPRINTF("Stop self PID %d\n", getpid()); 2553 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2554 } 2555 2556 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 2557 /* Wait for message from the parent */ 2558 _exit(exitval_tracee); 2559 } 2560 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2561 2562 if (stopped) { 2563 DPRINTF("Await for a stopped tracee PID %d\n", tracee); 2564 await_stopped(tracee); 2565 } 2566 2567 DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 2568 SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2569 2570 DPRINTF("Wait for the stopped tracee process with %s()\n", 2571 TWAIT_FNAME); 2572 TWAIT_REQUIRE_SUCCESS( 2573 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2574 2575 validate_status_stopped(status, SIGSTOP); 2576 2577 DPRINTF("Resume tracee with PT_CONTINUE\n"); 2578 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2579 2580 DPRINTF("Let the tracee exit now\n"); 2581 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 2582 2583 DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 2584 TWAIT_REQUIRE_SUCCESS( 2585 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2586 2587 validate_status_exited(status, exitval_tracee); 2588 2589 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 2590 TWAIT_REQUIRE_FAILURE(ECHILD, 2591 wpid = TWAIT_GENERIC(tracee, &status, 0)); 2592 2593 msg_close(&parent_tracee); 2594 } 2595 2596 ATF_TC(parent_attach_to_its_child); 2597 ATF_TC_HEAD(parent_attach_to_its_child, tc) 2598 { 2599 atf_tc_set_md_var(tc, "descr", 2600 "Assert that tracer parent can PT_ATTACH to its child"); 2601 } 2602 2603 ATF_TC_BODY(parent_attach_to_its_child, tc) 2604 { 2605 2606 parent_attach_to_its_child(false); 2607 } 2608 2609 ATF_TC(parent_attach_to_its_stopped_child); 2610 ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 2611 { 2612 atf_tc_set_md_var(tc, "descr", 2613 "Assert that tracer parent can PT_ATTACH to its stopped child"); 2614 } 2615 2616 ATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 2617 { 2618 2619 parent_attach_to_its_child(true); 2620 } 2621 2622 /// ---------------------------------------------------------------------------- 2623 2624 static void 2625 child_attach_to_its_parent(bool stopped) 2626 { 2627 struct msg_fds parent_tracee; 2628 const int exitval_tracer = 5; 2629 pid_t tracer, wpid; 2630 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2631 #if defined(TWAIT_HAVE_STATUS) 2632 int status; 2633 #endif 2634 2635 DPRINTF("Spawn tracer\n"); 2636 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2637 tracer = atf_utils_fork(); 2638 if (tracer == 0) { 2639 /* Wait for message from the parent */ 2640 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2641 2642 if (stopped) { 2643 DPRINTF("Await for a stopped parent PID %d\n", 2644 getppid()); 2645 await_stopped(getppid()); 2646 } 2647 2648 DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 2649 getppid()); 2650 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 2651 2652 DPRINTF("Wait for the stopped parent process with %s()\n", 2653 TWAIT_FNAME); 2654 FORKEE_REQUIRE_SUCCESS( 2655 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 2656 2657 forkee_status_stopped(status, SIGSTOP); 2658 2659 DPRINTF("Resume parent with PT_DETACH\n"); 2660 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 2661 != -1); 2662 2663 /* Tell parent we are ready */ 2664 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 2665 2666 _exit(exitval_tracer); 2667 } 2668 2669 DPRINTF("Wait for the tracer to become ready\n"); 2670 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2671 2672 if (stopped) { 2673 DPRINTF("Stop self PID %d\n", getpid()); 2674 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2675 } 2676 2677 DPRINTF("Allow the tracer to exit now\n"); 2678 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 2679 2680 DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 2681 TWAIT_REQUIRE_SUCCESS( 2682 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2683 2684 validate_status_exited(status, exitval_tracer); 2685 2686 DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 2687 TWAIT_REQUIRE_FAILURE(ECHILD, 2688 wpid = TWAIT_GENERIC(tracer, &status, 0)); 2689 2690 msg_close(&parent_tracee); 2691 } 2692 2693 ATF_TC(child_attach_to_its_parent); 2694 ATF_TC_HEAD(child_attach_to_its_parent, tc) 2695 { 2696 atf_tc_set_md_var(tc, "descr", 2697 "Assert that tracer child can PT_ATTACH to its parent"); 2698 } 2699 2700 ATF_TC_BODY(child_attach_to_its_parent, tc) 2701 { 2702 2703 child_attach_to_its_parent(false); 2704 } 2705 2706 ATF_TC(child_attach_to_its_stopped_parent); 2707 ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 2708 { 2709 atf_tc_set_md_var(tc, "descr", 2710 "Assert that tracer child can PT_ATTACH to its stopped parent"); 2711 } 2712 2713 ATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 2714 { 2715 /* 2716 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 2717 * this causes a pipe (established from atf-run) to be broken. 2718 * atf-run uses this mechanism to monitor whether a test is alive. 2719 * 2720 * As a workaround spawn this test as a subprocess. 2721 */ 2722 2723 const int exitval = 15; 2724 pid_t child, wpid; 2725 #if defined(TWAIT_HAVE_STATUS) 2726 int status; 2727 #endif 2728 2729 SYSCALL_REQUIRE((child = fork()) != -1); 2730 if (child == 0) { 2731 child_attach_to_its_parent(true); 2732 _exit(exitval); 2733 } else { 2734 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2735 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2736 2737 validate_status_exited(status, exitval); 2738 2739 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 2740 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2741 } 2742 } 2743 2744 /// ---------------------------------------------------------------------------- 2745 2746 #if defined(TWAIT_HAVE_PID) 2747 2748 enum tracee_sees_its_original_parent_type { 2749 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2750 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2751 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 2752 }; 2753 2754 static void 2755 tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 2756 { 2757 struct msg_fds parent_tracer, parent_tracee; 2758 const int exitval_tracee = 5; 2759 const int exitval_tracer = 10; 2760 pid_t parent, tracee, tracer, wpid; 2761 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2762 #if defined(TWAIT_HAVE_STATUS) 2763 int status; 2764 #endif 2765 /* sysctl(3) - kinfo_proc2 */ 2766 int name[CTL_MAXNAME]; 2767 struct kinfo_proc2 kp; 2768 size_t len = sizeof(kp); 2769 unsigned int namelen; 2770 2771 /* procfs - status */ 2772 FILE *fp; 2773 struct stat st; 2774 const char *fname = "/proc/curproc/status"; 2775 char s_executable[MAXPATHLEN]; 2776 int s_pid, s_ppid; 2777 int rv; 2778 2779 if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 2780 SYSCALL_REQUIRE( 2781 (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 2782 if (rv != 0) 2783 atf_tc_skip("/proc/curproc/status not found"); 2784 } 2785 2786 DPRINTF("Spawn tracee\n"); 2787 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2788 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2789 tracee = atf_utils_fork(); 2790 if (tracee == 0) { 2791 parent = getppid(); 2792 2793 /* Emit message to the parent */ 2794 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 2795 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2796 2797 switch (type) { 2798 case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 2799 FORKEE_ASSERT_EQ(parent, getppid()); 2800 break; 2801 case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 2802 namelen = 0; 2803 name[namelen++] = CTL_KERN; 2804 name[namelen++] = KERN_PROC2; 2805 name[namelen++] = KERN_PROC_PID; 2806 name[namelen++] = getpid(); 2807 name[namelen++] = len; 2808 name[namelen++] = 1; 2809 2810 FORKEE_ASSERT_EQ( 2811 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2812 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 2813 break; 2814 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 2815 /* 2816 * Format: 2817 * EXECUTABLE PID PPID ... 2818 */ 2819 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 2820 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 2821 FORKEE_ASSERT_EQ(fclose(fp), 0); 2822 FORKEE_ASSERT_EQ(parent, s_ppid); 2823 break; 2824 } 2825 2826 _exit(exitval_tracee); 2827 } 2828 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 2829 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 2830 2831 DPRINTF("Spawn debugger\n"); 2832 tracer = atf_utils_fork(); 2833 if (tracer == 0) { 2834 /* No IPC to communicate with the child */ 2835 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2836 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2837 2838 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2839 FORKEE_REQUIRE_SUCCESS( 2840 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2841 2842 forkee_status_stopped(status, SIGSTOP); 2843 2844 /* Resume tracee with PT_CONTINUE */ 2845 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2846 2847 /* Inform parent that tracer has attached to tracee */ 2848 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2849 2850 /* Wait for parent to tell use that tracee should have exited */ 2851 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2852 2853 /* Wait for tracee and assert that it exited */ 2854 FORKEE_REQUIRE_SUCCESS( 2855 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2856 2857 forkee_status_exited(status, exitval_tracee); 2858 2859 DPRINTF("Before exiting of the tracer process\n"); 2860 _exit(exitval_tracer); 2861 } 2862 2863 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2864 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2865 2866 DPRINTF("Resume the tracee and let it exit\n"); 2867 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2868 2869 DPRINTF("Detect that tracee is zombie\n"); 2870 await_zombie(tracee); 2871 2872 DPRINTF("Assert that there is no status about tracee - " 2873 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 2874 TWAIT_REQUIRE_SUCCESS( 2875 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2876 2877 DPRINTF("Tell the tracer child should have exited\n"); 2878 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2879 2880 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 2881 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2882 tracer); 2883 2884 validate_status_exited(status, exitval_tracer); 2885 2886 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2887 TWAIT_FNAME); 2888 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 2889 tracee); 2890 2891 validate_status_exited(status, exitval_tracee); 2892 2893 msg_close(&parent_tracer); 2894 msg_close(&parent_tracee); 2895 } 2896 2897 #define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 2898 ATF_TC(test); \ 2899 ATF_TC_HEAD(test, tc) \ 2900 { \ 2901 atf_tc_set_md_var(tc, "descr", \ 2902 "Assert that tracee sees its original parent when being traced " \ 2903 "(check " descr ")"); \ 2904 } \ 2905 \ 2906 ATF_TC_BODY(test, tc) \ 2907 { \ 2908 \ 2909 tracee_sees_its_original_parent(type); \ 2910 } 2911 2912 TRACEE_SEES_ITS_ORIGINAL_PARENT( 2913 tracee_sees_its_original_parent_getppid, 2914 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2915 "getppid(2)"); 2916 TRACEE_SEES_ITS_ORIGINAL_PARENT( 2917 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 2918 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2919 "sysctl(3) and kinfo_proc2"); 2920 TRACEE_SEES_ITS_ORIGINAL_PARENT( 2921 tracee_sees_its_original_parent_procfs_status, 2922 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 2923 "the status file in procfs"); 2924 #endif 2925 2926 /// ---------------------------------------------------------------------------- 2927 2928 static void 2929 eventmask_preserved(int event) 2930 { 2931 const int exitval = 5; 2932 const int sigval = SIGSTOP; 2933 pid_t child, wpid; 2934 #if defined(TWAIT_HAVE_STATUS) 2935 int status; 2936 #endif 2937 ptrace_event_t set_event, get_event; 2938 const int len = sizeof(ptrace_event_t); 2939 2940 DPRINTF("Before forking process PID=%d\n", getpid()); 2941 SYSCALL_REQUIRE((child = fork()) != -1); 2942 if (child == 0) { 2943 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2944 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2945 2946 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2947 FORKEE_ASSERT(raise(sigval) == 0); 2948 2949 DPRINTF("Before exiting of the child process\n"); 2950 _exit(exitval); 2951 } 2952 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2953 2954 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2955 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2956 2957 validate_status_stopped(status, sigval); 2958 2959 set_event.pe_set_event = event; 2960 SYSCALL_REQUIRE( 2961 ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 2962 SYSCALL_REQUIRE( 2963 ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 2964 DPRINTF("set_event=%#x get_event=%#x\n", set_event.pe_set_event, 2965 get_event.pe_set_event); 2966 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 2967 2968 DPRINTF("Before resuming the child process where it left off and " 2969 "without signal to be sent\n"); 2970 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2971 2972 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2973 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2974 2975 validate_status_exited(status, exitval); 2976 2977 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2978 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2979 } 2980 2981 #define EVENTMASK_PRESERVED(test, event) \ 2982 ATF_TC(test); \ 2983 ATF_TC_HEAD(test, tc) \ 2984 { \ 2985 atf_tc_set_md_var(tc, "descr", \ 2986 "Verify that eventmask " #event " is preserved"); \ 2987 } \ 2988 \ 2989 ATF_TC_BODY(test, tc) \ 2990 { \ 2991 \ 2992 eventmask_preserved(event); \ 2993 } 2994 2995 EVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 2996 EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 2997 EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 2998 EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 2999 EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 3000 EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 3001 EVENTMASK_PRESERVED(eventmask_preserved_posix_spawn, PTRACE_POSIX_SPAWN) 3002 3003 /// ---------------------------------------------------------------------------- 3004 3005 static void 3006 fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork, 3007 bool trackvforkdone) 3008 { 3009 const int exitval = 5; 3010 const int exitval2 = 0; /* This matched exit status from /bin/echo */ 3011 const int sigval = SIGSTOP; 3012 pid_t child, child2 = 0, wpid; 3013 #if defined(TWAIT_HAVE_STATUS) 3014 int status; 3015 #endif 3016 ptrace_state_t state; 3017 const int slen = sizeof(state); 3018 ptrace_event_t event; 3019 const int elen = sizeof(event); 3020 3021 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 3022 3023 DPRINTF("Before forking process PID=%d\n", getpid()); 3024 SYSCALL_REQUIRE((child = fork()) != -1); 3025 if (child == 0) { 3026 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3027 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3028 3029 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3030 FORKEE_ASSERT(raise(sigval) == 0); 3031 3032 if (strcmp(fn, "spawn") == 0) { 3033 FORKEE_ASSERT_EQ(posix_spawn(&child2, 3034 arg[0], NULL, NULL, arg, NULL), 0); 3035 } else { 3036 if (strcmp(fn, "fork") == 0) { 3037 FORKEE_ASSERT((child2 = fork()) != -1); 3038 } else if (strcmp(fn, "vfork") == 0) { 3039 FORKEE_ASSERT((child2 = vfork()) != -1); 3040 } 3041 3042 if (child2 == 0) 3043 _exit(exitval2); 3044 } 3045 FORKEE_REQUIRE_SUCCESS 3046 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3047 3048 forkee_status_exited(status, exitval2); 3049 3050 DPRINTF("Before exiting of the child process\n"); 3051 _exit(exitval); 3052 } 3053 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3054 3055 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3056 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3057 3058 validate_status_stopped(status, sigval); 3059 3060 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 3061 trackspawn ? "|PTRACE_POSIX_SPAWN" : "", 3062 trackfork ? "|PTRACE_FORK" : "", 3063 trackvfork ? "|PTRACE_VFORK" : "", 3064 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 3065 event.pe_set_event = 0; 3066 if (trackspawn) 3067 event.pe_set_event |= PTRACE_POSIX_SPAWN; 3068 if (trackfork) 3069 event.pe_set_event |= PTRACE_FORK; 3070 if (trackvfork) 3071 event.pe_set_event |= PTRACE_VFORK; 3072 if (trackvforkdone) 3073 event.pe_set_event |= PTRACE_VFORK_DONE; 3074 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3075 3076 DPRINTF("Before resuming the child process where it left off and " 3077 "without signal to be sent\n"); 3078 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3079 3080 #if defined(TWAIT_HAVE_PID) 3081 if ((trackspawn && strcmp(fn, "spawn") == 0) || 3082 (trackfork && strcmp(fn, "fork") == 0) || 3083 (trackvfork && strcmp(fn, "vfork") == 0)) { 3084 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 3085 child); 3086 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3087 child); 3088 3089 validate_status_stopped(status, SIGTRAP); 3090 3091 SYSCALL_REQUIRE( 3092 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3093 if (trackspawn && strcmp(fn, "spawn") == 0) { 3094 ATF_REQUIRE_EQ( 3095 state.pe_report_event & PTRACE_POSIX_SPAWN, 3096 PTRACE_POSIX_SPAWN); 3097 } 3098 if (trackfork && strcmp(fn, "fork") == 0) { 3099 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 3100 PTRACE_FORK); 3101 } 3102 if (trackvfork && strcmp(fn, "vfork") == 0) { 3103 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 3104 PTRACE_VFORK); 3105 } 3106 3107 child2 = state.pe_other_pid; 3108 DPRINTF("Reported ptrace event with forkee %d\n", child2); 3109 3110 DPRINTF("Before calling %s() for the forkee %d of the child " 3111 "%d\n", TWAIT_FNAME, child2, child); 3112 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 3113 child2); 3114 3115 validate_status_stopped(status, SIGTRAP); 3116 3117 SYSCALL_REQUIRE( 3118 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 3119 if (trackspawn && strcmp(fn, "spawn") == 0) { 3120 ATF_REQUIRE_EQ( 3121 state.pe_report_event & PTRACE_POSIX_SPAWN, 3122 PTRACE_POSIX_SPAWN); 3123 } 3124 if (trackfork && strcmp(fn, "fork") == 0) { 3125 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 3126 PTRACE_FORK); 3127 } 3128 if (trackvfork && strcmp(fn, "vfork") == 0) { 3129 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 3130 PTRACE_VFORK); 3131 } 3132 3133 ATF_REQUIRE_EQ(state.pe_other_pid, child); 3134 3135 DPRINTF("Before resuming the forkee process where it left off " 3136 "and without signal to be sent\n"); 3137 SYSCALL_REQUIRE( 3138 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 3139 3140 DPRINTF("Before resuming the child process where it left off " 3141 "and without signal to be sent\n"); 3142 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3143 } 3144 #endif 3145 3146 if (trackvforkdone && strcmp(fn, "vfork") == 0) { 3147 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 3148 child); 3149 TWAIT_REQUIRE_SUCCESS( 3150 wpid = TWAIT_GENERIC(child, &status, 0), child); 3151 3152 validate_status_stopped(status, SIGTRAP); 3153 3154 SYSCALL_REQUIRE( 3155 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3156 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 3157 3158 child2 = state.pe_other_pid; 3159 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 3160 child2); 3161 3162 DPRINTF("Before resuming the child process where it left off " 3163 "and without signal to be sent\n"); 3164 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3165 } 3166 3167 #if defined(TWAIT_HAVE_PID) 3168 if ((trackspawn && strcmp(fn, "spawn") == 0) || 3169 (trackfork && strcmp(fn, "fork") == 0) || 3170 (trackvfork && strcmp(fn, "vfork") == 0)) { 3171 DPRINTF("Before calling %s() for the forkee - expected exited" 3172 "\n", TWAIT_FNAME); 3173 TWAIT_REQUIRE_SUCCESS( 3174 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3175 3176 validate_status_exited(status, exitval2); 3177 3178 DPRINTF("Before calling %s() for the forkee - expected no " 3179 "process\n", TWAIT_FNAME); 3180 TWAIT_REQUIRE_FAILURE(ECHILD, 3181 wpid = TWAIT_GENERIC(child2, &status, 0)); 3182 } 3183 #endif 3184 3185 DPRINTF("Before calling %s() for the child - expected stopped " 3186 "SIGCHLD\n", TWAIT_FNAME); 3187 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3188 3189 validate_status_stopped(status, SIGCHLD); 3190 3191 DPRINTF("Before resuming the child process where it left off and " 3192 "without signal to be sent\n"); 3193 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3194 3195 DPRINTF("Before calling %s() for the child - expected exited\n", 3196 TWAIT_FNAME); 3197 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3198 3199 validate_status_exited(status, exitval); 3200 3201 DPRINTF("Before calling %s() for the child - expected no process\n", 3202 TWAIT_FNAME); 3203 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3204 } 3205 3206 #define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone) \ 3207 ATF_TC(name); \ 3208 ATF_TC_HEAD(name, tc) \ 3209 { \ 3210 atf_tc_set_md_var(tc, "descr", "Verify " fun "() " \ 3211 "called with 0%s%s%s%s in EVENT_MASK", \ 3212 tspawn ? "|PTRACE_POSIX_SPAWN" : "", \ 3213 tfork ? "|PTRACE_FORK" : "", \ 3214 tvfork ? "|PTRACE_VFORK" : "", \ 3215 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 3216 } \ 3217 \ 3218 ATF_TC_BODY(name, tc) \ 3219 { \ 3220 \ 3221 fork_body(fun, tspawn, tfork, tvfork, tvforkdone); \ 3222 } 3223 3224 FORK_TEST(fork1, "fork", false, false, false, false) 3225 #if defined(TWAIT_HAVE_PID) 3226 FORK_TEST(fork2, "fork", false, true, false, false) 3227 FORK_TEST(fork3, "fork", false, false, true, false) 3228 FORK_TEST(fork4, "fork", false, true, true, false) 3229 #endif 3230 FORK_TEST(fork5, "fork", false, false, false, true) 3231 #if defined(TWAIT_HAVE_PID) 3232 FORK_TEST(fork6, "fork", false, true, false, true) 3233 FORK_TEST(fork7, "fork", false, false, true, true) 3234 FORK_TEST(fork8, "fork", false, true, true, true) 3235 #endif 3236 FORK_TEST(fork9, "fork", true, false, false, false) 3237 #if defined(TWAIT_HAVE_PID) 3238 FORK_TEST(fork10, "fork", true, true, false, false) 3239 FORK_TEST(fork11, "fork", true, false, true, false) 3240 FORK_TEST(fork12, "fork", true, true, true, false) 3241 #endif 3242 FORK_TEST(fork13, "fork", true, false, false, true) 3243 #if defined(TWAIT_HAVE_PID) 3244 FORK_TEST(fork14, "fork", true, true, false, true) 3245 FORK_TEST(fork15, "fork", true, false, true, true) 3246 FORK_TEST(fork16, "fork", true, true, true, true) 3247 #endif 3248 3249 FORK_TEST(vfork1, "vfork", false, false, false, false) 3250 #if defined(TWAIT_HAVE_PID) 3251 FORK_TEST(vfork2, "vfork", false, true, false, false) 3252 FORK_TEST(vfork3, "vfork", false, false, true, false) 3253 FORK_TEST(vfork4, "vfork", false, true, true, false) 3254 #endif 3255 FORK_TEST(vfork5, "vfork", false, false, false, true) 3256 #if defined(TWAIT_HAVE_PID) 3257 FORK_TEST(vfork6, "vfork", false, true, false, true) 3258 FORK_TEST(vfork7, "vfork", false, false, true, true) 3259 FORK_TEST(vfork8, "vfork", false, true, true, true) 3260 #endif 3261 FORK_TEST(vfork9, "vfork", true, false, false, false) 3262 #if defined(TWAIT_HAVE_PID) 3263 FORK_TEST(vfork10, "vfork", true, true, false, false) 3264 FORK_TEST(vfork11, "vfork", true, false, true, false) 3265 FORK_TEST(vfork12, "vfork", true, true, true, false) 3266 #endif 3267 FORK_TEST(vfork13, "vfork", true, false, false, true) 3268 #if defined(TWAIT_HAVE_PID) 3269 FORK_TEST(vfork14, "vfork", true, true, false, true) 3270 FORK_TEST(vfork15, "vfork", true, false, true, true) 3271 FORK_TEST(vfork16, "vfork", true, true, true, true) 3272 #endif 3273 3274 FORK_TEST(posix_spawn1, "spawn", false, false, false, false) 3275 FORK_TEST(posix_spawn2, "spawn", false, true, false, false) 3276 FORK_TEST(posix_spawn3, "spawn", false, false, true, false) 3277 FORK_TEST(posix_spawn4, "spawn", false, true, true, false) 3278 FORK_TEST(posix_spawn5, "spawn", false, false, false, true) 3279 FORK_TEST(posix_spawn6, "spawn", false, true, false, true) 3280 FORK_TEST(posix_spawn7, "spawn", false, false, true, true) 3281 FORK_TEST(posix_spawn8, "spawn", false, true, true, true) 3282 #if defined(TWAIT_HAVE_PID) 3283 FORK_TEST(posix_spawn9, "spawn", true, false, false, false) 3284 FORK_TEST(posix_spawn10, "spawn", true, true, false, false) 3285 FORK_TEST(posix_spawn11, "spawn", true, false, true, false) 3286 FORK_TEST(posix_spawn12, "spawn", true, true, true, false) 3287 FORK_TEST(posix_spawn13, "spawn", true, false, false, true) 3288 FORK_TEST(posix_spawn14, "spawn", true, true, false, true) 3289 FORK_TEST(posix_spawn15, "spawn", true, false, true, true) 3290 FORK_TEST(posix_spawn16, "spawn", true, true, true, true) 3291 #endif 3292 3293 /// ---------------------------------------------------------------------------- 3294 3295 #if defined(TWAIT_HAVE_PID) 3296 static void 3297 unrelated_tracer_fork_body(const char *fn, bool trackspawn, bool trackfork, 3298 bool trackvfork, bool trackvforkdone) 3299 { 3300 const int sigval = SIGSTOP; 3301 struct msg_fds parent_tracee, parent_tracer; 3302 const int exitval = 10; 3303 const int exitval2 = 0; /* This matched exit status from /bin/echo */ 3304 pid_t tracee, tracer, wpid; 3305 pid_t tracee2 = 0; 3306 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 3307 #if defined(TWAIT_HAVE_STATUS) 3308 int status; 3309 #endif 3310 3311 struct ptrace_siginfo info; 3312 ptrace_state_t state; 3313 const int slen = sizeof(state); 3314 ptrace_event_t event; 3315 const int elen = sizeof(event); 3316 3317 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 3318 3319 DPRINTF("Spawn tracee\n"); 3320 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 3321 tracee = atf_utils_fork(); 3322 if (tracee == 0) { 3323 // Wait for parent to let us crash 3324 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 3325 3326 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3327 FORKEE_ASSERT(raise(sigval) == 0); 3328 3329 if (strcmp(fn, "spawn") == 0) { 3330 FORKEE_ASSERT_EQ(posix_spawn(&tracee2, 3331 arg[0], NULL, NULL, arg, NULL), 0); 3332 } else { 3333 if (strcmp(fn, "fork") == 0) { 3334 FORKEE_ASSERT((tracee2 = fork()) != -1); 3335 } else if (strcmp(fn, "vfork") == 0) { 3336 FORKEE_ASSERT((tracee2 = vfork()) != -1); 3337 } 3338 3339 if (tracee2 == 0) 3340 _exit(exitval2); 3341 } 3342 FORKEE_REQUIRE_SUCCESS 3343 (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 3344 3345 forkee_status_exited(status, exitval2); 3346 3347 DPRINTF("Before exiting of the child process\n"); 3348 _exit(exitval); 3349 } 3350 3351 DPRINTF("Spawn debugger\n"); 3352 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 3353 tracer = atf_utils_fork(); 3354 if (tracer == 0) { 3355 /* Fork again and drop parent to reattach to PID 1 */ 3356 tracer = atf_utils_fork(); 3357 if (tracer != 0) 3358 _exit(exitval); 3359 3360 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 3361 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 3362 3363 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 3364 FORKEE_REQUIRE_SUCCESS( 3365 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3366 3367 forkee_status_stopped(status, SIGSTOP); 3368 3369 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 3370 "traced process\n"); 3371 SYSCALL_REQUIRE( 3372 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3373 3374 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3375 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3376 "si_errno=%#x\n", info.psi_siginfo.si_signo, 3377 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 3378 3379 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 3380 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 3381 3382 /* Resume tracee with PT_CONTINUE */ 3383 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3384 3385 /* Inform parent that tracer has attached to tracee */ 3386 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 3387 3388 /* Wait for parent to tell use that tracee should have exited */ 3389 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 3390 3391 /* Wait for tracee and assert that it exited */ 3392 FORKEE_REQUIRE_SUCCESS( 3393 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3394 3395 forkee_status_stopped(status, sigval); 3396 3397 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 3398 "traced process\n"); 3399 SYSCALL_REQUIRE( 3400 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3401 3402 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3403 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3404 "si_errno=%#x\n", info.psi_siginfo.si_signo, 3405 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 3406 3407 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 3408 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 3409 3410 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 3411 trackspawn ? "|PTRACE_POSIX_SPAWN" : "", 3412 trackfork ? "|PTRACE_FORK" : "", 3413 trackvfork ? "|PTRACE_VFORK" : "", 3414 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", tracee); 3415 event.pe_set_event = 0; 3416 if (trackspawn) 3417 event.pe_set_event |= PTRACE_POSIX_SPAWN; 3418 if (trackfork) 3419 event.pe_set_event |= PTRACE_FORK; 3420 if (trackvfork) 3421 event.pe_set_event |= PTRACE_VFORK; 3422 if (trackvforkdone) 3423 event.pe_set_event |= PTRACE_VFORK_DONE; 3424 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) 3425 != -1); 3426 3427 DPRINTF("Before resuming the child process where it left off " 3428 "and without signal to be sent\n"); 3429 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3430 3431 if ((trackspawn && strcmp(fn, "spawn") == 0) || 3432 (trackfork && strcmp(fn, "fork") == 0) || 3433 (trackvfork && strcmp(fn, "vfork") == 0)) { 3434 DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME, 3435 tracee); 3436 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), 3437 tracee); 3438 3439 validate_status_stopped(status, SIGTRAP); 3440 3441 SYSCALL_REQUIRE( 3442 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 3443 if (trackspawn && strcmp(fn, "spawn") == 0) { 3444 ATF_REQUIRE_EQ( 3445 state.pe_report_event & PTRACE_POSIX_SPAWN, 3446 PTRACE_POSIX_SPAWN); 3447 } 3448 if (trackfork && strcmp(fn, "fork") == 0) { 3449 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 3450 PTRACE_FORK); 3451 } 3452 if (trackvfork && strcmp(fn, "vfork") == 0) { 3453 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 3454 PTRACE_VFORK); 3455 } 3456 3457 tracee2 = state.pe_other_pid; 3458 DPRINTF("Reported ptrace event with forkee %d\n", tracee2); 3459 3460 DPRINTF("Before calling %s() for the forkee %d of the tracee " 3461 "%d\n", TWAIT_FNAME, tracee2, tracee); 3462 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), 3463 tracee2); 3464 3465 validate_status_stopped(status, SIGTRAP); 3466 3467 SYSCALL_REQUIRE( 3468 ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1); 3469 if (trackspawn && strcmp(fn, "spawn") == 0) { 3470 ATF_REQUIRE_EQ( 3471 state.pe_report_event & PTRACE_POSIX_SPAWN, 3472 PTRACE_POSIX_SPAWN); 3473 } 3474 if (trackfork && strcmp(fn, "fork") == 0) { 3475 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 3476 PTRACE_FORK); 3477 } 3478 if (trackvfork && strcmp(fn, "vfork") == 0) { 3479 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 3480 PTRACE_VFORK); 3481 } 3482 3483 ATF_REQUIRE_EQ(state.pe_other_pid, tracee); 3484 3485 DPRINTF("Before resuming the forkee process where it left off " 3486 "and without signal to be sent\n"); 3487 SYSCALL_REQUIRE( 3488 ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1); 3489 3490 DPRINTF("Before resuming the tracee process where it left off " 3491 "and without signal to be sent\n"); 3492 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3493 } 3494 3495 if (trackvforkdone && strcmp(fn, "vfork") == 0) { 3496 DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME, 3497 tracee); 3498 TWAIT_REQUIRE_SUCCESS( 3499 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3500 3501 validate_status_stopped(status, SIGTRAP); 3502 3503 SYSCALL_REQUIRE( 3504 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 3505 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 3506 3507 tracee2 = state.pe_other_pid; 3508 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 3509 tracee2); 3510 3511 DPRINTF("Before resuming the tracee process where it left off " 3512 "and without signal to be sent\n"); 3513 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3514 } 3515 3516 3517 if ((trackspawn && strcmp(fn, "spawn") == 0) || 3518 (trackfork && strcmp(fn, "fork") == 0) || 3519 (trackvfork && strcmp(fn, "vfork") == 0)) { 3520 DPRINTF("Before calling %s() for the forkee - expected exited" 3521 "\n", TWAIT_FNAME); 3522 TWAIT_REQUIRE_SUCCESS( 3523 wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 3524 3525 validate_status_exited(status, exitval2); 3526 3527 DPRINTF("Before calling %s() for the forkee - expected no " 3528 "process\n", TWAIT_FNAME); 3529 TWAIT_REQUIRE_FAILURE(ECHILD, 3530 wpid = TWAIT_GENERIC(tracee2, &status, 0)); 3531 } 3532 3533 DPRINTF("Before calling %s() for the tracee - expected stopped " 3534 "SIGCHLD\n", TWAIT_FNAME); 3535 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3536 3537 validate_status_stopped(status, SIGCHLD); 3538 3539 DPRINTF("Before resuming the tracee process where it left off and " 3540 "without signal to be sent\n"); 3541 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3542 3543 DPRINTF("Before calling %s() for the tracee - expected exited\n", 3544 TWAIT_FNAME); 3545 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3546 3547 validate_status_exited(status, exitval); 3548 3549 /* Inform parent that tracer is exiting normally */ 3550 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 3551 3552 DPRINTF("Before exiting of the tracer process\n"); 3553 _exit(0 /* collect by initproc */); 3554 } 3555 3556 DPRINTF("Wait for the tracer process (direct child) to exit " 3557 "calling %s()\n", TWAIT_FNAME); 3558 TWAIT_REQUIRE_SUCCESS( 3559 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 3560 3561 validate_status_exited(status, exitval); 3562 3563 DPRINTF("Wait for the non-exited tracee process with %s()\n", 3564 TWAIT_FNAME); 3565 TWAIT_REQUIRE_SUCCESS( 3566 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 3567 3568 DPRINTF("Wait for the tracer to attach to the tracee\n"); 3569 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 3570 3571 DPRINTF("Resume the tracee and let it crash\n"); 3572 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 3573 3574 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 3575 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 3576 3577 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 3578 TWAIT_FNAME); 3579 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3580 3581 validate_status_exited(status, exitval); 3582 3583 DPRINTF("Await normal exit of tracer\n"); 3584 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 3585 3586 msg_close(&parent_tracer); 3587 msg_close(&parent_tracee); 3588 } 3589 3590 #define UNRELATED_TRACER_FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)\ 3591 ATF_TC(name); \ 3592 ATF_TC_HEAD(name, tc) \ 3593 { \ 3594 atf_tc_set_md_var(tc, "descr", "Verify " fun "() " \ 3595 "called with 0%s%s%s%s in EVENT_MASK", \ 3596 tspawn ? "|PTRACE_POSIX_SPAWN" : "", \ 3597 tfork ? "|PTRACE_FORK" : "", \ 3598 tvfork ? "|PTRACE_VFORK" : "", \ 3599 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 3600 } \ 3601 \ 3602 ATF_TC_BODY(name, tc) \ 3603 { \ 3604 \ 3605 unrelated_tracer_fork_body(fun, tspawn, tfork, tvfork, \ 3606 tvforkdone); \ 3607 } 3608 3609 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork1, "fork", false, false, false, false) 3610 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork2, "fork", false, true, false, false) 3611 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork3, "fork", false, false, true, false) 3612 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork4, "fork", false, true, true, false) 3613 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork5, "fork", false, false, false, true) 3614 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork6, "fork", false, true, false, true) 3615 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork7, "fork", false, false, true, true) 3616 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork8, "fork", false, true, true, true) 3617 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork9, "fork", true, false, false, false) 3618 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork10, "fork", true, true, false, false) 3619 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork11, "fork", true, false, true, false) 3620 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork12, "fork", true, true, true, false) 3621 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork13, "fork", true, false, false, true) 3622 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork14, "fork", true, true, false, true) 3623 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork15, "fork", true, false, true, true) 3624 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork16, "fork", true, true, true, true) 3625 3626 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork1, "vfork", false, false, false, false) 3627 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork2, "vfork", false, true, false, false) 3628 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork3, "vfork", false, false, true, false) 3629 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork4, "vfork", false, true, true, false) 3630 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork5, "vfork", false, false, false, true) 3631 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork6, "vfork", false, true, false, true) 3632 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork7, "vfork", false, false, true, true) 3633 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork8, "vfork", false, true, true, true) 3634 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork9, "vfork", true, false, false, false) 3635 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork10, "vfork", true, true, false, false) 3636 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork11, "vfork", true, false, true, false) 3637 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork12, "vfork", true, true, true, false) 3638 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork13, "vfork", true, false, false, true) 3639 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork14, "vfork", true, true, false, true) 3640 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork15, "vfork", true, false, true, true) 3641 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork16, "vfork", true, true, true, true) 3642 3643 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn1, "spawn", false, false, false, false) 3644 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn2, "spawn", false, true, false, false) 3645 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn3, "spawn", false, false, true, false) 3646 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn4, "spawn", false, true, true, false) 3647 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn5, "spawn", false, false, false, true) 3648 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn6, "spawn", false, true, false, true) 3649 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn7, "spawn", false, false, true, true) 3650 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn8, "spawn", false, true, true, true) 3651 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn9, "spawn", true, false, false, false) 3652 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn10, "spawn", true, true, false, false) 3653 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn11, "spawn", true, false, true, false) 3654 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn12, "spawn", true, true, true, false) 3655 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn13, "spawn", true, false, false, true) 3656 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn14, "spawn", true, true, false, true) 3657 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn15, "spawn", true, false, true, true) 3658 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn16, "spawn", true, true, true, true) 3659 #endif 3660 3661 /// ---------------------------------------------------------------------------- 3662 3663 #if defined(TWAIT_HAVE_PID) 3664 static void 3665 fork_detach_forker_body(const char *fn, bool kill_process) 3666 { 3667 const int exitval = 5; 3668 const int exitval2 = 0; /* Matches exit value from /bin/echo */ 3669 const int sigval = SIGSTOP; 3670 pid_t child, child2 = 0, wpid; 3671 #if defined(TWAIT_HAVE_STATUS) 3672 int status; 3673 #endif 3674 ptrace_state_t state; 3675 const int slen = sizeof(state); 3676 ptrace_event_t event; 3677 const int elen = sizeof(event); 3678 3679 int op; 3680 3681 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 3682 3683 DPRINTF("Before forking process PID=%d\n", getpid()); 3684 SYSCALL_REQUIRE((child = fork()) != -1); 3685 if (child == 0) { 3686 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3687 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3688 3689 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3690 FORKEE_ASSERT(raise(sigval) == 0); 3691 3692 if (strcmp(fn, "spawn") == 0) { 3693 FORKEE_ASSERT_EQ(posix_spawn(&child2, 3694 arg[0], NULL, NULL, arg, NULL), 0); 3695 } else { 3696 if (strcmp(fn, "fork") == 0) { 3697 FORKEE_ASSERT((child2 = fork()) != -1); 3698 } else { 3699 FORKEE_ASSERT((child2 = vfork()) != -1); 3700 } 3701 3702 if (child2 == 0) 3703 _exit(exitval2); 3704 } 3705 3706 FORKEE_REQUIRE_SUCCESS 3707 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3708 3709 forkee_status_exited(status, exitval2); 3710 3711 DPRINTF("Before exiting of the child process\n"); 3712 _exit(exitval); 3713 } 3714 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3715 3716 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3717 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3718 3719 validate_status_stopped(status, sigval); 3720 3721 DPRINTF("Set EVENT_MASK for the child %d\n", child); 3722 event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK 3723 | PTRACE_VFORK_DONE; 3724 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3725 3726 DPRINTF("Before resuming the child process where it left off and " 3727 "without signal to be sent\n"); 3728 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3729 3730 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child); 3731 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3732 3733 validate_status_stopped(status, SIGTRAP); 3734 3735 SYSCALL_REQUIRE( 3736 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3737 3738 if (strcmp(fn, "spawn") == 0) 3739 op = PTRACE_POSIX_SPAWN; 3740 else if (strcmp(fn, "fork") == 0) 3741 op = PTRACE_FORK; 3742 else 3743 op = PTRACE_VFORK; 3744 3745 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 3746 3747 child2 = state.pe_other_pid; 3748 DPRINTF("Reported ptrace event with forkee %d\n", child2); 3749 3750 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 3751 strcmp(fn, "vfork") == 0) 3752 op = kill_process ? PT_KILL : PT_DETACH; 3753 else 3754 op = PT_CONTINUE; 3755 SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1); 3756 3757 DPRINTF("Before calling %s() for the forkee %d of the child %d\n", 3758 TWAIT_FNAME, child2, child); 3759 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3760 3761 validate_status_stopped(status, SIGTRAP); 3762 3763 SYSCALL_REQUIRE( 3764 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 3765 if (strcmp(fn, "spawn") == 0) 3766 op = PTRACE_POSIX_SPAWN; 3767 else if (strcmp(fn, "fork") == 0) 3768 op = PTRACE_FORK; 3769 else 3770 op = PTRACE_VFORK; 3771 3772 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 3773 ATF_REQUIRE_EQ(state.pe_other_pid, child); 3774 3775 DPRINTF("Before resuming the forkee process where it left off " 3776 "and without signal to be sent\n"); 3777 SYSCALL_REQUIRE( 3778 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 3779 3780 if (strcmp(fn, "vforkdone") == 0) { 3781 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 3782 child); 3783 TWAIT_REQUIRE_SUCCESS( 3784 wpid = TWAIT_GENERIC(child, &status, 0), child); 3785 3786 validate_status_stopped(status, SIGTRAP); 3787 3788 SYSCALL_REQUIRE( 3789 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3790 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 3791 3792 child2 = state.pe_other_pid; 3793 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 3794 child2); 3795 3796 op = kill_process ? PT_KILL : PT_DETACH; 3797 DPRINTF("Before resuming the child process where it left off " 3798 "and without signal to be sent\n"); 3799 SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1); 3800 } 3801 3802 DPRINTF("Before calling %s() for the forkee - expected exited\n", 3803 TWAIT_FNAME); 3804 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3805 3806 validate_status_exited(status, exitval2); 3807 3808 DPRINTF("Before calling %s() for the forkee - expected no process\n", 3809 TWAIT_FNAME); 3810 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0)); 3811 3812 DPRINTF("Before calling %s() for the forkee - expected exited\n", 3813 TWAIT_FNAME); 3814 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3815 3816 if (kill_process) { 3817 validate_status_signaled(status, SIGKILL, 0); 3818 } else { 3819 validate_status_exited(status, exitval); 3820 } 3821 3822 DPRINTF("Before calling %s() for the child - expected no process\n", 3823 TWAIT_FNAME); 3824 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3825 } 3826 3827 #define FORK_DETACH_FORKER(name,event,kprocess) \ 3828 ATF_TC(name); \ 3829 ATF_TC_HEAD(name, tc) \ 3830 { \ 3831 atf_tc_set_md_var(tc, "descr", "Verify %s " event, \ 3832 kprocess ? "killed" : "detached"); \ 3833 } \ 3834 \ 3835 ATF_TC_BODY(name, tc) \ 3836 { \ 3837 \ 3838 fork_detach_forker_body(event, kprocess); \ 3839 } 3840 3841 FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false) 3842 FORK_DETACH_FORKER(fork_detach_forker, "fork", false) 3843 FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false) 3844 FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false) 3845 3846 FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true) 3847 FORK_DETACH_FORKER(fork_kill_forker, "fork", true) 3848 FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true) 3849 FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true) 3850 #endif 3851 3852 /// ---------------------------------------------------------------------------- 3853 3854 #if defined(TWAIT_HAVE_PID) 3855 static void 3856 unrelated_tracer_fork_detach_forker_body(const char *fn, bool kill_process) 3857 { 3858 const int sigval = SIGSTOP; 3859 struct msg_fds parent_tracee, parent_tracer; 3860 const int exitval = 10; 3861 const int exitval2 = 0; /* This matched exit status from /bin/echo */ 3862 pid_t tracee, tracer, wpid; 3863 pid_t tracee2 = 0; 3864 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 3865 #if defined(TWAIT_HAVE_STATUS) 3866 int status; 3867 #endif 3868 int op; 3869 3870 struct ptrace_siginfo info; 3871 ptrace_state_t state; 3872 const int slen = sizeof(state); 3873 ptrace_event_t event; 3874 const int elen = sizeof(event); 3875 3876 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 3877 3878 DPRINTF("Spawn tracee\n"); 3879 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 3880 tracee = atf_utils_fork(); 3881 if (tracee == 0) { 3882 // Wait for parent to let us crash 3883 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 3884 3885 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3886 FORKEE_ASSERT(raise(sigval) == 0); 3887 3888 if (strcmp(fn, "spawn") == 0) { 3889 FORKEE_ASSERT_EQ(posix_spawn(&tracee2, 3890 arg[0], NULL, NULL, arg, NULL), 0); 3891 } else { 3892 if (strcmp(fn, "fork") == 0) { 3893 FORKEE_ASSERT((tracee2 = fork()) != -1); 3894 } else { 3895 FORKEE_ASSERT((tracee2 = vfork()) != -1); 3896 } 3897 3898 if (tracee2 == 0) 3899 _exit(exitval2); 3900 } 3901 3902 FORKEE_REQUIRE_SUCCESS 3903 (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 3904 3905 forkee_status_exited(status, exitval2); 3906 3907 DPRINTF("Before exiting of the child process\n"); 3908 _exit(exitval); 3909 } 3910 3911 DPRINTF("Spawn debugger\n"); 3912 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 3913 tracer = atf_utils_fork(); 3914 if (tracer == 0) { 3915 /* Fork again and drop parent to reattach to PID 1 */ 3916 tracer = atf_utils_fork(); 3917 if (tracer != 0) 3918 _exit(exitval); 3919 3920 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 3921 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 3922 3923 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 3924 FORKEE_REQUIRE_SUCCESS( 3925 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3926 3927 forkee_status_stopped(status, SIGSTOP); 3928 3929 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 3930 "traced process\n"); 3931 SYSCALL_REQUIRE( 3932 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3933 3934 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3935 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3936 "si_errno=%#x\n", info.psi_siginfo.si_signo, 3937 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 3938 3939 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 3940 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 3941 3942 /* Resume tracee with PT_CONTINUE */ 3943 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3944 3945 /* Inform parent that tracer has attached to tracee */ 3946 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 3947 3948 /* Wait for parent to tell use that tracee should have exited */ 3949 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 3950 3951 /* Wait for tracee and assert that it exited */ 3952 FORKEE_REQUIRE_SUCCESS( 3953 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3954 3955 forkee_status_stopped(status, sigval); 3956 3957 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 3958 "traced process\n"); 3959 SYSCALL_REQUIRE( 3960 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3961 3962 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3963 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3964 "si_errno=%#x\n", info.psi_siginfo.si_signo, 3965 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 3966 3967 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 3968 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 3969 3970 DPRINTF("Set EVENT_MASK for the child %d\n", tracee); 3971 event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK 3972 | PTRACE_VFORK_DONE; 3973 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) != -1); 3974 3975 DPRINTF("Before resuming the child process where it left off and " 3976 "without signal to be sent\n"); 3977 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3978 3979 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, tracee); 3980 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3981 3982 validate_status_stopped(status, SIGTRAP); 3983 3984 SYSCALL_REQUIRE( 3985 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 3986 3987 if (strcmp(fn, "spawn") == 0) 3988 op = PTRACE_POSIX_SPAWN; 3989 else if (strcmp(fn, "fork") == 0) 3990 op = PTRACE_FORK; 3991 else 3992 op = PTRACE_VFORK; 3993 3994 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 3995 3996 tracee2 = state.pe_other_pid; 3997 DPRINTF("Reported ptrace event with forkee %d\n", tracee2); 3998 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 3999 strcmp(fn, "vfork") == 0) 4000 op = kill_process ? PT_KILL : PT_DETACH; 4001 else 4002 op = PT_CONTINUE; 4003 SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1); 4004 4005 DPRINTF("Before calling %s() for the forkee %d of the tracee %d\n", 4006 TWAIT_FNAME, tracee2, tracee); 4007 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 4008 4009 validate_status_stopped(status, SIGTRAP); 4010 4011 SYSCALL_REQUIRE( 4012 ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1); 4013 if (strcmp(fn, "spawn") == 0) 4014 op = PTRACE_POSIX_SPAWN; 4015 else if (strcmp(fn, "fork") == 0) 4016 op = PTRACE_FORK; 4017 else 4018 op = PTRACE_VFORK; 4019 4020 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 4021 ATF_REQUIRE_EQ(state.pe_other_pid, tracee); 4022 4023 DPRINTF("Before resuming the forkee process where it left off " 4024 "and without signal to be sent\n"); 4025 SYSCALL_REQUIRE( 4026 ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1); 4027 4028 if (strcmp(fn, "vforkdone") == 0) { 4029 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 4030 tracee); 4031 TWAIT_REQUIRE_SUCCESS( 4032 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4033 4034 validate_status_stopped(status, SIGTRAP); 4035 4036 SYSCALL_REQUIRE( 4037 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 4038 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 4039 4040 tracee2 = state.pe_other_pid; 4041 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 4042 tracee2); 4043 4044 op = kill_process ? PT_KILL : PT_DETACH; 4045 DPRINTF("Before resuming the child process where it left off " 4046 "and without signal to be sent\n"); 4047 SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1); 4048 } 4049 4050 DPRINTF("Before calling %s() for the forkee - expected exited\n", 4051 TWAIT_FNAME); 4052 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 4053 4054 validate_status_exited(status, exitval2); 4055 4056 DPRINTF("Before calling %s() for the forkee - expected no process\n", 4057 TWAIT_FNAME); 4058 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(tracee2, &status, 0)); 4059 4060 if (kill_process) { 4061 DPRINTF("Before calling %s() for the forkee - expected signaled\n", 4062 TWAIT_FNAME); 4063 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4064 4065 validate_status_signaled(status, SIGKILL, 0); 4066 } 4067 4068 /* Inform parent that tracer is exiting normally */ 4069 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 4070 4071 DPRINTF("Before exiting of the tracer process\n"); 4072 _exit(0 /* collect by initproc */); 4073 } 4074 4075 DPRINTF("Wait for the tracer process (direct child) to exit " 4076 "calling %s()\n", TWAIT_FNAME); 4077 TWAIT_REQUIRE_SUCCESS( 4078 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 4079 4080 validate_status_exited(status, exitval); 4081 4082 DPRINTF("Wait for the non-exited tracee process with %s()\n", 4083 TWAIT_FNAME); 4084 TWAIT_REQUIRE_SUCCESS( 4085 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 4086 4087 DPRINTF("Wait for the tracer to attach to the tracee\n"); 4088 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 4089 4090 DPRINTF("Resume the tracee and let it crash\n"); 4091 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 4092 4093 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 4094 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 4095 4096 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 4097 TWAIT_FNAME); 4098 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4099 4100 if (kill_process) { 4101 validate_status_signaled(status, SIGKILL, 0); 4102 } else { 4103 validate_status_exited(status, exitval); 4104 } 4105 4106 DPRINTF("Await normal exit of tracer\n"); 4107 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 4108 4109 msg_close(&parent_tracer); 4110 msg_close(&parent_tracee); 4111 } 4112 4113 #define UNRELATED_TRACER_FORK_DETACH_FORKER(name,event,kprocess) \ 4114 ATF_TC(name); \ 4115 ATF_TC_HEAD(name, tc) \ 4116 { \ 4117 atf_tc_set_md_var(tc, "descr", "Verify %s " event, \ 4118 kprocess ? "killed" : "detached"); \ 4119 } \ 4120 \ 4121 ATF_TC_BODY(name, tc) \ 4122 { \ 4123 \ 4124 unrelated_tracer_fork_detach_forker_body(event, kprocess); \ 4125 } 4126 4127 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_detach_spawner, "spawn", false) 4128 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_detach_forker, "fork", false) 4129 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforker, "vfork", false) 4130 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforkerdone, "vforkdone", false) 4131 4132 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_kill_spawner, "spawn", true) 4133 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_kill_forker, "fork", true) 4134 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforker, "vfork", true) 4135 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforkerdone, "vforkdone", true) 4136 #endif 4137 4138 /// ---------------------------------------------------------------------------- 4139 4140 static void 4141 traceme_vfork_fork_body(pid_t (*fn)(void)) 4142 { 4143 const int exitval = 5; 4144 const int exitval2 = 15; 4145 pid_t child, child2 = 0, wpid; 4146 #if defined(TWAIT_HAVE_STATUS) 4147 int status; 4148 #endif 4149 4150 DPRINTF("Before forking process PID=%d\n", getpid()); 4151 SYSCALL_REQUIRE((child = vfork()) != -1); 4152 if (child == 0) { 4153 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4154 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4155 4156 FORKEE_ASSERT((child2 = (fn)()) != -1); 4157 4158 if (child2 == 0) 4159 _exit(exitval2); 4160 4161 FORKEE_REQUIRE_SUCCESS 4162 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4163 4164 forkee_status_exited(status, exitval2); 4165 4166 DPRINTF("Before exiting of the child process\n"); 4167 _exit(exitval); 4168 } 4169 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4170 4171 DPRINTF("Before calling %s() for the child - expected exited\n", 4172 TWAIT_FNAME); 4173 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4174 4175 validate_status_exited(status, exitval); 4176 4177 DPRINTF("Before calling %s() for the child - expected no process\n", 4178 TWAIT_FNAME); 4179 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4180 } 4181 4182 #define TRACEME_VFORK_FORK_TEST(name,fun) \ 4183 ATF_TC(name); \ 4184 ATF_TC_HEAD(name, tc) \ 4185 { \ 4186 atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) " \ 4187 "called from vfork(2)ed child"); \ 4188 } \ 4189 \ 4190 ATF_TC_BODY(name, tc) \ 4191 { \ 4192 \ 4193 traceme_vfork_fork_body(fun); \ 4194 } 4195 4196 TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork) 4197 TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork) 4198 4199 /// ---------------------------------------------------------------------------- 4200 4201 enum bytes_transfer_type { 4202 BYTES_TRANSFER_DATA, 4203 BYTES_TRANSFER_DATAIO, 4204 BYTES_TRANSFER_TEXT, 4205 BYTES_TRANSFER_TEXTIO, 4206 BYTES_TRANSFER_AUXV 4207 }; 4208 4209 static int __used 4210 bytes_transfer_dummy(int a, int b, int c, int d) 4211 { 4212 int e, f, g, h; 4213 4214 a *= 4; 4215 b += 3; 4216 c -= 2; 4217 d /= 1; 4218 4219 e = strtol("10", NULL, 10); 4220 f = strtol("20", NULL, 10); 4221 g = strtol("30", NULL, 10); 4222 h = strtol("40", NULL, 10); 4223 4224 return (a + b * c - d) + (e * f - g / h); 4225 } 4226 4227 static void 4228 bytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 4229 { 4230 const int exitval = 5; 4231 const int sigval = SIGSTOP; 4232 pid_t child, wpid; 4233 bool skip = false; 4234 4235 int lookup_me = 0; 4236 uint8_t lookup_me8 = 0; 4237 uint16_t lookup_me16 = 0; 4238 uint32_t lookup_me32 = 0; 4239 uint64_t lookup_me64 = 0; 4240 4241 int magic = 0x13579246; 4242 uint8_t magic8 = 0xab; 4243 uint16_t magic16 = 0x1234; 4244 uint32_t magic32 = 0x98765432; 4245 uint64_t magic64 = 0xabcdef0123456789; 4246 4247 struct ptrace_io_desc io; 4248 #if defined(TWAIT_HAVE_STATUS) 4249 int status; 4250 #endif 4251 /* 513 is just enough, for the purposes of ATF it's good enough */ 4252 AuxInfo ai[513], *aip; 4253 4254 ATF_REQUIRE(size < sizeof(ai)); 4255 4256 /* Prepare variables for .TEXT transfers */ 4257 switch (type) { 4258 case BYTES_TRANSFER_TEXT: 4259 memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 4260 break; 4261 case BYTES_TRANSFER_TEXTIO: 4262 switch (size) { 4263 case 8: 4264 memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 4265 break; 4266 case 16: 4267 memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 4268 break; 4269 case 32: 4270 memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 4271 break; 4272 case 64: 4273 memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 4274 break; 4275 } 4276 break; 4277 default: 4278 break; 4279 } 4280 4281 /* Prepare variables for PIOD and AUXV transfers */ 4282 switch (type) { 4283 case BYTES_TRANSFER_TEXTIO: 4284 case BYTES_TRANSFER_DATAIO: 4285 io.piod_op = operation; 4286 switch (size) { 4287 case 8: 4288 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 4289 (void *)bytes_transfer_dummy : 4290 &lookup_me8; 4291 io.piod_addr = &lookup_me8; 4292 io.piod_len = sizeof(lookup_me8); 4293 break; 4294 case 16: 4295 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 4296 (void *)bytes_transfer_dummy : 4297 &lookup_me16; 4298 io.piod_addr = &lookup_me16; 4299 io.piod_len = sizeof(lookup_me16); 4300 break; 4301 case 32: 4302 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 4303 (void *)bytes_transfer_dummy : 4304 &lookup_me32; 4305 io.piod_addr = &lookup_me32; 4306 io.piod_len = sizeof(lookup_me32); 4307 break; 4308 case 64: 4309 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 4310 (void *)bytes_transfer_dummy : 4311 &lookup_me64; 4312 io.piod_addr = &lookup_me64; 4313 io.piod_len = sizeof(lookup_me64); 4314 break; 4315 default: 4316 break; 4317 } 4318 break; 4319 case BYTES_TRANSFER_AUXV: 4320 io.piod_op = operation; 4321 io.piod_offs = 0; 4322 io.piod_addr = ai; 4323 io.piod_len = size; 4324 break; 4325 default: 4326 break; 4327 } 4328 4329 DPRINTF("Before forking process PID=%d\n", getpid()); 4330 SYSCALL_REQUIRE((child = fork()) != -1); 4331 if (child == 0) { 4332 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4333 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4334 4335 switch (type) { 4336 case BYTES_TRANSFER_DATA: 4337 switch (operation) { 4338 case PT_READ_D: 4339 case PT_READ_I: 4340 lookup_me = magic; 4341 break; 4342 default: 4343 break; 4344 } 4345 break; 4346 case BYTES_TRANSFER_DATAIO: 4347 switch (operation) { 4348 case PIOD_READ_D: 4349 case PIOD_READ_I: 4350 switch (size) { 4351 case 8: 4352 lookup_me8 = magic8; 4353 break; 4354 case 16: 4355 lookup_me16 = magic16; 4356 break; 4357 case 32: 4358 lookup_me32 = magic32; 4359 break; 4360 case 64: 4361 lookup_me64 = magic64; 4362 break; 4363 default: 4364 break; 4365 } 4366 break; 4367 default: 4368 break; 4369 } 4370 default: 4371 break; 4372 } 4373 4374 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4375 FORKEE_ASSERT(raise(sigval) == 0); 4376 4377 /* Handle PIOD and PT separately as operation values overlap */ 4378 switch (type) { 4379 case BYTES_TRANSFER_DATA: 4380 switch (operation) { 4381 case PT_WRITE_D: 4382 case PT_WRITE_I: 4383 FORKEE_ASSERT_EQ(lookup_me, magic); 4384 break; 4385 default: 4386 break; 4387 } 4388 break; 4389 case BYTES_TRANSFER_DATAIO: 4390 switch (operation) { 4391 case PIOD_WRITE_D: 4392 case PIOD_WRITE_I: 4393 switch (size) { 4394 case 8: 4395 FORKEE_ASSERT_EQ(lookup_me8, magic8); 4396 break; 4397 case 16: 4398 FORKEE_ASSERT_EQ(lookup_me16, magic16); 4399 break; 4400 case 32: 4401 FORKEE_ASSERT_EQ(lookup_me32, magic32); 4402 break; 4403 case 64: 4404 FORKEE_ASSERT_EQ(lookup_me64, magic64); 4405 break; 4406 default: 4407 break; 4408 } 4409 break; 4410 default: 4411 break; 4412 } 4413 break; 4414 case BYTES_TRANSFER_TEXT: 4415 FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 4416 sizeof(magic)) == 0); 4417 break; 4418 case BYTES_TRANSFER_TEXTIO: 4419 switch (size) { 4420 case 8: 4421 FORKEE_ASSERT(memcmp(&magic8, 4422 bytes_transfer_dummy, 4423 sizeof(magic8)) == 0); 4424 break; 4425 case 16: 4426 FORKEE_ASSERT(memcmp(&magic16, 4427 bytes_transfer_dummy, 4428 sizeof(magic16)) == 0); 4429 break; 4430 case 32: 4431 FORKEE_ASSERT(memcmp(&magic32, 4432 bytes_transfer_dummy, 4433 sizeof(magic32)) == 0); 4434 break; 4435 case 64: 4436 FORKEE_ASSERT(memcmp(&magic64, 4437 bytes_transfer_dummy, 4438 sizeof(magic64)) == 0); 4439 break; 4440 } 4441 break; 4442 default: 4443 break; 4444 } 4445 4446 DPRINTF("Before exiting of the child process\n"); 4447 _exit(exitval); 4448 } 4449 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4450 4451 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4452 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4453 4454 validate_status_stopped(status, sigval); 4455 4456 /* Check PaX MPROTECT */ 4457 if (!can_we_write_to_text(child)) { 4458 switch (type) { 4459 case BYTES_TRANSFER_TEXTIO: 4460 switch (operation) { 4461 case PIOD_WRITE_D: 4462 case PIOD_WRITE_I: 4463 skip = true; 4464 break; 4465 default: 4466 break; 4467 } 4468 break; 4469 case BYTES_TRANSFER_TEXT: 4470 switch (operation) { 4471 case PT_WRITE_D: 4472 case PT_WRITE_I: 4473 skip = true; 4474 break; 4475 default: 4476 break; 4477 } 4478 break; 4479 default: 4480 break; 4481 } 4482 } 4483 4484 /* Bailout cleanly killing the child process */ 4485 if (skip) { 4486 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 4487 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4488 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4489 child); 4490 4491 validate_status_signaled(status, SIGKILL, 0); 4492 4493 atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 4494 } 4495 4496 DPRINTF("Calling operation to transfer bytes between child=%d and " 4497 "parent=%d\n", child, getpid()); 4498 4499 switch (type) { 4500 case BYTES_TRANSFER_TEXTIO: 4501 case BYTES_TRANSFER_DATAIO: 4502 case BYTES_TRANSFER_AUXV: 4503 switch (operation) { 4504 case PIOD_WRITE_D: 4505 case PIOD_WRITE_I: 4506 switch (size) { 4507 case 8: 4508 lookup_me8 = magic8; 4509 break; 4510 case 16: 4511 lookup_me16 = magic16; 4512 break; 4513 case 32: 4514 lookup_me32 = magic32; 4515 break; 4516 case 64: 4517 lookup_me64 = magic64; 4518 break; 4519 default: 4520 break; 4521 } 4522 break; 4523 default: 4524 break; 4525 } 4526 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 4527 switch (operation) { 4528 case PIOD_READ_D: 4529 case PIOD_READ_I: 4530 switch (size) { 4531 case 8: 4532 ATF_REQUIRE_EQ(lookup_me8, magic8); 4533 break; 4534 case 16: 4535 ATF_REQUIRE_EQ(lookup_me16, magic16); 4536 break; 4537 case 32: 4538 ATF_REQUIRE_EQ(lookup_me32, magic32); 4539 break; 4540 case 64: 4541 ATF_REQUIRE_EQ(lookup_me64, magic64); 4542 break; 4543 default: 4544 break; 4545 } 4546 break; 4547 case PIOD_READ_AUXV: 4548 DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 4549 io.piod_len); 4550 ATF_REQUIRE(io.piod_len > 0); 4551 for (aip = ai; aip->a_type != AT_NULL; aip++) 4552 DPRINTF("a_type=%#llx a_v=%#llx\n", 4553 (long long int)aip->a_type, 4554 (long long int)aip->a_v); 4555 break; 4556 default: 4557 break; 4558 } 4559 break; 4560 case BYTES_TRANSFER_TEXT: 4561 switch (operation) { 4562 case PT_READ_D: 4563 case PT_READ_I: 4564 errno = 0; 4565 lookup_me = ptrace(operation, child, 4566 bytes_transfer_dummy, 0); 4567 ATF_REQUIRE_EQ(lookup_me, magic); 4568 SYSCALL_REQUIRE_ERRNO(errno, 0); 4569 break; 4570 case PT_WRITE_D: 4571 case PT_WRITE_I: 4572 SYSCALL_REQUIRE(ptrace(operation, child, 4573 bytes_transfer_dummy, magic) 4574 != -1); 4575 break; 4576 default: 4577 break; 4578 } 4579 break; 4580 case BYTES_TRANSFER_DATA: 4581 switch (operation) { 4582 case PT_READ_D: 4583 case PT_READ_I: 4584 errno = 0; 4585 lookup_me = ptrace(operation, child, &lookup_me, 0); 4586 ATF_REQUIRE_EQ(lookup_me, magic); 4587 SYSCALL_REQUIRE_ERRNO(errno, 0); 4588 break; 4589 case PT_WRITE_D: 4590 case PT_WRITE_I: 4591 lookup_me = magic; 4592 SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 4593 magic) != -1); 4594 break; 4595 default: 4596 break; 4597 } 4598 break; 4599 default: 4600 break; 4601 } 4602 4603 DPRINTF("Before resuming the child process where it left off and " 4604 "without signal to be sent\n"); 4605 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4606 4607 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4608 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4609 4610 validate_status_exited(status, exitval); 4611 4612 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4613 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4614 } 4615 4616 #define BYTES_TRANSFER(test, operation, size, type) \ 4617 ATF_TC(test); \ 4618 ATF_TC_HEAD(test, tc) \ 4619 { \ 4620 atf_tc_set_md_var(tc, "descr", \ 4621 "Verify bytes transfer operation" #operation " and size " #size \ 4622 " of type " #type); \ 4623 } \ 4624 \ 4625 ATF_TC_BODY(test, tc) \ 4626 { \ 4627 \ 4628 bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 4629 } 4630 4631 // DATA 4632 4633 BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 4634 BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 4635 BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 4636 BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 4637 4638 BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 4639 BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 4640 BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 4641 BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 4642 4643 BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 4644 BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 4645 BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 4646 BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 4647 4648 BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 4649 BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 4650 BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 4651 BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 4652 4653 BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 4654 BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 4655 BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 4656 BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 4657 4658 // TEXT 4659 4660 BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 4661 BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 4662 BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 4663 BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 4664 4665 BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 4666 BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 4667 BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 4668 BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 4669 4670 BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 4671 BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 4672 BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 4673 BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 4674 4675 BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 4676 BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 4677 BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 4678 BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 4679 4680 BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 4681 BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 4682 BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 4683 BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 4684 4685 // AUXV 4686 4687 BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 4688 4689 /// ---------------------------------------------------------------------------- 4690 4691 static void 4692 bytes_transfer_alignment(const char *operation) 4693 { 4694 const int exitval = 5; 4695 const int sigval = SIGSTOP; 4696 pid_t child, wpid; 4697 #if defined(TWAIT_HAVE_STATUS) 4698 int status; 4699 #endif 4700 char *buffer; 4701 int vector; 4702 size_t len; 4703 size_t i; 4704 int op; 4705 4706 struct ptrace_io_desc io; 4707 struct ptrace_siginfo info; 4708 4709 memset(&io, 0, sizeof(io)); 4710 memset(&info, 0, sizeof(info)); 4711 4712 /* Testing misaligned byte transfer crossing page boundaries */ 4713 len = sysconf(_SC_PAGESIZE) * 2; 4714 buffer = malloc(len); 4715 ATF_REQUIRE(buffer != NULL); 4716 4717 /* Initialize the buffer with random data */ 4718 for (i = 0; i < len; i++) 4719 buffer[i] = i & 0xff; 4720 4721 DPRINTF("Before forking process PID=%d\n", getpid()); 4722 SYSCALL_REQUIRE((child = fork()) != -1); 4723 if (child == 0) { 4724 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4725 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4726 4727 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4728 FORKEE_ASSERT(raise(sigval) == 0); 4729 4730 DPRINTF("Before exiting of the child process\n"); 4731 _exit(exitval); 4732 } 4733 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4734 4735 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4736 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4737 4738 validate_status_stopped(status, sigval); 4739 4740 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4741 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) 4742 != -1); 4743 4744 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4745 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4746 "si_errno=%#x\n", 4747 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4748 info.psi_siginfo.si_errno); 4749 4750 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4751 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4752 4753 if (strcmp(operation, "PT_READ_I") == 0 || 4754 strcmp(operation, "PT_READ_D") == 0) { 4755 if (strcmp(operation, "PT_READ_I")) 4756 op = PT_READ_I; 4757 else 4758 op = PT_READ_D; 4759 4760 for (i = 0; i <= (len - sizeof(int)); i++) { 4761 errno = 0; 4762 vector = ptrace(op, child, buffer + i, 0); 4763 ATF_REQUIRE_EQ(errno, 0); 4764 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int))); 4765 } 4766 } else if (strcmp(operation, "PT_WRITE_I") == 0 || 4767 strcmp(operation, "PT_WRITE_D") == 0) { 4768 if (strcmp(operation, "PT_WRITE_I")) 4769 op = PT_WRITE_I; 4770 else 4771 op = PT_WRITE_D; 4772 4773 for (i = 0; i <= (len - sizeof(int)); i++) { 4774 memcpy(&vector, buffer + i, sizeof(int)); 4775 SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector) 4776 != -1); 4777 } 4778 } else if (strcmp(operation, "PIOD_READ_I") == 0 || 4779 strcmp(operation, "PIOD_READ_D") == 0) { 4780 if (strcmp(operation, "PIOD_READ_I")) 4781 op = PIOD_READ_I; 4782 else 4783 op = PIOD_READ_D; 4784 4785 io.piod_op = op; 4786 io.piod_addr = &vector; 4787 io.piod_len = sizeof(int); 4788 4789 for (i = 0; i <= (len - sizeof(int)); i++) { 4790 io.piod_offs = buffer + i; 4791 4792 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 4793 != -1); 4794 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int))); 4795 } 4796 } else if (strcmp(operation, "PIOD_WRITE_I") == 0 || 4797 strcmp(operation, "PIOD_WRITE_D") == 0) { 4798 if (strcmp(operation, "PIOD_WRITE_I")) 4799 op = PIOD_WRITE_I; 4800 else 4801 op = PIOD_WRITE_D; 4802 4803 io.piod_op = op; 4804 io.piod_addr = &vector; 4805 io.piod_len = sizeof(int); 4806 4807 for (i = 0; i <= (len - sizeof(int)); i++) { 4808 io.piod_offs = buffer + i; 4809 4810 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 4811 != -1); 4812 } 4813 } else if (strcmp(operation, "PIOD_READ_AUXV") == 0) { 4814 io.piod_op = PIOD_READ_AUXV; 4815 io.piod_addr = &vector; 4816 io.piod_len = sizeof(int); 4817 4818 errno = 0; 4819 i = 0; 4820 /* Read the whole AUXV vector, it has no clear length */ 4821 while (io.piod_len > 0) { 4822 io.piod_offs = (void *)(intptr_t)i; 4823 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 4824 != -1 || (io.piod_len == 0 && i > 0)); 4825 ++i; 4826 } 4827 } 4828 4829 DPRINTF("Before resuming the child process where it left off " 4830 "and without signal to be sent\n"); 4831 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4832 4833 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4834 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4835 child); 4836 4837 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4838 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4839 } 4840 4841 #define BYTES_TRANSFER_ALIGNMENT(test, operation) \ 4842 ATF_TC(test); \ 4843 ATF_TC_HEAD(test, tc) \ 4844 { \ 4845 atf_tc_set_md_var(tc, "descr", \ 4846 "Verify bytes transfer for potentially misaligned " \ 4847 "operation " operation); \ 4848 } \ 4849 \ 4850 ATF_TC_BODY(test, tc) \ 4851 { \ 4852 \ 4853 bytes_transfer_alignment(operation); \ 4854 } 4855 4856 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I") 4857 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D") 4858 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I") 4859 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D") 4860 4861 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I") 4862 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D") 4863 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I") 4864 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D") 4865 4866 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV") 4867 4868 /// ---------------------------------------------------------------------------- 4869 4870 static void 4871 bytes_transfer_eof(const char *operation) 4872 { 4873 const int exitval = 5; 4874 const int sigval = SIGSTOP; 4875 pid_t child, wpid; 4876 #if defined(TWAIT_HAVE_STATUS) 4877 int status; 4878 #endif 4879 FILE *fp; 4880 char *p; 4881 int vector; 4882 int op; 4883 4884 struct ptrace_io_desc io; 4885 struct ptrace_siginfo info; 4886 4887 memset(&io, 0, sizeof(io)); 4888 memset(&info, 0, sizeof(info)); 4889 4890 vector = 0; 4891 4892 fp = tmpfile(); 4893 ATF_REQUIRE(fp != NULL); 4894 4895 p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0); 4896 ATF_REQUIRE(p != MAP_FAILED); 4897 4898 DPRINTF("Before forking process PID=%d\n", getpid()); 4899 SYSCALL_REQUIRE((child = fork()) != -1); 4900 if (child == 0) { 4901 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4902 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4903 4904 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4905 FORKEE_ASSERT(raise(sigval) == 0); 4906 4907 DPRINTF("Before exiting of the child process\n"); 4908 _exit(exitval); 4909 } 4910 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4911 4912 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4913 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4914 4915 validate_status_stopped(status, sigval); 4916 4917 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4918 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) 4919 != -1); 4920 4921 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4922 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4923 "si_errno=%#x\n", 4924 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4925 info.psi_siginfo.si_errno); 4926 4927 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4928 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4929 4930 if (strcmp(operation, "PT_READ_I") == 0 || 4931 strcmp(operation, "PT_READ_D") == 0) { 4932 if (strcmp(operation, "PT_READ_I")) 4933 op = PT_READ_I; 4934 else 4935 op = PT_READ_D; 4936 4937 errno = 0; 4938 SYSCALL_REQUIRE(ptrace(op, child, p, 0) == -1); 4939 ATF_REQUIRE_EQ(errno, EINVAL); 4940 } else if (strcmp(operation, "PT_WRITE_I") == 0 || 4941 strcmp(operation, "PT_WRITE_D") == 0) { 4942 if (strcmp(operation, "PT_WRITE_I")) 4943 op = PT_WRITE_I; 4944 else 4945 op = PT_WRITE_D; 4946 4947 errno = 0; 4948 SYSCALL_REQUIRE(ptrace(op, child, p, vector) == -1); 4949 ATF_REQUIRE_EQ(errno, EINVAL); 4950 } else if (strcmp(operation, "PIOD_READ_I") == 0 || 4951 strcmp(operation, "PIOD_READ_D") == 0) { 4952 if (strcmp(operation, "PIOD_READ_I")) 4953 op = PIOD_READ_I; 4954 else 4955 op = PIOD_READ_D; 4956 4957 io.piod_op = op; 4958 io.piod_addr = &vector; 4959 io.piod_len = sizeof(int); 4960 io.piod_offs = p; 4961 4962 errno = 0; 4963 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1); 4964 ATF_REQUIRE_EQ(errno, EINVAL); 4965 } else if (strcmp(operation, "PIOD_WRITE_I") == 0 || 4966 strcmp(operation, "PIOD_WRITE_D") == 0) { 4967 if (strcmp(operation, "PIOD_WRITE_I")) 4968 op = PIOD_WRITE_I; 4969 else 4970 op = PIOD_WRITE_D; 4971 4972 io.piod_op = op; 4973 io.piod_addr = &vector; 4974 io.piod_len = sizeof(int); 4975 io.piod_offs = p; 4976 4977 errno = 0; 4978 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1); 4979 ATF_REQUIRE_EQ(errno, EINVAL); 4980 } 4981 4982 DPRINTF("Before resuming the child process where it left off " 4983 "and without signal to be sent\n"); 4984 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4985 4986 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4987 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4988 child); 4989 4990 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4991 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4992 } 4993 4994 #define BYTES_TRANSFER_EOF(test, operation) \ 4995 ATF_TC(test); \ 4996 ATF_TC_HEAD(test, tc) \ 4997 { \ 4998 atf_tc_set_md_var(tc, "descr", \ 4999 "Verify bytes EOF byte transfer for the " operation \ 5000 " operation"); \ 5001 } \ 5002 \ 5003 ATF_TC_BODY(test, tc) \ 5004 { \ 5005 \ 5006 bytes_transfer_eof(operation); \ 5007 } 5008 5009 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_i, "PT_READ_I") 5010 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_d, "PT_READ_D") 5011 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_i, "PT_WRITE_I") 5012 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_d, "PT_WRITE_D") 5013 5014 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_i, "PIOD_READ_I") 5015 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_d, "PIOD_READ_D") 5016 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_i, "PIOD_WRITE_I") 5017 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_d, "PIOD_WRITE_D") 5018 5019 /// ---------------------------------------------------------------------------- 5020 5021 #if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 5022 static void 5023 access_regs(const char *regset, const char *aux) 5024 { 5025 const int exitval = 5; 5026 const int sigval = SIGSTOP; 5027 pid_t child, wpid; 5028 #if defined(TWAIT_HAVE_STATUS) 5029 int status; 5030 #endif 5031 #if defined(HAVE_GPREGS) 5032 struct reg gpr; 5033 register_t rgstr; 5034 #endif 5035 #if defined(HAVE_FPREGS) 5036 struct fpreg fpr; 5037 #endif 5038 5039 #if !defined(HAVE_GPREGS) 5040 if (strcmp(regset, "regs") == 0) 5041 atf_tc_fail("Impossible test scenario!"); 5042 #endif 5043 5044 #if !defined(HAVE_FPREGS) 5045 if (strcmp(regset, "fpregs") == 0) 5046 atf_tc_fail("Impossible test scenario!"); 5047 #endif 5048 5049 DPRINTF("Before forking process PID=%d\n", getpid()); 5050 SYSCALL_REQUIRE((child = fork()) != -1); 5051 if (child == 0) { 5052 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5053 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5054 5055 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5056 FORKEE_ASSERT(raise(sigval) == 0); 5057 5058 DPRINTF("Before exiting of the child process\n"); 5059 _exit(exitval); 5060 } 5061 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5062 5063 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5064 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5065 5066 validate_status_stopped(status, sigval); 5067 5068 #if defined(HAVE_GPREGS) 5069 if (strcmp(regset, "regs") == 0) { 5070 DPRINTF("Call GETREGS for the child process\n"); 5071 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 5072 5073 if (strcmp(aux, "none") == 0) { 5074 DPRINTF("Retrieved registers\n"); 5075 } else if (strcmp(aux, "pc") == 0) { 5076 rgstr = PTRACE_REG_PC(&gpr); 5077 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 5078 } else if (strstr(aux, "set_pc") != NULL) { 5079 rgstr = PTRACE_REG_PC(&gpr); 5080 DPRINTF("Retrieved PC %" PRIxREGISTER "\n", rgstr); 5081 if (strstr(aux, "0x1") != NULL) { 5082 rgstr |= 0x1; 5083 } else if (strstr(aux, "0x3") != NULL) { 5084 rgstr |= 0x3; 5085 } else if (strstr(aux, "0x7") != NULL) { 5086 rgstr |= 0x7; 5087 } 5088 DPRINTF("Set PC %" PRIxREGISTER "\n", rgstr); 5089 PTRACE_REG_SET_PC(&gpr, rgstr); 5090 if (strcmp(aux, "set_pc") != 0) { 5091 /* This call can fail with EINVAL or similar. */ 5092 ptrace(PT_SETREGS, child, &gpr, 0); 5093 } 5094 } else if (strcmp(aux, "sp") == 0) { 5095 rgstr = PTRACE_REG_SP(&gpr); 5096 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 5097 } else if (strcmp(aux, "intrv") == 0) { 5098 rgstr = PTRACE_REG_INTRV(&gpr); 5099 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 5100 } else if (strcmp(aux, "setregs") == 0) { 5101 DPRINTF("Call SETREGS for the child process\n"); 5102 SYSCALL_REQUIRE( 5103 ptrace(PT_SETREGS, child, &gpr, 0) != -1); 5104 } 5105 } 5106 #endif 5107 5108 #if defined(HAVE_FPREGS) 5109 if (strcmp(regset, "fpregs") == 0) { 5110 DPRINTF("Call GETFPREGS for the child process\n"); 5111 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 5112 5113 if (strcmp(aux, "getfpregs") == 0) { 5114 DPRINTF("Retrieved FP registers\n"); 5115 } else if (strcmp(aux, "setfpregs") == 0) { 5116 DPRINTF("Call SETFPREGS for the child\n"); 5117 SYSCALL_REQUIRE( 5118 ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 5119 } 5120 } 5121 #endif 5122 5123 DPRINTF("Before resuming the child process where it left off and " 5124 "without signal to be sent\n"); 5125 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5126 5127 if (strstr(aux, "unaligned") != NULL) { 5128 DPRINTF("Before resuming the child process where it left off " 5129 "and without signal to be sent\n"); 5130 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 5131 5132 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5133 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5134 child); 5135 5136 validate_status_signaled(status, SIGKILL, 0); 5137 5138 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5139 TWAIT_REQUIRE_FAILURE(ECHILD, 5140 wpid = TWAIT_GENERIC(child, &status, 0)); 5141 } else { 5142 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5143 TWAIT_REQUIRE_SUCCESS( 5144 wpid = TWAIT_GENERIC(child, &status, 0), child); 5145 5146 validate_status_exited(status, exitval); 5147 5148 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5149 TWAIT_REQUIRE_FAILURE(ECHILD, 5150 wpid = TWAIT_GENERIC(child, &status, 0)); 5151 } 5152 } 5153 5154 #define ACCESS_REGS(test, regset, aux) \ 5155 ATF_TC(test); \ 5156 ATF_TC_HEAD(test, tc) \ 5157 { \ 5158 atf_tc_set_md_var(tc, "descr", \ 5159 "Verify " regset " with auxiliary operation: " aux); \ 5160 } \ 5161 \ 5162 ATF_TC_BODY(test, tc) \ 5163 { \ 5164 \ 5165 access_regs(regset, aux); \ 5166 } 5167 #endif 5168 5169 #if defined(HAVE_GPREGS) 5170 ACCESS_REGS(access_regs1, "regs", "none") 5171 ACCESS_REGS(access_regs2, "regs", "pc") 5172 ACCESS_REGS(access_regs3, "regs", "set_pc") 5173 ACCESS_REGS(access_regs4, "regs", "sp") 5174 ACCESS_REGS(access_regs5, "regs", "intrv") 5175 ACCESS_REGS(access_regs6, "regs", "setregs") 5176 ACCESS_REGS(access_regs_set_unaligned_pc_0x1, "regs", "set_pc+unaligned+0x1") 5177 ACCESS_REGS(access_regs_set_unaligned_pc_0x3, "regs", "set_pc+unaligned+0x3") 5178 ACCESS_REGS(access_regs_set_unaligned_pc_0x7, "regs", "set_pc+unaligned+0x7") 5179 #endif 5180 #if defined(HAVE_FPREGS) 5181 ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 5182 ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 5183 #endif 5184 5185 /// ---------------------------------------------------------------------------- 5186 5187 #if defined(PT_STEP) 5188 static void 5189 ptrace_step(int N, int setstep, bool masked, bool ignored) 5190 { 5191 const int exitval = 5; 5192 const int sigval = SIGSTOP; 5193 pid_t child, wpid; 5194 #if defined(TWAIT_HAVE_STATUS) 5195 int status; 5196 #endif 5197 int happy; 5198 struct sigaction sa; 5199 struct ptrace_siginfo info; 5200 sigset_t intmask; 5201 struct kinfo_proc2 kp; 5202 size_t len = sizeof(kp); 5203 5204 int name[6]; 5205 const size_t namelen = __arraycount(name); 5206 ki_sigset_t kp_sigmask; 5207 ki_sigset_t kp_sigignore; 5208 5209 #if defined(__arm__) 5210 /* PT_STEP not supported on arm 32-bit */ 5211 atf_tc_expect_fail("PR kern/52119"); 5212 #endif 5213 5214 DPRINTF("Before forking process PID=%d\n", getpid()); 5215 SYSCALL_REQUIRE((child = fork()) != -1); 5216 if (child == 0) { 5217 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5218 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5219 5220 if (masked) { 5221 sigemptyset(&intmask); 5222 sigaddset(&intmask, SIGTRAP); 5223 sigprocmask(SIG_BLOCK, &intmask, NULL); 5224 } 5225 5226 if (ignored) { 5227 memset(&sa, 0, sizeof(sa)); 5228 sa.sa_handler = SIG_IGN; 5229 sigemptyset(&sa.sa_mask); 5230 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 5231 } 5232 5233 happy = check_happy(999); 5234 5235 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5236 FORKEE_ASSERT(raise(sigval) == 0); 5237 5238 FORKEE_ASSERT_EQ(happy, check_happy(999)); 5239 5240 DPRINTF("Before exiting of the child process\n"); 5241 _exit(exitval); 5242 } 5243 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5244 5245 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5246 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5247 5248 validate_status_stopped(status, sigval); 5249 5250 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5251 SYSCALL_REQUIRE( 5252 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5253 5254 DPRINTF("Before checking siginfo_t\n"); 5255 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5256 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5257 5258 name[0] = CTL_KERN, 5259 name[1] = KERN_PROC2, 5260 name[2] = KERN_PROC_PID; 5261 name[3] = child; 5262 name[4] = sizeof(kp); 5263 name[5] = 1; 5264 5265 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5266 5267 if (masked) 5268 kp_sigmask = kp.p_sigmask; 5269 5270 if (ignored) 5271 kp_sigignore = kp.p_sigignore; 5272 5273 while (N --> 0) { 5274 if (setstep) { 5275 DPRINTF("Before resuming the child process where it " 5276 "left off and without signal to be sent (use " 5277 "PT_SETSTEP and PT_CONTINUE)\n"); 5278 SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 5279 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 5280 != -1); 5281 } else { 5282 DPRINTF("Before resuming the child process where it " 5283 "left off and without signal to be sent (use " 5284 "PT_STEP)\n"); 5285 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 5286 != -1); 5287 } 5288 5289 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5290 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5291 child); 5292 5293 validate_status_stopped(status, SIGTRAP); 5294 5295 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5296 SYSCALL_REQUIRE( 5297 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5298 5299 DPRINTF("Before checking siginfo_t\n"); 5300 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5301 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 5302 5303 if (setstep) { 5304 SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 5305 } 5306 5307 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5308 5309 if (masked) { 5310 DPRINTF("kp_sigmask=" 5311 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5312 PRIx32 "\n", 5313 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5314 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5315 5316 DPRINTF("kp.p_sigmask=" 5317 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5318 PRIx32 "\n", 5319 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5320 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5321 5322 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5323 sizeof(kp_sigmask))); 5324 } 5325 5326 if (ignored) { 5327 DPRINTF("kp_sigignore=" 5328 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5329 PRIx32 "\n", 5330 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5331 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5332 5333 DPRINTF("kp.p_sigignore=" 5334 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5335 PRIx32 "\n", 5336 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5337 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5338 5339 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5340 sizeof(kp_sigignore))); 5341 } 5342 } 5343 5344 DPRINTF("Before resuming the child process where it left off and " 5345 "without signal to be sent\n"); 5346 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5347 5348 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5349 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5350 5351 validate_status_exited(status, exitval); 5352 5353 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5354 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5355 } 5356 5357 #define PTRACE_STEP(test, N, setstep) \ 5358 ATF_TC(test); \ 5359 ATF_TC_HEAD(test, tc) \ 5360 { \ 5361 atf_tc_set_md_var(tc, "descr", \ 5362 "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 5363 } \ 5364 \ 5365 ATF_TC_BODY(test, tc) \ 5366 { \ 5367 \ 5368 ptrace_step(N, setstep, false, false); \ 5369 } 5370 5371 PTRACE_STEP(step1, 1, 0) 5372 PTRACE_STEP(step2, 2, 0) 5373 PTRACE_STEP(step3, 3, 0) 5374 PTRACE_STEP(step4, 4, 0) 5375 PTRACE_STEP(setstep1, 1, 1) 5376 PTRACE_STEP(setstep2, 2, 1) 5377 PTRACE_STEP(setstep3, 3, 1) 5378 PTRACE_STEP(setstep4, 4, 1) 5379 5380 ATF_TC(step_signalmasked); 5381 ATF_TC_HEAD(step_signalmasked, tc) 5382 { 5383 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with masked SIGTRAP"); 5384 } 5385 5386 ATF_TC_BODY(step_signalmasked, tc) 5387 { 5388 5389 ptrace_step(1, 0, true, false); 5390 } 5391 5392 ATF_TC(step_signalignored); 5393 ATF_TC_HEAD(step_signalignored, tc) 5394 { 5395 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with ignored SIGTRAP"); 5396 } 5397 5398 ATF_TC_BODY(step_signalignored, tc) 5399 { 5400 5401 ptrace_step(1, 0, false, true); 5402 } 5403 #endif 5404 5405 /// ---------------------------------------------------------------------------- 5406 5407 static void 5408 ptrace_kill(const char *type) 5409 { 5410 const int sigval = SIGSTOP; 5411 pid_t child, wpid; 5412 #if defined(TWAIT_HAVE_STATUS) 5413 int status; 5414 #endif 5415 5416 DPRINTF("Before forking process PID=%d\n", getpid()); 5417 SYSCALL_REQUIRE((child = fork()) != -1); 5418 if (child == 0) { 5419 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5420 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5421 5422 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5423 FORKEE_ASSERT(raise(sigval) == 0); 5424 5425 /* NOTREACHED */ 5426 FORKEE_ASSERTX(0 && 5427 "Child should be terminated by a signal from its parent"); 5428 } 5429 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5430 5431 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5432 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5433 5434 validate_status_stopped(status, sigval); 5435 5436 DPRINTF("Before killing the child process with %s\n", type); 5437 if (strcmp(type, "ptrace(PT_KILL)") == 0) { 5438 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 5439 } else if (strcmp(type, "kill(SIGKILL)") == 0) { 5440 kill(child, SIGKILL); 5441 } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 5442 setpgid(child, 0); 5443 killpg(getpgid(child), SIGKILL); 5444 } 5445 5446 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5447 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5448 5449 validate_status_signaled(status, SIGKILL, 0); 5450 5451 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5452 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5453 } 5454 5455 #define PTRACE_KILL(test, type) \ 5456 ATF_TC(test); \ 5457 ATF_TC_HEAD(test, tc) \ 5458 { \ 5459 atf_tc_set_md_var(tc, "descr", \ 5460 "Verify killing the child with " type); \ 5461 } \ 5462 \ 5463 ATF_TC_BODY(test, tc) \ 5464 { \ 5465 \ 5466 ptrace_kill(type); \ 5467 } 5468 5469 // PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 5470 PTRACE_KILL(kill1, "ptrace(PT_KILL)") 5471 PTRACE_KILL(kill2, "kill(SIGKILL)") 5472 PTRACE_KILL(kill3, "killpg(SIGKILL)") 5473 5474 /// ---------------------------------------------------------------------------- 5475 5476 static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG}; 5477 5478 static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER; 5479 static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER; 5480 static volatile size_t lwpinfo_thread_done; 5481 5482 static void * 5483 lwpinfo_thread(void *arg) 5484 { 5485 sigset_t s; 5486 volatile void **tcb; 5487 5488 tcb = (volatile void **)arg; 5489 5490 *tcb = _lwp_getprivate(); 5491 DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self()); 5492 5493 pthread_setname_np(pthread_self(), "thread %d", 5494 (void *)(intptr_t)_lwp_self()); 5495 5496 sigemptyset(&s); 5497 pthread_mutex_lock(&lwpinfo_thread_mtx); 5498 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 5499 lwpinfo_thread_done++; 5500 pthread_sigmask(SIG_BLOCK, &s, NULL); 5501 pthread_cond_signal(&lwpinfo_thread_cnd); 5502 pthread_mutex_unlock(&lwpinfo_thread_mtx); 5503 5504 return infinite_thread(NULL); 5505 } 5506 5507 static void 5508 traceme_lwpinfo(const size_t threads, const char *iter) 5509 { 5510 const int sigval = SIGSTOP; 5511 const int sigval2 = SIGINT; 5512 pid_t child, wpid; 5513 #if defined(TWAIT_HAVE_STATUS) 5514 int status; 5515 #endif 5516 struct ptrace_lwpinfo lwp = {0, 0}; 5517 struct ptrace_lwpstatus lwpstatus = {0}; 5518 struct ptrace_siginfo info; 5519 void *private; 5520 char *name; 5521 char namebuf[PL_LNAMELEN]; 5522 volatile void *tcb[4]; 5523 bool found; 5524 sigset_t s; 5525 5526 /* Maximum number of supported threads in this test */ 5527 pthread_t t[__arraycount(tcb) - 1]; 5528 size_t n, m; 5529 int rv; 5530 size_t bytes_read; 5531 5532 struct ptrace_io_desc io; 5533 sigset_t sigmask; 5534 5535 ATF_REQUIRE(__arraycount(t) >= threads); 5536 memset(tcb, 0, sizeof(tcb)); 5537 5538 DPRINTF("Before forking process PID=%d\n", getpid()); 5539 SYSCALL_REQUIRE((child = fork()) != -1); 5540 if (child == 0) { 5541 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5542 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5543 5544 tcb[0] = _lwp_getprivate(); 5545 DPRINTF("Storing tcb[0] = %p\n", tcb[0]); 5546 5547 pthread_setname_np(pthread_self(), "thread %d", 5548 (void *)(intptr_t)_lwp_self()); 5549 5550 sigemptyset(&s); 5551 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 5552 pthread_sigmask(SIG_BLOCK, &s, NULL); 5553 5554 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5555 FORKEE_ASSERT(raise(sigval) == 0); 5556 5557 for (n = 0; n < threads; n++) { 5558 rv = pthread_create(&t[n], NULL, lwpinfo_thread, 5559 &tcb[n + 1]); 5560 FORKEE_ASSERT(rv == 0); 5561 } 5562 5563 pthread_mutex_lock(&lwpinfo_thread_mtx); 5564 while (lwpinfo_thread_done < threads) { 5565 pthread_cond_wait(&lwpinfo_thread_cnd, 5566 &lwpinfo_thread_mtx); 5567 } 5568 pthread_mutex_unlock(&lwpinfo_thread_mtx); 5569 5570 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 5571 FORKEE_ASSERT(raise(sigval2) == 0); 5572 5573 /* NOTREACHED */ 5574 FORKEE_ASSERTX(0 && "Not reached"); 5575 } 5576 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5577 5578 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5579 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5580 5581 validate_status_stopped(status, sigval); 5582 5583 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 5584 SYSCALL_REQUIRE( 5585 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5586 5587 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5588 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5589 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5590 info.psi_siginfo.si_errno); 5591 5592 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5593 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5594 5595 if (strstr(iter, "LWPINFO") != NULL) { 5596 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5597 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5598 != -1); 5599 5600 DPRINTF("Assert that there exists a single thread only\n"); 5601 ATF_REQUIRE(lwp.pl_lwpid > 0); 5602 5603 DPRINTF("Assert that lwp thread %d received event " 5604 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 5605 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 5606 5607 if (strstr(iter, "LWPSTATUS") != NULL) { 5608 DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS " 5609 "for child\n"); 5610 lwpstatus.pl_lwpid = lwp.pl_lwpid; 5611 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus, 5612 sizeof(lwpstatus)) != -1); 5613 } 5614 5615 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5616 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5617 != -1); 5618 5619 DPRINTF("Assert that there exists a single thread only\n"); 5620 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 5621 } else { 5622 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5623 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5624 sizeof(lwpstatus)) != -1); 5625 5626 DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid); 5627 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 5628 5629 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5630 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5631 sizeof(lwpstatus)) != -1); 5632 5633 DPRINTF("Assert that there exists a single thread only\n"); 5634 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 5635 } 5636 5637 DPRINTF("Before resuming the child process where it left off and " 5638 "without signal to be sent\n"); 5639 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5640 5641 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5642 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5643 5644 validate_status_stopped(status, sigval2); 5645 5646 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 5647 SYSCALL_REQUIRE( 5648 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5649 5650 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5651 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5652 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5653 info.psi_siginfo.si_errno); 5654 5655 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 5656 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5657 5658 memset(&lwp, 0, sizeof(lwp)); 5659 memset(&lwpstatus, 0, sizeof(lwpstatus)); 5660 5661 memset(&io, 0, sizeof(io)); 5662 5663 bytes_read = 0; 5664 io.piod_op = PIOD_READ_D; 5665 io.piod_len = sizeof(tcb); 5666 5667 do { 5668 io.piod_addr = (char *)&tcb + bytes_read; 5669 io.piod_offs = io.piod_addr; 5670 5671 rv = ptrace(PT_IO, child, &io, sizeof(io)); 5672 ATF_REQUIRE(rv != -1 && io.piod_len != 0); 5673 5674 bytes_read += io.piod_len; 5675 io.piod_len = sizeof(tcb) - bytes_read; 5676 } while (bytes_read < sizeof(tcb)); 5677 5678 for (n = 0; n <= threads; n++) { 5679 if (strstr(iter, "LWPINFO") != NULL) { 5680 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5681 "child\n"); 5682 SYSCALL_REQUIRE( 5683 ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 5684 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5685 5686 DPRINTF("Assert that the thread exists\n"); 5687 ATF_REQUIRE(lwp.pl_lwpid > 0); 5688 5689 DPRINTF("Assert that lwp thread %d received expected " 5690 "event\n", lwp.pl_lwpid); 5691 FORKEE_ASSERT_EQ(lwp.pl_event, 5692 info.psi_lwpid == lwp.pl_lwpid ? 5693 PL_EVENT_SIGNAL : PL_EVENT_NONE); 5694 5695 if (strstr(iter, "LWPSTATUS") != NULL) { 5696 DPRINTF("Before calling ptrace(2) with " 5697 "PT_LWPSTATUS for child\n"); 5698 lwpstatus.pl_lwpid = lwp.pl_lwpid; 5699 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, 5700 &lwpstatus, sizeof(lwpstatus)) != -1); 5701 5702 goto check_lwpstatus; 5703 } 5704 } else { 5705 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for " 5706 "child\n"); 5707 SYSCALL_REQUIRE( 5708 ptrace(PT_LWPNEXT, child, &lwpstatus, 5709 sizeof(lwpstatus)) != -1); 5710 DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid); 5711 5712 DPRINTF("Assert that the thread exists\n"); 5713 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 5714 5715 check_lwpstatus: 5716 5717 if (strstr(iter, "pl_sigmask") != NULL) { 5718 sigmask = lwpstatus.pl_sigmask; 5719 5720 DPRINTF("Retrieved sigmask: " 5721 "%02x%02x%02x%02x\n", 5722 sigmask.__bits[0], sigmask.__bits[1], 5723 sigmask.__bits[2], sigmask.__bits[3]); 5724 5725 found = false; 5726 for (m = 0; 5727 m < __arraycount(lwpinfo_thread_sigmask); 5728 m++) { 5729 if (sigismember(&sigmask, 5730 lwpinfo_thread_sigmask[m])) { 5731 found = true; 5732 lwpinfo_thread_sigmask[m] = 0; 5733 break; 5734 } 5735 } 5736 ATF_REQUIRE(found == true); 5737 } else if (strstr(iter, "pl_name") != NULL) { 5738 name = lwpstatus.pl_name; 5739 5740 DPRINTF("Retrieved thread name: " 5741 "%s\n", name); 5742 5743 snprintf(namebuf, sizeof namebuf, "thread %d", 5744 lwpstatus.pl_lwpid); 5745 5746 ATF_REQUIRE(strcmp(name, namebuf) == 0); 5747 } else if (strstr(iter, "pl_private") != NULL) { 5748 private = lwpstatus.pl_private; 5749 5750 DPRINTF("Retrieved thread private pointer: " 5751 "%p\n", private); 5752 5753 found = false; 5754 for (m = 0; m < __arraycount(tcb); m++) { 5755 DPRINTF("Comparing %p and %p\n", 5756 private, tcb[m]); 5757 if (private == tcb[m]) { 5758 found = true; 5759 break; 5760 } 5761 } 5762 ATF_REQUIRE(found == true); 5763 } 5764 } 5765 } 5766 5767 if (strstr(iter, "LWPINFO") != NULL) { 5768 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5769 "child\n"); 5770 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5771 != -1); 5772 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5773 5774 DPRINTF("Assert that there are no more threads\n"); 5775 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 5776 } else { 5777 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5778 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5779 sizeof(lwpstatus)) != -1); 5780 5781 DPRINTF("Assert that there exists a single thread only\n"); 5782 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 5783 } 5784 5785 DPRINTF("Before resuming the child process where it left off and " 5786 "without signal to be sent\n"); 5787 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 5788 5789 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5790 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5791 5792 validate_status_signaled(status, SIGKILL, 0); 5793 5794 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5795 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5796 } 5797 5798 #define TRACEME_LWPINFO(test, threads, iter) \ 5799 ATF_TC(test); \ 5800 ATF_TC_HEAD(test, tc) \ 5801 { \ 5802 atf_tc_set_md_var(tc, "descr", \ 5803 "Verify " iter " with the child with " #threads \ 5804 " spawned extra threads"); \ 5805 } \ 5806 \ 5807 ATF_TC_BODY(test, tc) \ 5808 { \ 5809 \ 5810 traceme_lwpinfo(threads, iter); \ 5811 } 5812 5813 TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO") 5814 TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO") 5815 TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO") 5816 TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO") 5817 5818 TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS") 5819 TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS") 5820 TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS") 5821 TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS") 5822 5823 TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0, 5824 "LWPINFO+LWPSTATUS+pl_sigmask") 5825 TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1, 5826 "LWPINFO+LWPSTATUS+pl_sigmask") 5827 TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2, 5828 "LWPINFO+LWPSTATUS+pl_sigmask") 5829 TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3, 5830 "LWPINFO+LWPSTATUS+pl_sigmask") 5831 5832 TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0, 5833 "LWPINFO+LWPSTATUS+pl_name") 5834 TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1, 5835 "LWPINFO+LWPSTATUS+pl_name") 5836 TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2, 5837 "LWPINFO+LWPSTATUS+pl_name") 5838 TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3, 5839 "LWPINFO+LWPSTATUS+pl_name") 5840 5841 TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0, 5842 "LWPINFO+LWPSTATUS+pl_private") 5843 TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1, 5844 "LWPINFO+LWPSTATUS+pl_private") 5845 TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2, 5846 "LWPINFO+LWPSTATUS+pl_private") 5847 TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3, 5848 "LWPINFO+LWPSTATUS+pl_private") 5849 5850 TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT") 5851 TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT") 5852 TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT") 5853 TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT") 5854 5855 TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask") 5856 TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask") 5857 TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask") 5858 TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask") 5859 5860 TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name") 5861 TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name") 5862 TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name") 5863 TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name") 5864 5865 TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private") 5866 TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private") 5867 TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private") 5868 TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private") 5869 5870 /// ---------------------------------------------------------------------------- 5871 5872 #if defined(TWAIT_HAVE_PID) 5873 static void 5874 attach_lwpinfo(const int threads) 5875 { 5876 const int sigval = SIGINT; 5877 struct msg_fds parent_tracee, parent_tracer; 5878 const int exitval_tracer = 10; 5879 pid_t tracee, tracer, wpid; 5880 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 5881 #if defined(TWAIT_HAVE_STATUS) 5882 int status; 5883 #endif 5884 struct ptrace_lwpinfo lwp = {0, 0}; 5885 struct ptrace_siginfo info; 5886 5887 /* Maximum number of supported threads in this test */ 5888 pthread_t t[3]; 5889 int n, rv; 5890 5891 DPRINTF("Spawn tracee\n"); 5892 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 5893 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 5894 tracee = atf_utils_fork(); 5895 if (tracee == 0) { 5896 /* Wait for message from the parent */ 5897 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 5898 5899 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 5900 5901 for (n = 0; n < threads; n++) { 5902 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 5903 FORKEE_ASSERT(rv == 0); 5904 } 5905 5906 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 5907 5908 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5909 FORKEE_ASSERT(raise(sigval) == 0); 5910 5911 /* NOTREACHED */ 5912 FORKEE_ASSERTX(0 && "Not reached"); 5913 } 5914 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 5915 5916 DPRINTF("Spawn debugger\n"); 5917 tracer = atf_utils_fork(); 5918 if (tracer == 0) { 5919 /* No IPC to communicate with the child */ 5920 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 5921 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 5922 5923 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 5924 FORKEE_REQUIRE_SUCCESS( 5925 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5926 5927 forkee_status_stopped(status, SIGSTOP); 5928 5929 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5930 "tracee"); 5931 FORKEE_ASSERT( 5932 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5933 5934 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5935 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5936 "si_errno=%#x\n", 5937 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5938 info.psi_siginfo.si_errno); 5939 5940 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 5941 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 5942 5943 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5944 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5945 != -1); 5946 5947 DPRINTF("Assert that there exists a thread\n"); 5948 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 5949 5950 DPRINTF("Assert that lwp thread %d received event " 5951 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 5952 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 5953 5954 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5955 "tracee\n"); 5956 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5957 != -1); 5958 5959 DPRINTF("Assert that there are no more lwp threads in " 5960 "tracee\n"); 5961 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 5962 5963 /* Resume tracee with PT_CONTINUE */ 5964 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 5965 5966 /* Inform parent that tracer has attached to tracee */ 5967 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 5968 5969 /* Wait for parent */ 5970 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 5971 5972 /* Wait for tracee and assert that it raised a signal */ 5973 FORKEE_REQUIRE_SUCCESS( 5974 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5975 5976 forkee_status_stopped(status, SIGINT); 5977 5978 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5979 "child"); 5980 FORKEE_ASSERT( 5981 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5982 5983 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5984 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5985 "si_errno=%#x\n", 5986 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5987 info.psi_siginfo.si_errno); 5988 5989 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 5990 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 5991 5992 memset(&lwp, 0, sizeof(lwp)); 5993 5994 for (n = 0; n <= threads; n++) { 5995 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5996 "child\n"); 5997 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 5998 sizeof(lwp)) != -1); 5999 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 6000 6001 DPRINTF("Assert that the thread exists\n"); 6002 FORKEE_ASSERT(lwp.pl_lwpid > 0); 6003 6004 DPRINTF("Assert that lwp thread %d received expected " 6005 "event\n", lwp.pl_lwpid); 6006 FORKEE_ASSERT_EQ(lwp.pl_event, 6007 info.psi_lwpid == lwp.pl_lwpid ? 6008 PL_EVENT_SIGNAL : PL_EVENT_NONE); 6009 } 6010 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 6011 "tracee\n"); 6012 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 6013 != -1); 6014 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 6015 6016 DPRINTF("Assert that there are no more threads\n"); 6017 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 6018 6019 DPRINTF("Before resuming the child process where it left off " 6020 "and without signal to be sent\n"); 6021 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 6022 != -1); 6023 6024 /* Wait for tracee and assert that it exited */ 6025 FORKEE_REQUIRE_SUCCESS( 6026 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 6027 6028 forkee_status_signaled(status, SIGKILL, 0); 6029 6030 DPRINTF("Before exiting of the tracer process\n"); 6031 _exit(exitval_tracer); 6032 } 6033 6034 DPRINTF("Wait for the tracer to attach to the tracee\n"); 6035 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 6036 6037 DPRINTF("Resume the tracee and spawn threads\n"); 6038 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 6039 6040 DPRINTF("Resume the tracee and let it exit\n"); 6041 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 6042 6043 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 6044 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 6045 6046 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 6047 TWAIT_FNAME); 6048 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 6049 tracer); 6050 6051 validate_status_exited(status, exitval_tracer); 6052 6053 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 6054 TWAIT_FNAME); 6055 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 6056 tracee); 6057 6058 validate_status_signaled(status, SIGKILL, 0); 6059 6060 msg_close(&parent_tracer); 6061 msg_close(&parent_tracee); 6062 } 6063 6064 #define ATTACH_LWPINFO(test, threads) \ 6065 ATF_TC(test); \ 6066 ATF_TC_HEAD(test, tc) \ 6067 { \ 6068 atf_tc_set_md_var(tc, "descr", \ 6069 "Verify LWPINFO with the child with " #threads \ 6070 " spawned extra threads (tracer is not the original " \ 6071 "parent)"); \ 6072 } \ 6073 \ 6074 ATF_TC_BODY(test, tc) \ 6075 { \ 6076 \ 6077 attach_lwpinfo(threads); \ 6078 } 6079 6080 ATTACH_LWPINFO(attach_lwpinfo0, 0) 6081 ATTACH_LWPINFO(attach_lwpinfo1, 1) 6082 ATTACH_LWPINFO(attach_lwpinfo2, 2) 6083 ATTACH_LWPINFO(attach_lwpinfo3, 3) 6084 #endif 6085 6086 /// ---------------------------------------------------------------------------- 6087 6088 static void 6089 ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 6090 { 6091 const int exitval = 5; 6092 const int sigval = SIGINT; 6093 const int sigfaked = SIGTRAP; 6094 const int sicodefaked = TRAP_BRKPT; 6095 pid_t child, wpid; 6096 struct sigaction sa; 6097 #if defined(TWAIT_HAVE_STATUS) 6098 int status; 6099 #endif 6100 struct ptrace_siginfo info; 6101 memset(&info, 0, sizeof(info)); 6102 6103 DPRINTF("Before forking process PID=%d\n", getpid()); 6104 SYSCALL_REQUIRE((child = fork()) != -1); 6105 if (child == 0) { 6106 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6107 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6108 6109 sa.sa_sigaction = sah; 6110 sa.sa_flags = SA_SIGINFO; 6111 sigemptyset(&sa.sa_mask); 6112 6113 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 6114 != -1); 6115 6116 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6117 FORKEE_ASSERT(raise(sigval) == 0); 6118 6119 FORKEE_ASSERT_EQ(*signal_caught, 1); 6120 6121 DPRINTF("Before exiting of the child process\n"); 6122 _exit(exitval); 6123 } 6124 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6125 6126 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6127 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6128 6129 validate_status_stopped(status, sigval); 6130 6131 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6132 SYSCALL_REQUIRE( 6133 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6134 6135 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6136 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6137 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6138 info.psi_siginfo.si_errno); 6139 6140 if (faked) { 6141 DPRINTF("Before setting new faked signal to signo=%d " 6142 "si_code=%d\n", sigfaked, sicodefaked); 6143 info.psi_siginfo.si_signo = sigfaked; 6144 info.psi_siginfo.si_code = sicodefaked; 6145 } 6146 6147 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 6148 SYSCALL_REQUIRE( 6149 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 6150 6151 if (faked) { 6152 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6153 "child\n"); 6154 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 6155 sizeof(info)) != -1); 6156 6157 DPRINTF("Before checking siginfo_t\n"); 6158 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 6159 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 6160 } 6161 6162 DPRINTF("Before resuming the child process where it left off and " 6163 "without signal to be sent\n"); 6164 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 6165 faked ? sigfaked : sigval) != -1); 6166 6167 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6168 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6169 6170 validate_status_exited(status, exitval); 6171 6172 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6173 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6174 } 6175 6176 #define PTRACE_SIGINFO(test, faked) \ 6177 ATF_TC(test); \ 6178 ATF_TC_HEAD(test, tc) \ 6179 { \ 6180 atf_tc_set_md_var(tc, "descr", \ 6181 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 6182 "with%s setting signal to new value", faked ? "" : "out"); \ 6183 } \ 6184 \ 6185 static int test##_caught = 0; \ 6186 \ 6187 static void \ 6188 test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 6189 { \ 6190 if (faked) { \ 6191 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 6192 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 6193 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 6194 } else { \ 6195 FORKEE_ASSERT_EQ(sig, SIGINT); \ 6196 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 6197 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 6198 } \ 6199 \ 6200 ++ test##_caught; \ 6201 } \ 6202 \ 6203 ATF_TC_BODY(test, tc) \ 6204 { \ 6205 \ 6206 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 6207 } 6208 6209 PTRACE_SIGINFO(siginfo_set_unmodified, false) 6210 PTRACE_SIGINFO(siginfo_set_faked, true) 6211 6212 /// ---------------------------------------------------------------------------- 6213 6214 static void 6215 traceme_exec(bool masked, bool ignored) 6216 { 6217 const int sigval = SIGTRAP; 6218 pid_t child, wpid; 6219 #if defined(TWAIT_HAVE_STATUS) 6220 int status; 6221 #endif 6222 struct sigaction sa; 6223 struct ptrace_siginfo info; 6224 sigset_t intmask; 6225 struct kinfo_proc2 kp; 6226 size_t len = sizeof(kp); 6227 6228 int name[6]; 6229 const size_t namelen = __arraycount(name); 6230 ki_sigset_t kp_sigmask; 6231 ki_sigset_t kp_sigignore; 6232 6233 memset(&info, 0, sizeof(info)); 6234 6235 DPRINTF("Before forking process PID=%d\n", getpid()); 6236 SYSCALL_REQUIRE((child = fork()) != -1); 6237 if (child == 0) { 6238 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6239 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6240 6241 if (masked) { 6242 sigemptyset(&intmask); 6243 sigaddset(&intmask, sigval); 6244 sigprocmask(SIG_BLOCK, &intmask, NULL); 6245 } 6246 6247 if (ignored) { 6248 memset(&sa, 0, sizeof(sa)); 6249 sa.sa_handler = SIG_IGN; 6250 sigemptyset(&sa.sa_mask); 6251 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 6252 } 6253 6254 DPRINTF("Before calling execve(2) from child\n"); 6255 execlp("/bin/echo", "/bin/echo", NULL); 6256 6257 FORKEE_ASSERT(0 && "Not reached"); 6258 } 6259 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6260 6261 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6262 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6263 6264 validate_status_stopped(status, sigval); 6265 6266 name[0] = CTL_KERN, 6267 name[1] = KERN_PROC2, 6268 name[2] = KERN_PROC_PID; 6269 name[3] = getpid(); 6270 name[4] = sizeof(kp); 6271 name[5] = 1; 6272 6273 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6274 6275 if (masked) 6276 kp_sigmask = kp.p_sigmask; 6277 6278 if (ignored) 6279 kp_sigignore = kp.p_sigignore; 6280 6281 name[3] = getpid(); 6282 6283 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6284 6285 if (masked) { 6286 DPRINTF("kp_sigmask=" 6287 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 6288 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6289 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6290 6291 DPRINTF("kp.p_sigmask=" 6292 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 6293 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6294 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6295 6296 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6297 sizeof(kp_sigmask))); 6298 } 6299 6300 if (ignored) { 6301 DPRINTF("kp_sigignore=" 6302 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 6303 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6304 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6305 6306 DPRINTF("kp.p_sigignore=" 6307 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 6308 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6309 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6310 6311 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6312 sizeof(kp_sigignore))); 6313 } 6314 6315 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6316 SYSCALL_REQUIRE( 6317 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6318 6319 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6320 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6321 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6322 info.psi_siginfo.si_errno); 6323 6324 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6325 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 6326 6327 DPRINTF("Before resuming the child process where it left off and " 6328 "without signal to be sent\n"); 6329 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6330 6331 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6332 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6333 6334 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6335 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6336 } 6337 6338 #define TRACEME_EXEC(test, masked, ignored) \ 6339 ATF_TC(test); \ 6340 ATF_TC_HEAD(test, tc) \ 6341 { \ 6342 atf_tc_set_md_var(tc, "descr", \ 6343 "Detect SIGTRAP TRAP_EXEC from " \ 6344 "child%s%s", masked ? " with masked signal" : "", \ 6345 masked ? " with ignored signal" : ""); \ 6346 } \ 6347 \ 6348 ATF_TC_BODY(test, tc) \ 6349 { \ 6350 \ 6351 traceme_exec(masked, ignored); \ 6352 } 6353 6354 TRACEME_EXEC(traceme_exec, false, false) 6355 TRACEME_EXEC(traceme_signalmasked_exec, true, false) 6356 TRACEME_EXEC(traceme_signalignored_exec, false, true) 6357 6358 /// ---------------------------------------------------------------------------- 6359 6360 #define TRACE_THREADS_NUM 100 6361 6362 static volatile int done; 6363 pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 6364 6365 static void * 6366 trace_threads_cb(void *arg __unused) 6367 { 6368 6369 pthread_mutex_lock(&trace_threads_mtx); 6370 done++; 6371 pthread_mutex_unlock(&trace_threads_mtx); 6372 6373 while (done < TRACE_THREADS_NUM) 6374 sched_yield(); 6375 6376 return NULL; 6377 } 6378 6379 static void 6380 trace_threads(bool trace_create, bool trace_exit, bool masked) 6381 { 6382 const int sigval = SIGSTOP; 6383 pid_t child, wpid; 6384 #if defined(TWAIT_HAVE_STATUS) 6385 int status; 6386 #endif 6387 ptrace_state_t state; 6388 const int slen = sizeof(state); 6389 ptrace_event_t event; 6390 const int elen = sizeof(event); 6391 struct ptrace_siginfo info; 6392 6393 sigset_t intmask; 6394 6395 pthread_t t[TRACE_THREADS_NUM]; 6396 int rv; 6397 size_t n; 6398 lwpid_t lid; 6399 6400 /* Track created and exited threads */ 6401 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 6402 6403 DPRINTF("Before forking process PID=%d\n", getpid()); 6404 SYSCALL_REQUIRE((child = fork()) != -1); 6405 if (child == 0) { 6406 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6407 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6408 6409 if (masked) { 6410 sigemptyset(&intmask); 6411 sigaddset(&intmask, SIGTRAP); 6412 sigprocmask(SIG_BLOCK, &intmask, NULL); 6413 } 6414 6415 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6416 FORKEE_ASSERT(raise(sigval) == 0); 6417 6418 for (n = 0; n < __arraycount(t); n++) { 6419 rv = pthread_create(&t[n], NULL, trace_threads_cb, 6420 NULL); 6421 FORKEE_ASSERT(rv == 0); 6422 } 6423 6424 for (n = 0; n < __arraycount(t); n++) { 6425 rv = pthread_join(t[n], NULL); 6426 FORKEE_ASSERT(rv == 0); 6427 } 6428 6429 /* 6430 * There is race between _exit() and pthread_join() detaching 6431 * a thread. For simplicity kill the process after detecting 6432 * LWP events. 6433 */ 6434 while (true) 6435 continue; 6436 6437 FORKEE_ASSERT(0 && "Not reached"); 6438 } 6439 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6440 6441 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6442 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6443 6444 validate_status_stopped(status, sigval); 6445 6446 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6447 SYSCALL_REQUIRE( 6448 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6449 6450 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6451 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6452 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6453 info.psi_siginfo.si_errno); 6454 6455 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6456 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6457 6458 DPRINTF("Set LWP event mask for the child %d\n", child); 6459 memset(&event, 0, sizeof(event)); 6460 if (trace_create) 6461 event.pe_set_event |= PTRACE_LWP_CREATE; 6462 if (trace_exit) 6463 event.pe_set_event |= PTRACE_LWP_EXIT; 6464 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6465 6466 DPRINTF("Before resuming the child process where it left off and " 6467 "without signal to be sent\n"); 6468 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6469 6470 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 6471 DPRINTF("Before calling %s() for the child - expected stopped " 6472 "SIGTRAP\n", TWAIT_FNAME); 6473 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6474 child); 6475 6476 validate_status_stopped(status, SIGTRAP); 6477 6478 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6479 "child\n"); 6480 SYSCALL_REQUIRE( 6481 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6482 6483 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6484 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 6485 "si_errno=%#x\n", 6486 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6487 info.psi_siginfo.si_errno); 6488 6489 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6490 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 6491 6492 SYSCALL_REQUIRE( 6493 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6494 6495 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 6496 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 6497 6498 lid = state.pe_lwp; 6499 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 6500 6501 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 6502 6503 DPRINTF("Before resuming the child process where it left off " 6504 "and without signal to be sent\n"); 6505 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6506 } 6507 6508 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 6509 DPRINTF("Before calling %s() for the child - expected stopped " 6510 "SIGTRAP\n", TWAIT_FNAME); 6511 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6512 child); 6513 6514 validate_status_stopped(status, SIGTRAP); 6515 6516 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6517 "child\n"); 6518 SYSCALL_REQUIRE( 6519 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6520 6521 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6522 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 6523 "si_errno=%#x\n", 6524 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6525 info.psi_siginfo.si_errno); 6526 6527 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6528 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 6529 6530 SYSCALL_REQUIRE( 6531 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6532 6533 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 6534 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 6535 6536 lid = state.pe_lwp; 6537 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 6538 6539 if (trace_create) { 6540 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 6541 ATF_REQUIRE_EQ(*count, 1); 6542 *count = 0; 6543 } 6544 6545 DPRINTF("Before resuming the child process where it left off " 6546 "and without signal to be sent\n"); 6547 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6548 } 6549 6550 kill(child, SIGKILL); 6551 6552 DPRINTF("Before calling %s() for the child - expected exited\n", 6553 TWAIT_FNAME); 6554 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6555 6556 validate_status_signaled(status, SIGKILL, 0); 6557 6558 DPRINTF("Before calling %s() for the child - expected no process\n", 6559 TWAIT_FNAME); 6560 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6561 } 6562 6563 #define TRACE_THREADS(test, trace_create, trace_exit, mask) \ 6564 ATF_TC(test); \ 6565 ATF_TC_HEAD(test, tc) \ 6566 { \ 6567 atf_tc_set_md_var(tc, "descr", \ 6568 "Verify spawning threads with%s tracing LWP create and" \ 6569 "with%s tracing LWP exit", trace_create ? "" : "out", \ 6570 trace_exit ? "" : "out"); \ 6571 } \ 6572 \ 6573 ATF_TC_BODY(test, tc) \ 6574 { \ 6575 \ 6576 trace_threads(trace_create, trace_exit, mask); \ 6577 } 6578 6579 TRACE_THREADS(trace_thread_nolwpevents, false, false, false) 6580 TRACE_THREADS(trace_thread_lwpexit, false, true, false) 6581 TRACE_THREADS(trace_thread_lwpcreate, true, false, false) 6582 TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false) 6583 6584 TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true) 6585 TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true) 6586 TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true) 6587 6588 /// ---------------------------------------------------------------------------- 6589 6590 ATF_TC(signal_mask_unrelated); 6591 ATF_TC_HEAD(signal_mask_unrelated, tc) 6592 { 6593 atf_tc_set_md_var(tc, "descr", 6594 "Verify that masking single unrelated signal does not stop tracer " 6595 "from catching other signals"); 6596 } 6597 6598 ATF_TC_BODY(signal_mask_unrelated, tc) 6599 { 6600 const int exitval = 5; 6601 const int sigval = SIGSTOP; 6602 const int sigmasked = SIGTRAP; 6603 const int signotmasked = SIGINT; 6604 pid_t child, wpid; 6605 #if defined(TWAIT_HAVE_STATUS) 6606 int status; 6607 #endif 6608 sigset_t intmask; 6609 6610 DPRINTF("Before forking process PID=%d\n", getpid()); 6611 SYSCALL_REQUIRE((child = fork()) != -1); 6612 if (child == 0) { 6613 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6614 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6615 6616 sigemptyset(&intmask); 6617 sigaddset(&intmask, sigmasked); 6618 sigprocmask(SIG_BLOCK, &intmask, NULL); 6619 6620 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6621 FORKEE_ASSERT(raise(sigval) == 0); 6622 6623 DPRINTF("Before raising %s from child\n", 6624 strsignal(signotmasked)); 6625 FORKEE_ASSERT(raise(signotmasked) == 0); 6626 6627 DPRINTF("Before exiting of the child process\n"); 6628 _exit(exitval); 6629 } 6630 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6631 6632 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6633 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6634 6635 validate_status_stopped(status, sigval); 6636 6637 DPRINTF("Before resuming the child process where it left off and " 6638 "without signal to be sent\n"); 6639 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6640 6641 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6642 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6643 6644 validate_status_stopped(status, signotmasked); 6645 6646 DPRINTF("Before resuming the child process where it left off and " 6647 "without signal to be sent\n"); 6648 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6649 6650 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6651 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6652 6653 validate_status_exited(status, exitval); 6654 6655 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6656 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6657 } 6658 6659 /// ---------------------------------------------------------------------------- 6660 6661 #if defined(TWAIT_HAVE_PID) 6662 static void 6663 fork2_body(const char *fn, bool masked, bool ignored) 6664 { 6665 const int exitval = 5; 6666 const int exitval2 = 0; /* Match exit status from /bin/echo */ 6667 const int sigval = SIGSTOP; 6668 pid_t child, child2 = 0, wpid; 6669 #if defined(TWAIT_HAVE_STATUS) 6670 int status; 6671 #endif 6672 ptrace_state_t state; 6673 const int slen = sizeof(state); 6674 ptrace_event_t event; 6675 const int elen = sizeof(event); 6676 struct sigaction sa; 6677 struct ptrace_siginfo info; 6678 sigset_t intmask; 6679 struct kinfo_proc2 kp; 6680 size_t len = sizeof(kp); 6681 6682 int name[6]; 6683 const size_t namelen = __arraycount(name); 6684 ki_sigset_t kp_sigmask; 6685 ki_sigset_t kp_sigignore; 6686 6687 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 6688 6689 DPRINTF("Before forking process PID=%d\n", getpid()); 6690 SYSCALL_REQUIRE((child = fork()) != -1); 6691 if (child == 0) { 6692 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6693 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6694 6695 if (masked) { 6696 sigemptyset(&intmask); 6697 sigaddset(&intmask, SIGTRAP); 6698 sigprocmask(SIG_BLOCK, &intmask, NULL); 6699 } 6700 6701 if (ignored) { 6702 memset(&sa, 0, sizeof(sa)); 6703 sa.sa_handler = SIG_IGN; 6704 sigemptyset(&sa.sa_mask); 6705 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 6706 } 6707 6708 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6709 FORKEE_ASSERT(raise(sigval) == 0); 6710 6711 if (strcmp(fn, "spawn") == 0) { 6712 FORKEE_ASSERT_EQ(posix_spawn(&child2, 6713 arg[0], NULL, NULL, arg, NULL), 0); 6714 } else { 6715 if (strcmp(fn, "fork") == 0) { 6716 FORKEE_ASSERT((child2 = fork()) != -1); 6717 } else { 6718 FORKEE_ASSERT((child2 = vfork()) != -1); 6719 } 6720 if (child2 == 0) 6721 _exit(exitval2); 6722 } 6723 6724 FORKEE_REQUIRE_SUCCESS 6725 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6726 6727 forkee_status_exited(status, exitval2); 6728 6729 DPRINTF("Before exiting of the child process\n"); 6730 _exit(exitval); 6731 } 6732 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6733 6734 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6735 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6736 6737 validate_status_stopped(status, sigval); 6738 6739 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6740 SYSCALL_REQUIRE( 6741 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6742 6743 DPRINTF("Before checking siginfo_t\n"); 6744 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6745 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6746 6747 name[0] = CTL_KERN, 6748 name[1] = KERN_PROC2, 6749 name[2] = KERN_PROC_PID; 6750 name[3] = child; 6751 name[4] = sizeof(kp); 6752 name[5] = 1; 6753 6754 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6755 6756 if (masked) 6757 kp_sigmask = kp.p_sigmask; 6758 6759 if (ignored) 6760 kp_sigignore = kp.p_sigignore; 6761 6762 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 6763 strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "", 6764 strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "", 6765 strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "", 6766 strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child); 6767 event.pe_set_event = 0; 6768 if (strcmp(fn, "spawn") == 0) 6769 event.pe_set_event |= PTRACE_POSIX_SPAWN; 6770 if (strcmp(fn, "fork") == 0) 6771 event.pe_set_event |= PTRACE_FORK; 6772 if (strcmp(fn, "vfork") == 0) 6773 event.pe_set_event |= PTRACE_VFORK; 6774 if (strcmp(fn, "vforkdone") == 0) 6775 event.pe_set_event |= PTRACE_VFORK_DONE; 6776 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6777 6778 DPRINTF("Before resuming the child process where it left off and " 6779 "without signal to be sent\n"); 6780 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6781 6782 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6783 strcmp(fn, "vfork") == 0) { 6784 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6785 child); 6786 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6787 child); 6788 6789 validate_status_stopped(status, SIGTRAP); 6790 6791 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6792 6793 if (masked) { 6794 DPRINTF("kp_sigmask=" 6795 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6796 PRIx32 "\n", 6797 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6798 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6799 6800 DPRINTF("kp.p_sigmask=" 6801 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6802 PRIx32 "\n", 6803 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6804 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6805 6806 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6807 sizeof(kp_sigmask))); 6808 } 6809 6810 if (ignored) { 6811 DPRINTF("kp_sigignore=" 6812 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6813 PRIx32 "\n", 6814 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6815 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6816 6817 DPRINTF("kp.p_sigignore=" 6818 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6819 PRIx32 "\n", 6820 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6821 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6822 6823 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6824 sizeof(kp_sigignore))); 6825 } 6826 6827 SYSCALL_REQUIRE( 6828 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6829 if (strcmp(fn, "spawn") == 0) { 6830 ATF_REQUIRE_EQ( 6831 state.pe_report_event & PTRACE_POSIX_SPAWN, 6832 PTRACE_POSIX_SPAWN); 6833 } 6834 if (strcmp(fn, "fork") == 0) { 6835 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6836 PTRACE_FORK); 6837 } 6838 if (strcmp(fn, "vfork") == 0) { 6839 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6840 PTRACE_VFORK); 6841 } 6842 6843 child2 = state.pe_other_pid; 6844 DPRINTF("Reported ptrace event with forkee %d\n", child2); 6845 6846 DPRINTF("Before calling %s() for the forkee %d of the child " 6847 "%d\n", TWAIT_FNAME, child2, child); 6848 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 6849 child2); 6850 6851 validate_status_stopped(status, SIGTRAP); 6852 6853 name[3] = child2; 6854 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6855 6856 if (masked) { 6857 DPRINTF("kp_sigmask=" 6858 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6859 PRIx32 "\n", 6860 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6861 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6862 6863 DPRINTF("kp.p_sigmask=" 6864 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6865 PRIx32 "\n", 6866 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6867 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6868 6869 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6870 sizeof(kp_sigmask))); 6871 } 6872 6873 if (ignored) { 6874 DPRINTF("kp_sigignore=" 6875 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6876 PRIx32 "\n", 6877 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6878 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6879 6880 DPRINTF("kp.p_sigignore=" 6881 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6882 PRIx32 "\n", 6883 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6884 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6885 6886 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6887 sizeof(kp_sigignore))); 6888 } 6889 6890 SYSCALL_REQUIRE( 6891 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 6892 if (strcmp(fn, "spawn") == 0) { 6893 ATF_REQUIRE_EQ( 6894 state.pe_report_event & PTRACE_POSIX_SPAWN, 6895 PTRACE_POSIX_SPAWN); 6896 } 6897 if (strcmp(fn, "fork") == 0) { 6898 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6899 PTRACE_FORK); 6900 } 6901 if (strcmp(fn, "vfork") == 0) { 6902 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6903 PTRACE_VFORK); 6904 } 6905 6906 ATF_REQUIRE_EQ(state.pe_other_pid, child); 6907 6908 DPRINTF("Before resuming the forkee process where it left off " 6909 "and without signal to be sent\n"); 6910 SYSCALL_REQUIRE( 6911 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6912 6913 DPRINTF("Before resuming the child process where it left off " 6914 "and without signal to be sent\n"); 6915 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6916 } 6917 6918 if (strcmp(fn, "vforkdone") == 0) { 6919 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6920 child); 6921 TWAIT_REQUIRE_SUCCESS( 6922 wpid = TWAIT_GENERIC(child, &status, 0), child); 6923 6924 validate_status_stopped(status, SIGTRAP); 6925 6926 name[3] = child; 6927 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6928 6929 /* 6930 * SIGCHLD is now pending in the signal queue and 6931 * the kernel presents it to userland as a masked signal. 6932 */ 6933 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 6934 6935 if (masked) { 6936 DPRINTF("kp_sigmask=" 6937 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6938 PRIx32 "\n", 6939 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6940 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6941 6942 DPRINTF("kp.p_sigmask=" 6943 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6944 PRIx32 "\n", 6945 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6946 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6947 6948 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6949 sizeof(kp_sigmask))); 6950 } 6951 6952 if (ignored) { 6953 DPRINTF("kp_sigignore=" 6954 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6955 PRIx32 "\n", 6956 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6957 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6958 6959 DPRINTF("kp.p_sigignore=" 6960 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6961 PRIx32 "\n", 6962 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6963 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6964 6965 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6966 sizeof(kp_sigignore))); 6967 } 6968 6969 SYSCALL_REQUIRE( 6970 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6971 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6972 6973 child2 = state.pe_other_pid; 6974 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6975 child2); 6976 6977 DPRINTF("Before resuming the child process where it left off " 6978 "and without signal to be sent\n"); 6979 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6980 } 6981 6982 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6983 strcmp(fn, "vfork") == 0) { 6984 DPRINTF("Before calling %s() for the forkee - expected exited" 6985 "\n", TWAIT_FNAME); 6986 TWAIT_REQUIRE_SUCCESS( 6987 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6988 6989 validate_status_exited(status, exitval2); 6990 6991 DPRINTF("Before calling %s() for the forkee - expected no " 6992 "process\n", TWAIT_FNAME); 6993 TWAIT_REQUIRE_FAILURE(ECHILD, 6994 wpid = TWAIT_GENERIC(child2, &status, 0)); 6995 } 6996 6997 DPRINTF("Before calling %s() for the child - expected stopped " 6998 "SIGCHLD\n", TWAIT_FNAME); 6999 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7000 7001 validate_status_stopped(status, SIGCHLD); 7002 7003 DPRINTF("Before resuming the child process where it left off and " 7004 "without signal to be sent\n"); 7005 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7006 7007 DPRINTF("Before calling %s() for the child - expected exited\n", 7008 TWAIT_FNAME); 7009 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7010 7011 validate_status_exited(status, exitval); 7012 7013 DPRINTF("Before calling %s() for the child - expected no process\n", 7014 TWAIT_FNAME); 7015 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7016 } 7017 7018 #define FORK2_TEST(name,fn,masked,ignored) \ 7019 ATF_TC(name); \ 7020 ATF_TC_HEAD(name, tc) \ 7021 { \ 7022 atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught " \ 7023 "regardless of signal %s%s", \ 7024 masked ? "masked" : "", ignored ? "ignored" : ""); \ 7025 } \ 7026 \ 7027 ATF_TC_BODY(name, tc) \ 7028 { \ 7029 \ 7030 fork2_body(fn, masked, ignored); \ 7031 } 7032 7033 FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false) 7034 FORK2_TEST(posix_spawn_singalignored, "spawn", false, true) 7035 FORK2_TEST(fork_singalmasked, "fork", true, false) 7036 FORK2_TEST(fork_singalignored, "fork", false, true) 7037 FORK2_TEST(vfork_singalmasked, "vfork", true, false) 7038 FORK2_TEST(vfork_singalignored, "vfork", false, true) 7039 FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false) 7040 FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true) 7041 #endif 7042 7043 /// ---------------------------------------------------------------------------- 7044 7045 static void * 7046 thread_and_exec_thread_cb(void *arg __unused) 7047 { 7048 7049 execlp("/bin/echo", "/bin/echo", NULL); 7050 7051 abort(); 7052 } 7053 7054 static void 7055 threads_and_exec(void) 7056 { 7057 const int sigval = SIGSTOP; 7058 pid_t child, wpid; 7059 #if defined(TWAIT_HAVE_STATUS) 7060 int status; 7061 #endif 7062 ptrace_state_t state; 7063 const int slen = sizeof(state); 7064 ptrace_event_t event; 7065 const int elen = sizeof(event); 7066 struct ptrace_siginfo info; 7067 7068 pthread_t t; 7069 lwpid_t lid; 7070 7071 DPRINTF("Before forking process PID=%d\n", getpid()); 7072 SYSCALL_REQUIRE((child = fork()) != -1); 7073 if (child == 0) { 7074 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7075 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7076 7077 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7078 FORKEE_ASSERT(raise(sigval) == 0); 7079 7080 FORKEE_ASSERT(pthread_create(&t, NULL, 7081 thread_and_exec_thread_cb, NULL) == 0); 7082 7083 for (;;) 7084 continue; 7085 7086 FORKEE_ASSERT(0 && "Not reached"); 7087 } 7088 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7089 7090 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7091 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7092 7093 validate_status_stopped(status, sigval); 7094 7095 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7096 SYSCALL_REQUIRE( 7097 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7098 7099 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7100 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 7101 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7102 info.psi_siginfo.si_errno); 7103 7104 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7105 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7106 7107 DPRINTF("Set LWP event mask for the child %d\n", child); 7108 memset(&event, 0, sizeof(event)); 7109 event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; 7110 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7111 7112 DPRINTF("Before resuming the child process where it left off and " 7113 "without signal to be sent\n"); 7114 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7115 7116 DPRINTF("Before calling %s() for the child - expected stopped " 7117 "SIGTRAP\n", TWAIT_FNAME); 7118 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7119 child); 7120 7121 validate_status_stopped(status, SIGTRAP); 7122 7123 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7124 "child\n"); 7125 SYSCALL_REQUIRE( 7126 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7127 7128 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7129 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7130 "si_errno=%#x\n", 7131 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7132 info.psi_siginfo.si_errno); 7133 7134 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 7135 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 7136 7137 SYSCALL_REQUIRE( 7138 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7139 7140 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 7141 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 7142 7143 lid = state.pe_lwp; 7144 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 7145 7146 DPRINTF("Before resuming the child process where it left off " 7147 "and without signal to be sent\n"); 7148 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7149 7150 DPRINTF("Before calling %s() for the child - expected stopped " 7151 "SIGTRAP\n", TWAIT_FNAME); 7152 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7153 child); 7154 7155 validate_status_stopped(status, SIGTRAP); 7156 7157 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7158 "child\n"); 7159 SYSCALL_REQUIRE( 7160 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7161 7162 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7163 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7164 "si_errno=%#x\n", 7165 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7166 info.psi_siginfo.si_errno); 7167 7168 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 7169 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 7170 7171 SYSCALL_REQUIRE( 7172 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7173 7174 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 7175 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 7176 7177 lid = state.pe_lwp; 7178 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 7179 7180 DPRINTF("Before resuming the child process where it left off " 7181 "and without signal to be sent\n"); 7182 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7183 7184 DPRINTF("Before calling %s() for the child - expected stopped " 7185 "SIGTRAP\n", TWAIT_FNAME); 7186 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7187 child); 7188 7189 validate_status_stopped(status, SIGTRAP); 7190 7191 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7192 "child\n"); 7193 SYSCALL_REQUIRE( 7194 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7195 7196 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7197 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7198 "si_errno=%#x\n", 7199 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7200 info.psi_siginfo.si_errno); 7201 7202 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 7203 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 7204 7205 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 7206 7207 DPRINTF("Before calling %s() for the child - expected exited\n", 7208 TWAIT_FNAME); 7209 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7210 7211 validate_status_signaled(status, SIGKILL, 0); 7212 7213 DPRINTF("Before calling %s() for the child - expected no process\n", 7214 TWAIT_FNAME); 7215 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7216 } 7217 7218 ATF_TC(threads_and_exec); 7219 ATF_TC_HEAD(threads_and_exec, tc) 7220 { 7221 atf_tc_set_md_var(tc, "descr", 7222 "Verify that multithreaded application on exec() will report " 7223 "LWP_EXIT events"); 7224 } 7225 7226 ATF_TC_BODY(threads_and_exec, tc) 7227 { 7228 7229 threads_and_exec(); 7230 } 7231 7232 /// ---------------------------------------------------------------------------- 7233 7234 ATF_TC(suspend_no_deadlock); 7235 ATF_TC_HEAD(suspend_no_deadlock, tc) 7236 { 7237 atf_tc_set_md_var(tc, "descr", 7238 "Verify that the while the only thread within a process is " 7239 "suspended, the whole process cannot be unstopped"); 7240 } 7241 7242 ATF_TC_BODY(suspend_no_deadlock, tc) 7243 { 7244 const int exitval = 5; 7245 const int sigval = SIGSTOP; 7246 pid_t child, wpid; 7247 #if defined(TWAIT_HAVE_STATUS) 7248 int status; 7249 #endif 7250 struct ptrace_siginfo psi; 7251 7252 DPRINTF("Before forking process PID=%d\n", getpid()); 7253 SYSCALL_REQUIRE((child = fork()) != -1); 7254 if (child == 0) { 7255 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7256 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7257 7258 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7259 FORKEE_ASSERT(raise(sigval) == 0); 7260 7261 DPRINTF("Before exiting of the child process\n"); 7262 _exit(exitval); 7263 } 7264 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7265 7266 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7267 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7268 7269 validate_status_stopped(status, sigval); 7270 7271 DPRINTF("Before reading siginfo and lwpid_t\n"); 7272 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 7273 7274 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 7275 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 7276 7277 DPRINTF("Before resuming the child process where it left off and " 7278 "without signal to be sent\n"); 7279 ATF_REQUIRE_ERRNO(EDEADLK, 7280 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 7281 7282 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 7283 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 7284 7285 DPRINTF("Before resuming the child process where it left off and " 7286 "without signal to be sent\n"); 7287 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7288 7289 DPRINTF("Before calling %s() for the child - expected exited\n", 7290 TWAIT_FNAME); 7291 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7292 7293 validate_status_exited(status, exitval); 7294 7295 DPRINTF("Before calling %s() for the child - expected no process\n", 7296 TWAIT_FNAME); 7297 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7298 } 7299 7300 /// ---------------------------------------------------------------------------- 7301 7302 static pthread_barrier_t barrier1_resume; 7303 static pthread_barrier_t barrier2_resume; 7304 7305 static void * 7306 resume_thread(void *arg) 7307 { 7308 7309 raise(SIGUSR1); 7310 7311 pthread_barrier_wait(&barrier1_resume); 7312 7313 /* Debugger will suspend the process here */ 7314 7315 pthread_barrier_wait(&barrier2_resume); 7316 7317 raise(SIGUSR2); 7318 7319 return infinite_thread(arg); 7320 } 7321 7322 ATF_TC(resume); 7323 ATF_TC_HEAD(resume, tc) 7324 { 7325 atf_tc_set_md_var(tc, "descr", 7326 "Verify that a thread can be suspended by a debugger and later " 7327 "resumed by the debugger"); 7328 } 7329 7330 ATF_TC_BODY(resume, tc) 7331 { 7332 const int sigval = SIGSTOP; 7333 pid_t child, wpid; 7334 #if defined(TWAIT_HAVE_STATUS) 7335 int status; 7336 #endif 7337 lwpid_t lid; 7338 struct ptrace_siginfo psi; 7339 pthread_t t; 7340 7341 DPRINTF("Before forking process PID=%d\n", getpid()); 7342 SYSCALL_REQUIRE((child = fork()) != -1); 7343 if (child == 0) { 7344 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7345 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7346 7347 pthread_barrier_init(&barrier1_resume, NULL, 2); 7348 pthread_barrier_init(&barrier2_resume, NULL, 2); 7349 7350 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7351 FORKEE_ASSERT(raise(sigval) == 0); 7352 7353 DPRINTF("Before creating new thread in child\n"); 7354 FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0); 7355 7356 pthread_barrier_wait(&barrier1_resume); 7357 7358 pthread_barrier_wait(&barrier2_resume); 7359 7360 infinite_thread(NULL); 7361 } 7362 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7363 7364 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7365 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7366 7367 validate_status_stopped(status, sigval); 7368 7369 DPRINTF("Before resuming the child process where it left off and " 7370 "without signal to be sent\n"); 7371 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7372 7373 DPRINTF("Before calling %s() for the child - expected stopped " 7374 "SIGUSR1\n", TWAIT_FNAME); 7375 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7376 7377 validate_status_stopped(status, SIGUSR1); 7378 7379 DPRINTF("Before reading siginfo and lwpid_t\n"); 7380 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 7381 7382 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 7383 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 7384 7385 lid = psi.psi_lwpid; 7386 7387 DPRINTF("Before resuming the child process where it left off and " 7388 "without signal to be sent\n"); 7389 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7390 7391 DPRINTF("Before suspending the parent for 1 second, we expect no signals\n"); 7392 SYSCALL_REQUIRE(sleep(1) == 0); 7393 7394 #if defined(TWAIT_HAVE_OPTIONS) 7395 DPRINTF("Before calling %s() for the child - expected no status\n", 7396 TWAIT_FNAME); 7397 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0); 7398 #endif 7399 7400 DPRINTF("Before resuming the child process where it left off and " 7401 "without signal to be sent\n"); 7402 SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1); 7403 7404 DPRINTF("Before calling %s() for the child - expected stopped " 7405 "SIGSTOP\n", TWAIT_FNAME); 7406 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7407 7408 validate_status_stopped(status, SIGSTOP); 7409 7410 DPRINTF("Before resuming LWP %d\n", lid); 7411 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1); 7412 7413 DPRINTF("Before resuming the child process where it left off and " 7414 "without signal to be sent\n"); 7415 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7416 7417 DPRINTF("Before calling %s() for the child - expected stopped " 7418 "SIGUSR2\n", TWAIT_FNAME); 7419 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7420 7421 validate_status_stopped(status, SIGUSR2); 7422 7423 DPRINTF("Before resuming the child process where it left off and " 7424 "without signal to be sent\n"); 7425 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 7426 7427 DPRINTF("Before calling %s() for the child - expected exited\n", 7428 TWAIT_FNAME); 7429 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7430 7431 validate_status_signaled(status, SIGKILL, 0); 7432 7433 DPRINTF("Before calling %s() for the child - expected no process\n", 7434 TWAIT_FNAME); 7435 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7436 } 7437 7438 /// ---------------------------------------------------------------------------- 7439 7440 static int test_syscall_caught; 7441 7442 static void 7443 syscall_sighand(int arg) 7444 { 7445 7446 DPRINTF("Caught a signal %d in process %d\n", arg, getpid()); 7447 7448 FORKEE_ASSERT_EQ(arg, SIGINFO); 7449 7450 ++test_syscall_caught; 7451 7452 FORKEE_ASSERT_EQ(test_syscall_caught, 1); 7453 } 7454 7455 static void 7456 syscall_body(const char *op) 7457 { 7458 const int exitval = 5; 7459 const int sigval = SIGSTOP; 7460 pid_t child, wpid; 7461 #if defined(TWAIT_HAVE_STATUS) 7462 int status; 7463 #endif 7464 struct ptrace_siginfo info; 7465 7466 memset(&info, 0, sizeof(info)); 7467 7468 #if defined(TWAIT_HAVE_STATUS) 7469 if (strstr(op, "signal") != NULL) { 7470 atf_tc_expect_fail("XXX: behavior under investigation"); 7471 } 7472 #endif 7473 7474 DPRINTF("Before forking process PID=%d\n", getpid()); 7475 SYSCALL_REQUIRE((child = fork()) != -1); 7476 if (child == 0) { 7477 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7478 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7479 7480 signal(SIGINFO, syscall_sighand); 7481 7482 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7483 FORKEE_ASSERT(raise(sigval) == 0); 7484 7485 syscall(SYS_getpid); 7486 7487 if (strstr(op, "signal") != NULL) { 7488 FORKEE_ASSERT_EQ(test_syscall_caught, 1); 7489 } 7490 7491 DPRINTF("Before exiting of the child process\n"); 7492 _exit(exitval); 7493 } 7494 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7495 7496 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7497 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7498 7499 validate_status_stopped(status, sigval); 7500 7501 DPRINTF("Before resuming the child process where it left off and " 7502 "without signal to be sent\n"); 7503 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 7504 7505 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7506 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7507 7508 validate_status_stopped(status, SIGTRAP); 7509 7510 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7511 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7512 7513 DPRINTF("Before checking siginfo_t and lwpid\n"); 7514 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 7515 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 7516 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 7517 7518 if (strstr(op, "killed") != NULL) { 7519 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 7520 7521 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7522 TWAIT_REQUIRE_SUCCESS( 7523 wpid = TWAIT_GENERIC(child, &status, 0), child); 7524 7525 validate_status_signaled(status, SIGKILL, 0); 7526 } else { 7527 if (strstr(op, "signal") != NULL) { 7528 DPRINTF("Before resuming the child %d and sending a " 7529 "signal SIGINFO\n", child); 7530 SYSCALL_REQUIRE( 7531 ptrace(PT_CONTINUE, child, (void *)1, SIGINFO) 7532 != -1); 7533 } else if (strstr(op, "detach") != NULL) { 7534 DPRINTF("Before detaching the child %d\n", child); 7535 SYSCALL_REQUIRE( 7536 ptrace(PT_DETACH, child, (void *)1, 0) != -1); 7537 } else { 7538 DPRINTF("Before resuming the child process where it " 7539 "left off and without signal to be sent\n"); 7540 SYSCALL_REQUIRE( 7541 ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 7542 7543 DPRINTF("Before calling %s() for the child\n", 7544 TWAIT_FNAME); 7545 TWAIT_REQUIRE_SUCCESS( 7546 wpid = TWAIT_GENERIC(child, &status, 0), child); 7547 7548 validate_status_stopped(status, SIGTRAP); 7549 7550 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO " 7551 "for child\n"); 7552 SYSCALL_REQUIRE( 7553 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) 7554 != -1); 7555 7556 DPRINTF("Before checking siginfo_t and lwpid\n"); 7557 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 7558 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 7559 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 7560 7561 DPRINTF("Before resuming the child process where it " 7562 "left off and without signal to be sent\n"); 7563 SYSCALL_REQUIRE( 7564 ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7565 } 7566 7567 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7568 TWAIT_REQUIRE_SUCCESS( 7569 wpid = TWAIT_GENERIC(child, &status, 0), child); 7570 7571 validate_status_exited(status, exitval); 7572 } 7573 7574 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7575 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7576 } 7577 7578 #define SYSCALL_TEST(name,op) \ 7579 ATF_TC(name); \ 7580 ATF_TC_HEAD(name, tc) \ 7581 { \ 7582 atf_tc_set_md_var(tc, "descr", \ 7583 "Verify that getpid(2) can be traced with PT_SYSCALL %s", \ 7584 #op ); \ 7585 } \ 7586 \ 7587 ATF_TC_BODY(name, tc) \ 7588 { \ 7589 \ 7590 syscall_body(op); \ 7591 } 7592 7593 SYSCALL_TEST(syscall, "") 7594 SYSCALL_TEST(syscall_killed_on_sce, "and killed") 7595 SYSCALL_TEST(syscall_signal_on_sce, "and signaled") 7596 SYSCALL_TEST(syscall_detach_on_sce, "and detached") 7597 7598 /// ---------------------------------------------------------------------------- 7599 7600 ATF_TC(syscallemu1); 7601 ATF_TC_HEAD(syscallemu1, tc) 7602 { 7603 atf_tc_set_md_var(tc, "descr", 7604 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 7605 } 7606 7607 ATF_TC_BODY(syscallemu1, tc) 7608 { 7609 const int exitval = 5; 7610 const int sigval = SIGSTOP; 7611 pid_t child, wpid; 7612 #if defined(TWAIT_HAVE_STATUS) 7613 int status; 7614 #endif 7615 7616 #if defined(__sparc__) && !defined(__sparc64__) 7617 /* syscallemu does not work on sparc (32-bit) */ 7618 atf_tc_expect_fail("PR kern/52166"); 7619 #endif 7620 7621 DPRINTF("Before forking process PID=%d\n", getpid()); 7622 SYSCALL_REQUIRE((child = fork()) != -1); 7623 if (child == 0) { 7624 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7625 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7626 7627 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7628 FORKEE_ASSERT(raise(sigval) == 0); 7629 7630 syscall(SYS_exit, 100); 7631 7632 DPRINTF("Before exiting of the child process\n"); 7633 _exit(exitval); 7634 } 7635 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7636 7637 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7638 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7639 7640 validate_status_stopped(status, sigval); 7641 7642 DPRINTF("Before resuming the child process where it left off and " 7643 "without signal to be sent\n"); 7644 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 7645 7646 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7647 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7648 7649 validate_status_stopped(status, SIGTRAP); 7650 7651 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 7652 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 7653 7654 DPRINTF("Before resuming the child process where it left off and " 7655 "without signal to be sent\n"); 7656 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 7657 7658 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7659 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7660 7661 validate_status_stopped(status, SIGTRAP); 7662 7663 DPRINTF("Before resuming the child process where it left off and " 7664 "without signal to be sent\n"); 7665 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7666 7667 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7668 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7669 7670 validate_status_exited(status, exitval); 7671 7672 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7673 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7674 } 7675 7676 /// ---------------------------------------------------------------------------- 7677 7678 static void 7679 clone_body(int flags, bool trackfork, bool trackvfork, 7680 bool trackvforkdone) 7681 { 7682 const int exitval = 5; 7683 const int exitval2 = 15; 7684 const int sigval = SIGSTOP; 7685 pid_t child, child2 = 0, wpid; 7686 #if defined(TWAIT_HAVE_STATUS) 7687 int status; 7688 #endif 7689 ptrace_state_t state; 7690 const int slen = sizeof(state); 7691 ptrace_event_t event; 7692 const int elen = sizeof(event); 7693 7694 const size_t stack_size = 1024 * 1024; 7695 void *stack, *stack_base; 7696 7697 stack = malloc(stack_size); 7698 ATF_REQUIRE(stack != NULL); 7699 7700 #ifdef __MACHINE_STACK_GROWS_UP 7701 stack_base = stack; 7702 #else 7703 stack_base = (char *)stack + stack_size; 7704 #endif 7705 7706 DPRINTF("Before forking process PID=%d\n", getpid()); 7707 SYSCALL_REQUIRE((child = fork()) != -1); 7708 if (child == 0) { 7709 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7710 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7711 7712 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7713 FORKEE_ASSERT(raise(sigval) == 0); 7714 7715 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7716 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7717 7718 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7719 child2); 7720 7721 // XXX WALLSIG? 7722 FORKEE_REQUIRE_SUCCESS 7723 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7724 7725 forkee_status_exited(status, exitval2); 7726 7727 DPRINTF("Before exiting of the child process\n"); 7728 _exit(exitval); 7729 } 7730 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7731 7732 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7733 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7734 7735 validate_status_stopped(status, sigval); 7736 7737 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 7738 trackfork ? "|PTRACE_FORK" : "", 7739 trackvfork ? "|PTRACE_VFORK" : "", 7740 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 7741 event.pe_set_event = 0; 7742 if (trackfork) 7743 event.pe_set_event |= PTRACE_FORK; 7744 if (trackvfork) 7745 event.pe_set_event |= PTRACE_VFORK; 7746 if (trackvforkdone) 7747 event.pe_set_event |= PTRACE_VFORK_DONE; 7748 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7749 7750 DPRINTF("Before resuming the child process where it left off and " 7751 "without signal to be sent\n"); 7752 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7753 7754 #if defined(TWAIT_HAVE_PID) 7755 if ((trackfork && !(flags & CLONE_VFORK)) || 7756 (trackvfork && (flags & CLONE_VFORK))) { 7757 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7758 child); 7759 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7760 child); 7761 7762 validate_status_stopped(status, SIGTRAP); 7763 7764 SYSCALL_REQUIRE( 7765 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7766 if (trackfork && !(flags & CLONE_VFORK)) { 7767 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7768 PTRACE_FORK); 7769 } 7770 if (trackvfork && (flags & CLONE_VFORK)) { 7771 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7772 PTRACE_VFORK); 7773 } 7774 7775 child2 = state.pe_other_pid; 7776 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7777 7778 DPRINTF("Before calling %s() for the forkee %d of the child " 7779 "%d\n", TWAIT_FNAME, child2, child); 7780 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7781 child2); 7782 7783 validate_status_stopped(status, SIGTRAP); 7784 7785 SYSCALL_REQUIRE( 7786 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7787 if (trackfork && !(flags & CLONE_VFORK)) { 7788 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7789 PTRACE_FORK); 7790 } 7791 if (trackvfork && (flags & CLONE_VFORK)) { 7792 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7793 PTRACE_VFORK); 7794 } 7795 7796 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7797 7798 DPRINTF("Before resuming the forkee process where it left off " 7799 "and without signal to be sent\n"); 7800 SYSCALL_REQUIRE( 7801 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7802 7803 DPRINTF("Before resuming the child process where it left off " 7804 "and without signal to be sent\n"); 7805 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7806 } 7807 #endif 7808 7809 if (trackvforkdone && (flags & CLONE_VFORK)) { 7810 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7811 child); 7812 TWAIT_REQUIRE_SUCCESS( 7813 wpid = TWAIT_GENERIC(child, &status, 0), child); 7814 7815 validate_status_stopped(status, SIGTRAP); 7816 7817 SYSCALL_REQUIRE( 7818 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7819 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7820 7821 child2 = state.pe_other_pid; 7822 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7823 child2); 7824 7825 DPRINTF("Before resuming the child process where it left off " 7826 "and without signal to be sent\n"); 7827 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7828 } 7829 7830 #if defined(TWAIT_HAVE_PID) 7831 if ((trackfork && !(flags & CLONE_VFORK)) || 7832 (trackvfork && (flags & CLONE_VFORK))) { 7833 DPRINTF("Before calling %s() for the forkee - expected exited" 7834 "\n", TWAIT_FNAME); 7835 TWAIT_REQUIRE_SUCCESS( 7836 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7837 7838 validate_status_exited(status, exitval2); 7839 7840 DPRINTF("Before calling %s() for the forkee - expected no " 7841 "process\n", TWAIT_FNAME); 7842 TWAIT_REQUIRE_FAILURE(ECHILD, 7843 wpid = TWAIT_GENERIC(child2, &status, 0)); 7844 } 7845 #endif 7846 7847 DPRINTF("Before calling %s() for the child - expected stopped " 7848 "SIGCHLD\n", TWAIT_FNAME); 7849 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7850 7851 validate_status_stopped(status, SIGCHLD); 7852 7853 DPRINTF("Before resuming the child process where it left off and " 7854 "without signal to be sent\n"); 7855 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7856 7857 DPRINTF("Before calling %s() for the child - expected exited\n", 7858 TWAIT_FNAME); 7859 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7860 7861 validate_status_exited(status, exitval); 7862 7863 DPRINTF("Before calling %s() for the child - expected no process\n", 7864 TWAIT_FNAME); 7865 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7866 } 7867 7868 #define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \ 7869 ATF_TC(name); \ 7870 ATF_TC_HEAD(name, tc) \ 7871 { \ 7872 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \ 7873 "called with 0%s%s%s in EVENT_MASK", \ 7874 #flags, \ 7875 tfork ? "|PTRACE_FORK" : "", \ 7876 tvfork ? "|PTRACE_VFORK" : "", \ 7877 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 7878 } \ 7879 \ 7880 ATF_TC_BODY(name, tc) \ 7881 { \ 7882 \ 7883 clone_body(flags, tfork, tvfork, tvforkdone); \ 7884 } 7885 7886 CLONE_TEST(clone1, 0, false, false, false) 7887 #if defined(TWAIT_HAVE_PID) 7888 CLONE_TEST(clone2, 0, true, false, false) 7889 CLONE_TEST(clone3, 0, false, true, false) 7890 CLONE_TEST(clone4, 0, true, true, false) 7891 #endif 7892 CLONE_TEST(clone5, 0, false, false, true) 7893 #if defined(TWAIT_HAVE_PID) 7894 CLONE_TEST(clone6, 0, true, false, true) 7895 CLONE_TEST(clone7, 0, false, true, true) 7896 CLONE_TEST(clone8, 0, true, true, true) 7897 #endif 7898 7899 CLONE_TEST(clone_vm1, CLONE_VM, false, false, false) 7900 #if defined(TWAIT_HAVE_PID) 7901 CLONE_TEST(clone_vm2, CLONE_VM, true, false, false) 7902 CLONE_TEST(clone_vm3, CLONE_VM, false, true, false) 7903 CLONE_TEST(clone_vm4, CLONE_VM, true, true, false) 7904 #endif 7905 CLONE_TEST(clone_vm5, CLONE_VM, false, false, true) 7906 #if defined(TWAIT_HAVE_PID) 7907 CLONE_TEST(clone_vm6, CLONE_VM, true, false, true) 7908 CLONE_TEST(clone_vm7, CLONE_VM, false, true, true) 7909 CLONE_TEST(clone_vm8, CLONE_VM, true, true, true) 7910 #endif 7911 7912 CLONE_TEST(clone_fs1, CLONE_FS, false, false, false) 7913 #if defined(TWAIT_HAVE_PID) 7914 CLONE_TEST(clone_fs2, CLONE_FS, true, false, false) 7915 CLONE_TEST(clone_fs3, CLONE_FS, false, true, false) 7916 CLONE_TEST(clone_fs4, CLONE_FS, true, true, false) 7917 #endif 7918 CLONE_TEST(clone_fs5, CLONE_FS, false, false, true) 7919 #if defined(TWAIT_HAVE_PID) 7920 CLONE_TEST(clone_fs6, CLONE_FS, true, false, true) 7921 CLONE_TEST(clone_fs7, CLONE_FS, false, true, true) 7922 CLONE_TEST(clone_fs8, CLONE_FS, true, true, true) 7923 #endif 7924 7925 CLONE_TEST(clone_files1, CLONE_FILES, false, false, false) 7926 #if defined(TWAIT_HAVE_PID) 7927 CLONE_TEST(clone_files2, CLONE_FILES, true, false, false) 7928 CLONE_TEST(clone_files3, CLONE_FILES, false, true, false) 7929 CLONE_TEST(clone_files4, CLONE_FILES, true, true, false) 7930 #endif 7931 CLONE_TEST(clone_files5, CLONE_FILES, false, false, true) 7932 #if defined(TWAIT_HAVE_PID) 7933 CLONE_TEST(clone_files6, CLONE_FILES, true, false, true) 7934 CLONE_TEST(clone_files7, CLONE_FILES, false, true, true) 7935 CLONE_TEST(clone_files8, CLONE_FILES, true, true, true) 7936 #endif 7937 7938 //CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false) 7939 #if defined(TWAIT_HAVE_PID) 7940 //CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false) 7941 //CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false) 7942 //CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false) 7943 #endif 7944 //CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true) 7945 #if defined(TWAIT_HAVE_PID) 7946 //CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true) 7947 //CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true) 7948 //CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true) 7949 #endif 7950 7951 CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false) 7952 #if defined(TWAIT_HAVE_PID) 7953 CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false) 7954 CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false) 7955 CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false) 7956 #endif 7957 CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true) 7958 #if defined(TWAIT_HAVE_PID) 7959 CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true) 7960 CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true) 7961 CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true) 7962 #endif 7963 7964 /// ---------------------------------------------------------------------------- 7965 7966 #if defined(TWAIT_HAVE_PID) 7967 static void 7968 clone_body2(int flags, bool masked, bool ignored) 7969 { 7970 const int exitval = 5; 7971 const int exitval2 = 15; 7972 const int sigval = SIGSTOP; 7973 pid_t child, child2 = 0, wpid; 7974 #if defined(TWAIT_HAVE_STATUS) 7975 int status; 7976 #endif 7977 ptrace_state_t state; 7978 const int slen = sizeof(state); 7979 ptrace_event_t event; 7980 const int elen = sizeof(event); 7981 struct sigaction sa; 7982 struct ptrace_siginfo info; 7983 sigset_t intmask; 7984 struct kinfo_proc2 kp; 7985 size_t len = sizeof(kp); 7986 7987 int name[6]; 7988 const size_t namelen = __arraycount(name); 7989 ki_sigset_t kp_sigmask; 7990 ki_sigset_t kp_sigignore; 7991 7992 const size_t stack_size = 1024 * 1024; 7993 void *stack, *stack_base; 7994 7995 stack = malloc(stack_size); 7996 ATF_REQUIRE(stack != NULL); 7997 7998 #ifdef __MACHINE_STACK_GROWS_UP 7999 stack_base = stack; 8000 #else 8001 stack_base = (char *)stack + stack_size; 8002 #endif 8003 8004 SYSCALL_REQUIRE((child = fork()) != -1); 8005 if (child == 0) { 8006 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8007 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8008 8009 if (masked) { 8010 sigemptyset(&intmask); 8011 sigaddset(&intmask, SIGTRAP); 8012 sigprocmask(SIG_BLOCK, &intmask, NULL); 8013 } 8014 8015 if (ignored) { 8016 memset(&sa, 0, sizeof(sa)); 8017 sa.sa_handler = SIG_IGN; 8018 sigemptyset(&sa.sa_mask); 8019 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 8020 } 8021 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8022 FORKEE_ASSERT(raise(sigval) == 0); 8023 8024 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 8025 flags); 8026 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 8027 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 8028 8029 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 8030 child2); 8031 8032 // XXX WALLSIG? 8033 FORKEE_REQUIRE_SUCCESS 8034 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 8035 8036 forkee_status_exited(status, exitval2); 8037 8038 DPRINTF("Before exiting of the child process\n"); 8039 _exit(exitval); 8040 } 8041 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8042 8043 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8044 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8045 8046 validate_status_stopped(status, sigval); 8047 8048 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 8049 SYSCALL_REQUIRE( 8050 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 8051 8052 DPRINTF("Before checking siginfo_t\n"); 8053 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 8054 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 8055 8056 name[0] = CTL_KERN, 8057 name[1] = KERN_PROC2, 8058 name[2] = KERN_PROC_PID; 8059 name[3] = child; 8060 name[4] = sizeof(kp); 8061 name[5] = 1; 8062 8063 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 8064 8065 if (masked) 8066 kp_sigmask = kp.p_sigmask; 8067 8068 if (ignored) 8069 kp_sigignore = kp.p_sigignore; 8070 8071 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in " 8072 "EVENT_MASK for the child %d\n", child); 8073 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; 8074 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 8075 8076 DPRINTF("Before resuming the child process where it left off and " 8077 "without signal to be sent\n"); 8078 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8079 8080 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 8081 child); 8082 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 8083 child); 8084 8085 validate_status_stopped(status, SIGTRAP); 8086 8087 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 8088 8089 if (masked) { 8090 DPRINTF("kp_sigmask=" 8091 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8092 PRIx32 "\n", 8093 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 8094 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 8095 8096 DPRINTF("kp.p_sigmask=" 8097 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8098 PRIx32 "\n", 8099 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 8100 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 8101 8102 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 8103 sizeof(kp_sigmask))); 8104 } 8105 8106 if (ignored) { 8107 DPRINTF("kp_sigignore=" 8108 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8109 PRIx32 "\n", 8110 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 8111 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 8112 8113 DPRINTF("kp.p_sigignore=" 8114 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8115 PRIx32 "\n", 8116 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 8117 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 8118 8119 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 8120 sizeof(kp_sigignore))); 8121 } 8122 8123 SYSCALL_REQUIRE( 8124 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 8125 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event, 8126 child2); 8127 if (!(flags & CLONE_VFORK)) { 8128 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 8129 PTRACE_FORK); 8130 } else { 8131 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 8132 PTRACE_VFORK); 8133 } 8134 8135 child2 = state.pe_other_pid; 8136 DPRINTF("Reported ptrace event with forkee %d\n", child2); 8137 8138 DPRINTF("Before calling %s() for the forkee %d of the child " 8139 "%d\n", TWAIT_FNAME, child2, child); 8140 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 8141 child2); 8142 8143 validate_status_stopped(status, SIGTRAP); 8144 8145 name[3] = child2; 8146 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 8147 8148 if (masked) { 8149 DPRINTF("kp_sigmask=" 8150 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8151 PRIx32 "\n", 8152 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 8153 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 8154 8155 DPRINTF("kp.p_sigmask=" 8156 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8157 PRIx32 "\n", 8158 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 8159 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 8160 8161 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 8162 sizeof(kp_sigmask))); 8163 } 8164 8165 if (ignored) { 8166 DPRINTF("kp_sigignore=" 8167 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8168 PRIx32 "\n", 8169 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 8170 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 8171 8172 DPRINTF("kp.p_sigignore=" 8173 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8174 PRIx32 "\n", 8175 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 8176 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 8177 8178 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 8179 sizeof(kp_sigignore))); 8180 } 8181 8182 SYSCALL_REQUIRE( 8183 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 8184 if (!(flags & CLONE_VFORK)) { 8185 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 8186 PTRACE_FORK); 8187 } else { 8188 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 8189 PTRACE_VFORK); 8190 } 8191 8192 ATF_REQUIRE_EQ(state.pe_other_pid, child); 8193 8194 DPRINTF("Before resuming the forkee process where it left off " 8195 "and without signal to be sent\n"); 8196 SYSCALL_REQUIRE( 8197 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 8198 8199 DPRINTF("Before resuming the child process where it left off " 8200 "and without signal to be sent\n"); 8201 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8202 8203 if (flags & CLONE_VFORK) { 8204 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 8205 child); 8206 TWAIT_REQUIRE_SUCCESS( 8207 wpid = TWAIT_GENERIC(child, &status, 0), child); 8208 8209 validate_status_stopped(status, SIGTRAP); 8210 8211 name[3] = child; 8212 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 8213 8214 /* 8215 * SIGCHLD is now pending in the signal queue and 8216 * the kernel presents it to userland as a masked signal. 8217 */ 8218 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 8219 8220 if (masked) { 8221 DPRINTF("kp_sigmask=" 8222 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8223 PRIx32 "\n", 8224 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 8225 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 8226 8227 DPRINTF("kp.p_sigmask=" 8228 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8229 PRIx32 "\n", 8230 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 8231 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 8232 8233 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 8234 sizeof(kp_sigmask))); 8235 } 8236 8237 if (ignored) { 8238 DPRINTF("kp_sigignore=" 8239 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8240 PRIx32 "\n", 8241 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 8242 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 8243 8244 DPRINTF("kp.p_sigignore=" 8245 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 8246 PRIx32 "\n", 8247 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 8248 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 8249 8250 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 8251 sizeof(kp_sigignore))); 8252 } 8253 8254 SYSCALL_REQUIRE( 8255 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 8256 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 8257 8258 child2 = state.pe_other_pid; 8259 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 8260 child2); 8261 8262 DPRINTF("Before resuming the child process where it left off " 8263 "and without signal to be sent\n"); 8264 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8265 } 8266 8267 DPRINTF("Before calling %s() for the forkee - expected exited" 8268 "\n", TWAIT_FNAME); 8269 TWAIT_REQUIRE_SUCCESS( 8270 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 8271 8272 validate_status_exited(status, exitval2); 8273 8274 DPRINTF("Before calling %s() for the forkee - expected no " 8275 "process\n", TWAIT_FNAME); 8276 TWAIT_REQUIRE_FAILURE(ECHILD, 8277 wpid = TWAIT_GENERIC(child2, &status, 0)); 8278 8279 DPRINTF("Before calling %s() for the child - expected stopped " 8280 "SIGCHLD\n", TWAIT_FNAME); 8281 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8282 8283 validate_status_stopped(status, SIGCHLD); 8284 8285 DPRINTF("Before resuming the child process where it left off and " 8286 "without signal to be sent\n"); 8287 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8288 8289 DPRINTF("Before calling %s() for the child - expected exited\n", 8290 TWAIT_FNAME); 8291 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8292 8293 validate_status_exited(status, exitval); 8294 8295 DPRINTF("Before calling %s() for the child - expected no process\n", 8296 TWAIT_FNAME); 8297 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 8298 } 8299 8300 #define CLONE_TEST2(name,flags,masked,ignored) \ 8301 ATF_TC(name); \ 8302 ATF_TC_HEAD(name, tc) \ 8303 { \ 8304 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\ 8305 " regardless of signal %s%s", \ 8306 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \ 8307 } \ 8308 \ 8309 ATF_TC_BODY(name, tc) \ 8310 { \ 8311 \ 8312 clone_body2(flags, masked, ignored); \ 8313 } 8314 8315 CLONE_TEST2(clone_signalignored, 0, true, false) 8316 CLONE_TEST2(clone_signalmasked, 0, false, true) 8317 CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false) 8318 CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true) 8319 CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false) 8320 CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true) 8321 CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false) 8322 CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true) 8323 //CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX 8324 //CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX 8325 CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false) 8326 CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true) 8327 #endif 8328 8329 /// ---------------------------------------------------------------------------- 8330 8331 #if defined(TWAIT_HAVE_PID) 8332 static void 8333 traceme_vfork_clone_body(int flags) 8334 { 8335 const int exitval = 5; 8336 const int exitval2 = 15; 8337 pid_t child, child2 = 0, wpid; 8338 #if defined(TWAIT_HAVE_STATUS) 8339 int status; 8340 #endif 8341 8342 const size_t stack_size = 1024 * 1024; 8343 void *stack, *stack_base; 8344 8345 stack = malloc(stack_size); 8346 ATF_REQUIRE(stack != NULL); 8347 8348 #ifdef __MACHINE_STACK_GROWS_UP 8349 stack_base = stack; 8350 #else 8351 stack_base = (char *)stack + stack_size; 8352 #endif 8353 8354 SYSCALL_REQUIRE((child = vfork()) != -1); 8355 if (child == 0) { 8356 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8357 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8358 8359 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 8360 flags); 8361 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 8362 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 8363 8364 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 8365 child2); 8366 8367 // XXX WALLSIG? 8368 FORKEE_REQUIRE_SUCCESS 8369 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 8370 8371 forkee_status_exited(status, exitval2); 8372 8373 DPRINTF("Before exiting of the child process\n"); 8374 _exit(exitval); 8375 } 8376 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8377 8378 DPRINTF("Before calling %s() for the child - expected exited\n", 8379 TWAIT_FNAME); 8380 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8381 8382 validate_status_exited(status, exitval); 8383 8384 DPRINTF("Before calling %s() for the child - expected no process\n", 8385 TWAIT_FNAME); 8386 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 8387 } 8388 8389 #define TRACEME_VFORK_CLONE_TEST(name,flags) \ 8390 ATF_TC(name); \ 8391 ATF_TC_HEAD(name, tc) \ 8392 { \ 8393 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \ 8394 "handled correctly with vfork(2)ed tracer", \ 8395 #flags); \ 8396 } \ 8397 \ 8398 ATF_TC_BODY(name, tc) \ 8399 { \ 8400 \ 8401 traceme_vfork_clone_body(flags); \ 8402 } 8403 8404 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0) 8405 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM) 8406 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS) 8407 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES) 8408 //TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX 8409 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK) 8410 #endif 8411 8412 /// ---------------------------------------------------------------------------- 8413 8414 static void 8415 user_va0_disable(int operation) 8416 { 8417 pid_t child, wpid; 8418 #if defined(TWAIT_HAVE_STATUS) 8419 int status; 8420 #endif 8421 const int sigval = SIGSTOP; 8422 int rv; 8423 8424 struct ptrace_siginfo info; 8425 8426 if (get_user_va0_disable() == 0) 8427 atf_tc_skip("vm.user_va0_disable is set to 0"); 8428 8429 memset(&info, 0, sizeof(info)); 8430 8431 DPRINTF("Before forking process PID=%d\n", getpid()); 8432 SYSCALL_REQUIRE((child = fork()) != -1); 8433 if (child == 0) { 8434 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8435 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8436 8437 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8438 FORKEE_ASSERT(raise(sigval) == 0); 8439 8440 /* NOTREACHED */ 8441 FORKEE_ASSERTX(0 && "This shall not be reached"); 8442 __unreachable(); 8443 } 8444 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8445 8446 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8447 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8448 8449 validate_status_stopped(status, sigval); 8450 8451 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 8452 "child\n"); 8453 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 8454 sizeof(info)) != -1); 8455 8456 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 8457 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 8458 "si_errno=%#x\n", 8459 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 8460 info.psi_siginfo.si_errno); 8461 8462 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 8463 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 8464 8465 DPRINTF("Before resuming the child process in PC=0x0 " 8466 "and without signal to be sent\n"); 8467 errno = 0; 8468 rv = ptrace(operation, child, (void *)0, 0); 8469 ATF_REQUIRE_EQ(errno, EINVAL); 8470 ATF_REQUIRE_EQ(rv, -1); 8471 8472 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 8473 8474 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8475 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8476 validate_status_signaled(status, SIGKILL, 0); 8477 8478 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8479 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 8480 } 8481 8482 #define USER_VA0_DISABLE(test, operation) \ 8483 ATF_TC(test); \ 8484 ATF_TC_HEAD(test, tc) \ 8485 { \ 8486 atf_tc_set_md_var(tc, "descr", \ 8487 "Verify behavior of " #operation " with PC set to 0x0"); \ 8488 } \ 8489 \ 8490 ATF_TC_BODY(test, tc) \ 8491 { \ 8492 \ 8493 user_va0_disable(operation); \ 8494 } 8495 8496 USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 8497 USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 8498 USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 8499 8500 /// ---------------------------------------------------------------------------- 8501 8502 /* 8503 * Parse the core file and find the requested note. If the reading or parsing 8504 * fails, the test is failed. If the note is found, it is read onto buf, up to 8505 * buf_len. The actual length of the note is returned (which can be greater 8506 * than buf_len, indicating that it has been truncated). If the note is not 8507 * found, -1 is returned. 8508 */ 8509 static ssize_t core_find_note(const char *core_path, 8510 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 8511 { 8512 int core_fd; 8513 Elf *core_elf; 8514 size_t core_numhdr, i; 8515 ssize_t ret = -1; 8516 /* note: we assume note name will be null-terminated */ 8517 size_t name_len = strlen(note_name) + 1; 8518 8519 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 8520 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 8521 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 8522 8523 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 8524 for (i = 0; i < core_numhdr && ret == -1; i++) { 8525 GElf_Phdr core_hdr; 8526 size_t offset; 8527 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 8528 if (core_hdr.p_type != PT_NOTE) 8529 continue; 8530 8531 for (offset = core_hdr.p_offset; 8532 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 8533 Elf64_Nhdr note_hdr; 8534 char name_buf[64]; 8535 8536 switch (gelf_getclass(core_elf)) { 8537 case ELFCLASS64: 8538 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 8539 sizeof(note_hdr), offset) 8540 == sizeof(note_hdr)); 8541 offset += sizeof(note_hdr); 8542 break; 8543 case ELFCLASS32: 8544 { 8545 Elf32_Nhdr tmp_hdr; 8546 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 8547 sizeof(tmp_hdr), offset) 8548 == sizeof(tmp_hdr)); 8549 offset += sizeof(tmp_hdr); 8550 note_hdr.n_namesz = tmp_hdr.n_namesz; 8551 note_hdr.n_descsz = tmp_hdr.n_descsz; 8552 note_hdr.n_type = tmp_hdr.n_type; 8553 } 8554 break; 8555 } 8556 8557 /* indicates end of notes */ 8558 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 8559 break; 8560 if (note_hdr.n_namesz == name_len && 8561 note_hdr.n_namesz <= sizeof(name_buf)) { 8562 SYSCALL_REQUIRE(pread(core_fd, name_buf, 8563 note_hdr.n_namesz, offset) 8564 == (ssize_t)(size_t)note_hdr.n_namesz); 8565 8566 if (!strncmp(note_name, name_buf, name_len) && 8567 note_hdr.n_type == note_type) 8568 ret = note_hdr.n_descsz; 8569 } 8570 8571 offset += note_hdr.n_namesz; 8572 /* fix to alignment */ 8573 offset = roundup(offset, core_hdr.p_align); 8574 8575 /* if name & type matched above */ 8576 if (ret != -1) { 8577 ssize_t read_len = MIN(buf_len, 8578 note_hdr.n_descsz); 8579 SYSCALL_REQUIRE(pread(core_fd, buf, 8580 read_len, offset) == read_len); 8581 break; 8582 } 8583 8584 offset += note_hdr.n_descsz; 8585 /* fix to alignment */ 8586 offset = roundup(offset, core_hdr.p_align); 8587 } 8588 } 8589 8590 elf_end(core_elf); 8591 close(core_fd); 8592 8593 return ret; 8594 } 8595 8596 ATF_TC(core_dump_procinfo); 8597 ATF_TC_HEAD(core_dump_procinfo, tc) 8598 { 8599 atf_tc_set_md_var(tc, "descr", 8600 "Trigger a core dump and verify its contents."); 8601 } 8602 8603 ATF_TC_BODY(core_dump_procinfo, tc) 8604 { 8605 const int exitval = 5; 8606 pid_t child, wpid; 8607 #if defined(TWAIT_HAVE_STATUS) 8608 const int sigval = SIGTRAP; 8609 int status; 8610 #endif 8611 char core_path[] = "/tmp/core.XXXXXX"; 8612 int core_fd; 8613 struct netbsd_elfcore_procinfo procinfo; 8614 8615 DPRINTF("Before forking process PID=%d\n", getpid()); 8616 SYSCALL_REQUIRE((child = fork()) != -1); 8617 if (child == 0) { 8618 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8619 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8620 8621 DPRINTF("Before triggering SIGTRAP\n"); 8622 trigger_trap(); 8623 8624 DPRINTF("Before exiting of the child process\n"); 8625 _exit(exitval); 8626 } 8627 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8628 8629 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8630 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8631 8632 validate_status_stopped(status, sigval); 8633 8634 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 8635 close(core_fd); 8636 8637 DPRINTF("Call DUMPCORE for the child process\n"); 8638 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 8639 != -1); 8640 8641 DPRINTF("Read core file\n"); 8642 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 8643 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 8644 sizeof(procinfo)); 8645 8646 ATF_CHECK_EQ(procinfo.cpi_version, 1); 8647 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 8648 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 8649 ATF_CHECK_EQ(procinfo.cpi_pid, child); 8650 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 8651 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 8652 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 8653 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 8654 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 8655 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 8656 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 8657 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 8658 ATF_CHECK_EQ(procinfo.cpi_siglwp, 1); 8659 8660 unlink(core_path); 8661 8662 DPRINTF("Before resuming the child process where it left off and " 8663 "without signal to be sent\n"); 8664 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8665 8666 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8667 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8668 8669 validate_status_exited(status, exitval); 8670 8671 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8672 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 8673 } 8674 8675 /// ---------------------------------------------------------------------------- 8676 8677 #if defined(TWAIT_HAVE_STATUS) 8678 8679 #define THREAD_CONCURRENT_BREAKPOINT_NUM 50 8680 #define THREAD_CONCURRENT_SIGNALS_NUM 50 8681 #define THREAD_CONCURRENT_WATCHPOINT_NUM 50 8682 8683 /* List of signals to use for the test */ 8684 const int thread_concurrent_signals_list[] = { 8685 SIGIO, 8686 SIGXCPU, 8687 SIGXFSZ, 8688 SIGVTALRM, 8689 SIGPROF, 8690 SIGWINCH, 8691 SIGINFO, 8692 SIGUSR1, 8693 SIGUSR2 8694 }; 8695 8696 enum thread_concurrent_signal_handling { 8697 /* the signal is discarded by debugger */ 8698 TCSH_DISCARD, 8699 /* the handler is set to SIG_IGN */ 8700 TCSH_SIG_IGN, 8701 /* an actual handler is used */ 8702 TCSH_HANDLER 8703 }; 8704 8705 static pthread_barrier_t thread_concurrent_barrier; 8706 static pthread_key_t thread_concurrent_key; 8707 static uint32_t thread_concurrent_watchpoint_var = 0; 8708 8709 static void * 8710 thread_concurrent_breakpoint_thread(void *arg) 8711 { 8712 static volatile int watchme = 1; 8713 pthread_barrier_wait(&thread_concurrent_barrier); 8714 DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self()); 8715 check_happy(watchme); 8716 return NULL; 8717 } 8718 8719 static void 8720 thread_concurrent_sig_handler(int sig) 8721 { 8722 void *tls_val = pthread_getspecific(thread_concurrent_key); 8723 DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 8724 FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key, 8725 (void*)((uintptr_t)tls_val + 1)) == 0); 8726 } 8727 8728 static void * 8729 thread_concurrent_signals_thread(void *arg) 8730 { 8731 int sigval = thread_concurrent_signals_list[ 8732 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 8733 enum thread_concurrent_signal_handling *signal_handle = arg; 8734 void *tls_val; 8735 8736 pthread_barrier_wait(&thread_concurrent_barrier); 8737 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 8738 _lwp_self()); 8739 pthread_kill(pthread_self(), sigval); 8740 if (*signal_handle == TCSH_HANDLER) { 8741 tls_val = pthread_getspecific(thread_concurrent_key); 8742 DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 8743 FORKEE_ASSERT(tls_val == (void*)1); 8744 } 8745 return NULL; 8746 } 8747 8748 static void * 8749 thread_concurrent_watchpoint_thread(void *arg) 8750 { 8751 pthread_barrier_wait(&thread_concurrent_barrier); 8752 DPRINTF("Before modifying var from LWP %d\n", _lwp_self()); 8753 thread_concurrent_watchpoint_var = 1; 8754 return NULL; 8755 } 8756 8757 #if defined(__i386__) || defined(__x86_64__) 8758 enum thread_concurrent_sigtrap_event { 8759 TCSE_UNKNOWN, 8760 TCSE_BREAKPOINT, 8761 TCSE_WATCHPOINT 8762 }; 8763 8764 static void 8765 thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid); 8766 static enum thread_concurrent_sigtrap_event 8767 thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info); 8768 #endif 8769 8770 static void 8771 thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle, 8772 int breakpoint_threads, int signal_threads, int watchpoint_threads) 8773 { 8774 const int exitval = 5; 8775 const int sigval = SIGSTOP; 8776 pid_t child, wpid; 8777 int status; 8778 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 8779 = {{0, 0}}; 8780 struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 8781 = {{0, 0}}; 8782 struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 8783 = {{0, 0}}; 8784 ptrace_event_t event; 8785 int i; 8786 8787 #if defined(HAVE_DBREGS) 8788 if (!can_we_set_dbregs()) { 8789 atf_tc_skip("Either run this test as root or set sysctl(3) " 8790 "security.models.extensions.user_set_dbregs to 1"); 8791 } 8792 #endif 8793 8794 atf_tc_skip("PR kern/54960"); 8795 8796 /* Protect against out-of-bounds array access. */ 8797 ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM); 8798 ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM); 8799 ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM); 8800 8801 DPRINTF("Before forking process PID=%d\n", getpid()); 8802 SYSCALL_REQUIRE((child = fork()) != -1); 8803 if (child == 0) { 8804 pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM]; 8805 pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM]; 8806 pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM]; 8807 8808 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8809 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8810 8811 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8812 FORKEE_ASSERT(raise(sigval) == 0); 8813 8814 if (signal_handle != TCSH_DISCARD) { 8815 struct sigaction sa; 8816 unsigned int j; 8817 8818 memset(&sa, 0, sizeof(sa)); 8819 if (signal_handle == TCSH_SIG_IGN) 8820 sa.sa_handler = SIG_IGN; 8821 else 8822 sa.sa_handler = thread_concurrent_sig_handler; 8823 sigemptyset(&sa.sa_mask); 8824 8825 for (j = 0; 8826 j < __arraycount(thread_concurrent_signals_list); 8827 j++) 8828 FORKEE_ASSERT(sigaction( 8829 thread_concurrent_signals_list[j], &sa, NULL) 8830 != -1); 8831 } 8832 8833 DPRINTF("Before starting threads from the child\n"); 8834 FORKEE_ASSERT(pthread_barrier_init( 8835 &thread_concurrent_barrier, NULL, 8836 breakpoint_threads + signal_threads + watchpoint_threads) 8837 == 0); 8838 FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL) 8839 == 0); 8840 8841 for (i = 0; i < signal_threads; i++) { 8842 FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL, 8843 thread_concurrent_signals_thread, 8844 &signal_handle) == 0); 8845 } 8846 for (i = 0; i < breakpoint_threads; i++) { 8847 FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL, 8848 thread_concurrent_breakpoint_thread, NULL) == 0); 8849 } 8850 for (i = 0; i < watchpoint_threads; i++) { 8851 FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL, 8852 thread_concurrent_watchpoint_thread, NULL) == 0); 8853 } 8854 8855 DPRINTF("Before joining threads from the child\n"); 8856 for (i = 0; i < watchpoint_threads; i++) { 8857 FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0); 8858 } 8859 for (i = 0; i < breakpoint_threads; i++) { 8860 FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0); 8861 } 8862 for (i = 0; i < signal_threads; i++) { 8863 FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0); 8864 } 8865 8866 FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0); 8867 FORKEE_ASSERT(pthread_barrier_destroy( 8868 &thread_concurrent_barrier) == 0); 8869 8870 DPRINTF("Before exiting of the child process\n"); 8871 _exit(exitval); 8872 } 8873 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8874 8875 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8876 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8877 8878 validate_status_stopped(status, sigval); 8879 8880 DPRINTF("Set LWP event mask for the child process\n"); 8881 memset(&event, 0, sizeof(event)); 8882 event.pe_set_event |= PTRACE_LWP_CREATE; 8883 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event)) 8884 != -1); 8885 8886 DPRINTF("Before resuming the child process where it left off\n"); 8887 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8888 8889 DPRINTF("Before entering signal collection loop\n"); 8890 while (1) { 8891 ptrace_siginfo_t info; 8892 8893 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8894 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 8895 child); 8896 if (WIFEXITED(status)) 8897 break; 8898 /* Note: we use validate_status_stopped() to get nice error 8899 * message. Signal is irrelevant since it won't be reached. 8900 */ 8901 else if (!WIFSTOPPED(status)) 8902 validate_status_stopped(status, 0); 8903 8904 DPRINTF("Before calling PT_GET_SIGINFO\n"); 8905 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 8906 sizeof(info)) != -1); 8907 8908 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 8909 info.psi_siginfo.si_signo, info.psi_lwpid, 8910 WSTOPSIG(status)); 8911 8912 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status), 8913 "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid, 8914 WSTOPSIG(status), info.psi_siginfo.si_signo); 8915 8916 if (WSTOPSIG(status) != SIGTRAP) { 8917 int expected_sig = 8918 thread_concurrent_signals_list[info.psi_lwpid % 8919 __arraycount(thread_concurrent_signals_list)]; 8920 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 8921 "lwp=%d, expected %d, got %d", info.psi_lwpid, 8922 expected_sig, WSTOPSIG(status)); 8923 8924 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 8925 } else if (info.psi_siginfo.si_code == TRAP_LWP) { 8926 #if defined(__i386__) || defined(__x86_64__) 8927 thread_concurrent_lwp_setup(child, info.psi_lwpid); 8928 #endif 8929 } else { 8930 #if defined(__i386__) || defined(__x86_64__) 8931 switch (thread_concurrent_handle_sigtrap(child, &info)) { 8932 case TCSE_UNKNOWN: 8933 /* already reported inside the function */ 8934 break; 8935 case TCSE_BREAKPOINT: 8936 *FIND_EVENT_COUNT(bp_counts, 8937 info.psi_lwpid) += 1; 8938 break; 8939 case TCSE_WATCHPOINT: 8940 *FIND_EVENT_COUNT(wp_counts, 8941 info.psi_lwpid) += 1; 8942 break; 8943 } 8944 #else 8945 ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n", 8946 info.psi_siginfo.si_code); 8947 #endif 8948 } 8949 8950 DPRINTF("Before resuming the child process\n"); 8951 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 8952 signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP 8953 ? WSTOPSIG(status) : 0) != -1); 8954 } 8955 8956 for (i = 0; i < signal_threads; i++) 8957 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 8958 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 8959 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 8960 for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++) 8961 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0, 8962 "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d", 8963 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 8964 8965 for (i = 0; i < breakpoint_threads; i++) 8966 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1, 8967 "bp_counts[%d].lec_count=%d; lec_lwp=%d", 8968 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 8969 for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++) 8970 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0, 8971 "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d", 8972 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 8973 8974 for (i = 0; i < watchpoint_threads; i++) 8975 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1, 8976 "wp_counts[%d].lec_count=%d; lec_lwp=%d", 8977 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 8978 for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++) 8979 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0, 8980 "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d", 8981 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 8982 8983 validate_status_exited(status, exitval); 8984 } 8985 8986 #define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr) \ 8987 ATF_TC(test); \ 8988 ATF_TC_HEAD(test, tc) \ 8989 { \ 8990 atf_tc_set_md_var(tc, "descr", descr); \ 8991 } \ 8992 \ 8993 ATF_TC_BODY(test, tc) \ 8994 { \ 8995 thread_concurrent_test(sig_hdl, bps, sigs, wps); \ 8996 } 8997 8998 THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD, 8999 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 9000 "Verify that concurrent signals issued to a single thread are reported " 9001 "correctly"); 9002 THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN, 9003 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 9004 "Verify that concurrent signals issued to a single thread are reported " 9005 "correctly and passed back to SIG_IGN handler"); 9006 THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER, 9007 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 9008 "Verify that concurrent signals issued to a single thread are reported " 9009 "correctly and passed back to a handler function"); 9010 9011 #if defined(__i386__) || defined(__x86_64__) 9012 THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD, 9013 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0, 9014 "Verify that concurrent breakpoints are reported correctly"); 9015 THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD, 9016 0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 9017 "Verify that concurrent breakpoints are reported correctly"); 9018 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD, 9019 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 9020 "Verify that concurrent breakpoints and watchpoints are reported " 9021 "correctly"); 9022 9023 THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD, 9024 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 9025 "Verify that concurrent breakpoints and signals are reported correctly"); 9026 THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN, 9027 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 9028 "Verify that concurrent breakpoints and signals are reported correctly " 9029 "and passed back to SIG_IGN handler"); 9030 THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER, 9031 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 9032 "Verify that concurrent breakpoints and signals are reported correctly " 9033 "and passed back to a handler function"); 9034 9035 THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD, 9036 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 9037 "Verify that concurrent watchpoints and signals are reported correctly"); 9038 THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN, 9039 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 9040 "Verify that concurrent watchpoints and signals are reported correctly " 9041 "and passed back to SIG_IGN handler"); 9042 THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER, 9043 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 9044 "Verify that concurrent watchpoints and signals are reported correctly " 9045 "and passed back to a handler function"); 9046 9047 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD, 9048 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 9049 THREAD_CONCURRENT_WATCHPOINT_NUM, 9050 "Verify that concurrent breakpoints, watchpoints and signals are reported " 9051 "correctly"); 9052 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN, 9053 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 9054 THREAD_CONCURRENT_WATCHPOINT_NUM, 9055 "Verify that concurrent breakpoints, watchpoints and signals are reported " 9056 "correctly and passed back to SIG_IGN handler"); 9057 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER, 9058 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 9059 THREAD_CONCURRENT_WATCHPOINT_NUM, 9060 "Verify that concurrent breakpoints, watchpoints and signals are reported " 9061 "correctly and passed back to a handler function"); 9062 #endif 9063 9064 #endif /*defined(TWAIT_HAVE_STATUS)*/ 9065 9066 /// ---------------------------------------------------------------------------- 9067 9068 #include "t_ptrace_amd64_wait.h" 9069 #include "t_ptrace_i386_wait.h" 9070 #include "t_ptrace_x86_wait.h" 9071 9072 /// ---------------------------------------------------------------------------- 9073 9074 #else 9075 ATF_TC(dummy); 9076 ATF_TC_HEAD(dummy, tc) 9077 { 9078 atf_tc_set_md_var(tc, "descr", "A dummy test"); 9079 } 9080 9081 ATF_TC_BODY(dummy, tc) 9082 { 9083 9084 // Dummy, skipped 9085 // The ATF framework requires at least a single defined test. 9086 } 9087 #endif 9088 9089 ATF_TP_ADD_TCS(tp) 9090 { 9091 setvbuf(stdout, NULL, _IONBF, 0); 9092 setvbuf(stderr, NULL, _IONBF, 0); 9093 9094 #ifdef ENABLE_TESTS 9095 ATF_TP_ADD_TC(tp, traceme_raise1); 9096 ATF_TP_ADD_TC(tp, traceme_raise2); 9097 ATF_TP_ADD_TC(tp, traceme_raise3); 9098 ATF_TP_ADD_TC(tp, traceme_raise4); 9099 ATF_TP_ADD_TC(tp, traceme_raise5); 9100 ATF_TP_ADD_TC(tp, traceme_raise6); 9101 ATF_TP_ADD_TC(tp, traceme_raise7); 9102 ATF_TP_ADD_TC(tp, traceme_raise8); 9103 ATF_TP_ADD_TC(tp, traceme_raise9); 9104 ATF_TP_ADD_TC(tp, traceme_raise10); 9105 9106 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 9107 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 9108 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 9109 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 9110 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 9111 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 9112 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 9113 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 9114 9115 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 9116 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 9117 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 9118 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 9119 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 9120 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 9121 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 9122 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 9123 9124 ATF_TP_ADD_TC(tp, traceme_crash_trap); 9125 ATF_TP_ADD_TC(tp, traceme_crash_segv); 9126 ATF_TP_ADD_TC(tp, traceme_crash_ill); 9127 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 9128 ATF_TP_ADD_TC(tp, traceme_crash_bus); 9129 9130 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 9131 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 9132 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 9133 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 9134 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 9135 9136 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 9137 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 9138 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 9139 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 9140 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 9141 9142 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 9143 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 9144 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 9145 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 9146 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 9147 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 9148 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 9149 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 9150 9151 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 9152 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 9153 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 9154 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 9155 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 9156 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 9157 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 9158 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 9159 9160 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 9161 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 9162 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 9163 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 9164 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 9165 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 9166 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 9167 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 9168 9169 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 9170 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 9171 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 9172 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 9173 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 9174 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 9175 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 9176 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 9177 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 9178 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 9179 9180 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 9181 9182 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 9183 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 9184 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 9185 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 9186 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 9187 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 9188 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 9189 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 9190 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 9191 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 9192 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 9193 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 9194 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 9195 9196 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 9197 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 9198 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 9199 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 9200 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 9201 9202 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 9203 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 9204 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 9205 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 9206 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 9207 9208 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 9209 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 9210 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 9211 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 9212 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 9213 9214 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 9215 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 9216 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 9217 9218 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 9219 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 9220 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 9221 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 9222 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 9223 9224 ATF_TP_ADD_TC_HAVE_PID(tp, 9225 unrelated_tracer_sees_signalmasked_crash_trap); 9226 ATF_TP_ADD_TC_HAVE_PID(tp, 9227 unrelated_tracer_sees_signalmasked_crash_segv); 9228 ATF_TP_ADD_TC_HAVE_PID(tp, 9229 unrelated_tracer_sees_signalmasked_crash_ill); 9230 ATF_TP_ADD_TC_HAVE_PID(tp, 9231 unrelated_tracer_sees_signalmasked_crash_fpe); 9232 ATF_TP_ADD_TC_HAVE_PID(tp, 9233 unrelated_tracer_sees_signalmasked_crash_bus); 9234 9235 ATF_TP_ADD_TC_HAVE_PID(tp, 9236 unrelated_tracer_sees_signalignored_crash_trap); 9237 ATF_TP_ADD_TC_HAVE_PID(tp, 9238 unrelated_tracer_sees_signalignored_crash_segv); 9239 ATF_TP_ADD_TC_HAVE_PID(tp, 9240 unrelated_tracer_sees_signalignored_crash_ill); 9241 ATF_TP_ADD_TC_HAVE_PID(tp, 9242 unrelated_tracer_sees_signalignored_crash_fpe); 9243 ATF_TP_ADD_TC_HAVE_PID(tp, 9244 unrelated_tracer_sees_signalignored_crash_bus); 9245 9246 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 9247 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 9248 ATF_TP_ADD_TC_HAVE_PID(tp, 9249 unrelated_tracer_sees_terminaton_before_the_parent); 9250 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 9251 9252 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 9253 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 9254 9255 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 9256 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 9257 9258 ATF_TP_ADD_TC_HAVE_PID(tp, 9259 tracee_sees_its_original_parent_getppid); 9260 ATF_TP_ADD_TC_HAVE_PID(tp, 9261 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 9262 ATF_TP_ADD_TC_HAVE_PID(tp, 9263 tracee_sees_its_original_parent_procfs_status); 9264 9265 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 9266 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 9267 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 9268 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 9269 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 9270 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 9271 ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn); 9272 9273 ATF_TP_ADD_TC(tp, fork1); 9274 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 9275 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 9276 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 9277 ATF_TP_ADD_TC(tp, fork5); 9278 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 9279 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 9280 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 9281 ATF_TP_ADD_TC(tp, fork9); 9282 ATF_TP_ADD_TC_HAVE_PID(tp, fork10); 9283 ATF_TP_ADD_TC_HAVE_PID(tp, fork11); 9284 ATF_TP_ADD_TC_HAVE_PID(tp, fork12); 9285 ATF_TP_ADD_TC(tp, fork13); 9286 ATF_TP_ADD_TC_HAVE_PID(tp, fork14); 9287 ATF_TP_ADD_TC_HAVE_PID(tp, fork15); 9288 ATF_TP_ADD_TC_HAVE_PID(tp, fork16); 9289 9290 ATF_TP_ADD_TC(tp, vfork1); 9291 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 9292 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 9293 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 9294 ATF_TP_ADD_TC(tp, vfork5); 9295 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 9296 ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 9297 ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 9298 ATF_TP_ADD_TC(tp, vfork9); 9299 ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); 9300 ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); 9301 ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); 9302 ATF_TP_ADD_TC(tp, vfork13); 9303 ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); 9304 ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); 9305 ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); 9306 9307 ATF_TP_ADD_TC(tp, posix_spawn1); 9308 ATF_TP_ADD_TC(tp, posix_spawn2); 9309 ATF_TP_ADD_TC(tp, posix_spawn3); 9310 ATF_TP_ADD_TC(tp, posix_spawn4); 9311 ATF_TP_ADD_TC(tp, posix_spawn5); 9312 ATF_TP_ADD_TC(tp, posix_spawn6); 9313 ATF_TP_ADD_TC(tp, posix_spawn7); 9314 ATF_TP_ADD_TC(tp, posix_spawn8); 9315 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); 9316 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); 9317 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); 9318 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); 9319 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); 9320 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); 9321 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); 9322 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); 9323 9324 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1); 9325 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2); 9326 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3); 9327 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4); 9328 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5); 9329 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6); 9330 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7); 9331 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8); 9332 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9); 9333 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10); 9334 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11); 9335 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12); 9336 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13); 9337 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14); 9338 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15); 9339 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16); 9340 9341 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1); 9342 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2); 9343 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3); 9344 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4); 9345 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5); 9346 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6); 9347 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7); 9348 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8); 9349 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9); 9350 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10); 9351 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11); 9352 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12); 9353 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13); 9354 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14); 9355 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15); 9356 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16); 9357 9358 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1); 9359 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2); 9360 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3); 9361 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4); 9362 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5); 9363 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6); 9364 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7); 9365 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8); 9366 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9); 9367 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10); 9368 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11); 9369 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12); 9370 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13); 9371 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14); 9372 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15); 9373 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16); 9374 9375 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); 9376 ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); 9377 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); 9378 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); 9379 9380 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); 9381 ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); 9382 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); 9383 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); 9384 9385 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner); 9386 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker); 9387 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker); 9388 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone); 9389 9390 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner); 9391 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker); 9392 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker); 9393 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone); 9394 9395 ATF_TP_ADD_TC(tp, traceme_vfork_fork); 9396 ATF_TP_ADD_TC(tp, traceme_vfork_vfork); 9397 9398 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 9399 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 9400 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 9401 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 9402 9403 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 9404 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 9405 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 9406 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 9407 9408 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 9409 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 9410 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 9411 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 9412 9413 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 9414 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 9415 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 9416 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 9417 9418 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 9419 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 9420 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 9421 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 9422 9423 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 9424 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 9425 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 9426 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 9427 9428 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 9429 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 9430 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 9431 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 9432 9433 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 9434 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 9435 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 9436 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 9437 9438 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 9439 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 9440 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 9441 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 9442 9443 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 9444 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 9445 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 9446 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 9447 9448 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 9449 9450 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); 9451 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); 9452 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); 9453 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); 9454 9455 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); 9456 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); 9457 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); 9458 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); 9459 9460 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); 9461 9462 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); 9463 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); 9464 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); 9465 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); 9466 9467 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); 9468 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); 9469 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); 9470 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d); 9471 9472 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 9473 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 9474 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 9475 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 9476 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 9477 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 9478 9479 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs_set_unaligned_pc_0x1); 9480 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs_set_unaligned_pc_0x3); 9481 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs_set_unaligned_pc_0x7); 9482 9483 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 9484 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 9485 9486 ATF_TP_ADD_TC_PT_STEP(tp, step1); 9487 ATF_TP_ADD_TC_PT_STEP(tp, step2); 9488 ATF_TP_ADD_TC_PT_STEP(tp, step3); 9489 ATF_TP_ADD_TC_PT_STEP(tp, step4); 9490 9491 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 9492 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 9493 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 9494 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 9495 9496 ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked); 9497 ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored); 9498 9499 ATF_TP_ADD_TC(tp, kill1); 9500 ATF_TP_ADD_TC(tp, kill2); 9501 ATF_TP_ADD_TC(tp, kill3); 9502 9503 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 9504 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 9505 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 9506 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 9507 9508 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus); 9509 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus); 9510 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus); 9511 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus); 9512 9513 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask); 9514 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask); 9515 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask); 9516 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask); 9517 9518 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name); 9519 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name); 9520 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name); 9521 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name); 9522 9523 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private); 9524 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private); 9525 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private); 9526 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private); 9527 9528 ATF_TP_ADD_TC(tp, traceme_lwpnext0); 9529 ATF_TP_ADD_TC(tp, traceme_lwpnext1); 9530 ATF_TP_ADD_TC(tp, traceme_lwpnext2); 9531 ATF_TP_ADD_TC(tp, traceme_lwpnext3); 9532 9533 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask); 9534 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask); 9535 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask); 9536 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask); 9537 9538 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name); 9539 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name); 9540 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name); 9541 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name); 9542 9543 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private); 9544 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private); 9545 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private); 9546 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private); 9547 9548 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 9549 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 9550 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 9551 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 9552 9553 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 9554 ATF_TP_ADD_TC(tp, siginfo_set_faked); 9555 9556 ATF_TP_ADD_TC(tp, traceme_exec); 9557 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 9558 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 9559 9560 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 9561 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 9562 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 9563 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 9564 9565 ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap); 9566 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap); 9567 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap); 9568 9569 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 9570 9571 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked); 9572 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored); 9573 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked); 9574 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored); 9575 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked); 9576 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored); 9577 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked); 9578 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored); 9579 9580 ATF_TP_ADD_TC(tp, threads_and_exec); 9581 9582 ATF_TP_ADD_TC(tp, suspend_no_deadlock); 9583 9584 ATF_TP_ADD_TC(tp, resume); 9585 9586 ATF_TP_ADD_TC(tp, syscall); 9587 ATF_TP_ADD_TC(tp, syscall_killed_on_sce); 9588 ATF_TP_ADD_TC(tp, syscall_signal_on_sce); 9589 ATF_TP_ADD_TC(tp, syscall_detach_on_sce); 9590 9591 ATF_TP_ADD_TC(tp, syscallemu1); 9592 9593 ATF_TP_ADD_TC(tp, clone1); 9594 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); 9595 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); 9596 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); 9597 ATF_TP_ADD_TC(tp, clone5); 9598 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); 9599 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); 9600 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); 9601 9602 ATF_TP_ADD_TC(tp, clone_vm1); 9603 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); 9604 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); 9605 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); 9606 ATF_TP_ADD_TC(tp, clone_vm5); 9607 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); 9608 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); 9609 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); 9610 9611 ATF_TP_ADD_TC(tp, clone_fs1); 9612 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); 9613 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); 9614 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); 9615 ATF_TP_ADD_TC(tp, clone_fs5); 9616 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); 9617 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); 9618 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); 9619 9620 ATF_TP_ADD_TC(tp, clone_files1); 9621 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); 9622 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); 9623 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); 9624 ATF_TP_ADD_TC(tp, clone_files5); 9625 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); 9626 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); 9627 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); 9628 9629 // ATF_TP_ADD_TC(tp, clone_sighand1); // XXX 9630 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX 9631 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX 9632 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX 9633 // ATF_TP_ADD_TC(tp, clone_sighand5); // XXX 9634 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX 9635 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX 9636 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX 9637 9638 ATF_TP_ADD_TC(tp, clone_vfork1); 9639 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); 9640 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); 9641 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); 9642 ATF_TP_ADD_TC(tp, clone_vfork5); 9643 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); 9644 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); 9645 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); 9646 9647 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); 9648 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); 9649 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); 9650 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); 9651 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); 9652 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); 9653 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); 9654 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); 9655 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX 9656 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX 9657 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); 9658 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); 9659 9660 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); 9661 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); 9662 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); 9663 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); 9664 // ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX 9665 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork); 9666 9667 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 9668 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 9669 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 9670 9671 ATF_TP_ADD_TC(tp, core_dump_procinfo); 9672 9673 #if defined(TWAIT_HAVE_STATUS) 9674 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 9675 ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign); 9676 ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler); 9677 #if defined(__i386__) || defined(__x86_64__) 9678 ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints); 9679 ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints); 9680 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp); 9681 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig); 9682 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign); 9683 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler); 9684 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig); 9685 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign); 9686 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler); 9687 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig); 9688 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign); 9689 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler); 9690 #endif 9691 #endif 9692 9693 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 9694 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 9695 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 9696 9697 #else 9698 ATF_TP_ADD_TC(tp, dummy); 9699 #endif 9700 9701 return atf_no_error(); 9702 } 9703