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