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