t_ptrace_wait.c revision 1.176
1/* $NetBSD: t_ptrace_wait.c,v 1.176 2020/05/04 21:33:20 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.176 2020/05/04 21:33:20 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 void 5018ptrace_kill(const char *type) 5019{ 5020 const int sigval = SIGSTOP; 5021 pid_t child, wpid; 5022#if defined(TWAIT_HAVE_STATUS) 5023 int status; 5024#endif 5025 5026 DPRINTF("Before forking process PID=%d\n", getpid()); 5027 SYSCALL_REQUIRE((child = fork()) != -1); 5028 if (child == 0) { 5029 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5030 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5031 5032 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5033 FORKEE_ASSERT(raise(sigval) == 0); 5034 5035 /* NOTREACHED */ 5036 FORKEE_ASSERTX(0 && 5037 "Child should be terminated by a signal from its parent"); 5038 } 5039 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5040 5041 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5042 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5043 5044 validate_status_stopped(status, sigval); 5045 5046 DPRINTF("Before killing the child process with %s\n", type); 5047 if (strcmp(type, "ptrace(PT_KILL)") == 0) { 5048 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 5049 } else if (strcmp(type, "kill(SIGKILL)") == 0) { 5050 kill(child, SIGKILL); 5051 } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 5052 setpgid(child, 0); 5053 killpg(getpgid(child), SIGKILL); 5054 } 5055 5056 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5057 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5058 5059 validate_status_signaled(status, SIGKILL, 0); 5060 5061 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5062 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5063} 5064 5065#define PTRACE_KILL(test, type) \ 5066ATF_TC(test); \ 5067ATF_TC_HEAD(test, tc) \ 5068{ \ 5069 atf_tc_set_md_var(tc, "descr", \ 5070 "Verify killing the child with " type); \ 5071} \ 5072 \ 5073ATF_TC_BODY(test, tc) \ 5074{ \ 5075 \ 5076 ptrace_kill(type); \ 5077} 5078 5079// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 5080PTRACE_KILL(kill1, "ptrace(PT_KILL)") 5081PTRACE_KILL(kill2, "kill(SIGKILL)") 5082PTRACE_KILL(kill3, "killpg(SIGKILL)") 5083 5084/// ---------------------------------------------------------------------------- 5085 5086static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG}; 5087 5088static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER; 5089static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER; 5090static volatile size_t lwpinfo_thread_done; 5091 5092static void * 5093lwpinfo_thread(void *arg) 5094{ 5095 sigset_t s; 5096 volatile void **tcb; 5097 5098 tcb = (volatile void **)arg; 5099 5100 *tcb = _lwp_getprivate(); 5101 DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self()); 5102 5103 pthread_setname_np(pthread_self(), "thread %d", 5104 (void *)(intptr_t)_lwp_self()); 5105 5106 sigemptyset(&s); 5107 pthread_mutex_lock(&lwpinfo_thread_mtx); 5108 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 5109 lwpinfo_thread_done++; 5110 pthread_sigmask(SIG_BLOCK, &s, NULL); 5111 pthread_cond_signal(&lwpinfo_thread_cnd); 5112 pthread_mutex_unlock(&lwpinfo_thread_mtx); 5113 5114 return infinite_thread(NULL); 5115} 5116 5117static void 5118traceme_lwpinfo(const size_t threads, const char *iter) 5119{ 5120 const int sigval = SIGSTOP; 5121 const int sigval2 = SIGINT; 5122 pid_t child, wpid; 5123#if defined(TWAIT_HAVE_STATUS) 5124 int status; 5125#endif 5126 struct ptrace_lwpinfo lwp = {0, 0}; 5127 struct ptrace_lwpstatus lwpstatus = {0}; 5128 struct ptrace_siginfo info; 5129 void *private; 5130 char *name; 5131 char namebuf[PL_LNAMELEN]; 5132 volatile void *tcb[4]; 5133 bool found; 5134 sigset_t s; 5135 5136 /* Maximum number of supported threads in this test */ 5137 pthread_t t[__arraycount(tcb) - 1]; 5138 size_t n, m; 5139 int rv; 5140 size_t bytes_read; 5141 5142 struct ptrace_io_desc io; 5143 sigset_t sigmask; 5144 5145 ATF_REQUIRE(__arraycount(t) >= threads); 5146 memset(tcb, 0, sizeof(tcb)); 5147 5148 DPRINTF("Before forking process PID=%d\n", getpid()); 5149 SYSCALL_REQUIRE((child = fork()) != -1); 5150 if (child == 0) { 5151 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5152 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5153 5154 tcb[0] = _lwp_getprivate(); 5155 DPRINTF("Storing tcb[0] = %p\n", tcb[0]); 5156 5157 pthread_setname_np(pthread_self(), "thread %d", 5158 (void *)(intptr_t)_lwp_self()); 5159 5160 sigemptyset(&s); 5161 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 5162 pthread_sigmask(SIG_BLOCK, &s, NULL); 5163 5164 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5165 FORKEE_ASSERT(raise(sigval) == 0); 5166 5167 for (n = 0; n < threads; n++) { 5168 rv = pthread_create(&t[n], NULL, lwpinfo_thread, 5169 &tcb[n + 1]); 5170 FORKEE_ASSERT(rv == 0); 5171 } 5172 5173 pthread_mutex_lock(&lwpinfo_thread_mtx); 5174 while (lwpinfo_thread_done < threads) { 5175 pthread_cond_wait(&lwpinfo_thread_cnd, 5176 &lwpinfo_thread_mtx); 5177 } 5178 pthread_mutex_unlock(&lwpinfo_thread_mtx); 5179 5180 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 5181 FORKEE_ASSERT(raise(sigval2) == 0); 5182 5183 /* NOTREACHED */ 5184 FORKEE_ASSERTX(0 && "Not reached"); 5185 } 5186 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5187 5188 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5189 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5190 5191 validate_status_stopped(status, sigval); 5192 5193 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 5194 SYSCALL_REQUIRE( 5195 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5196 5197 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5198 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5199 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5200 info.psi_siginfo.si_errno); 5201 5202 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5203 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5204 5205 if (strstr(iter, "LWPINFO") != NULL) { 5206 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5207 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5208 != -1); 5209 5210 DPRINTF("Assert that there exists a single thread only\n"); 5211 ATF_REQUIRE(lwp.pl_lwpid > 0); 5212 5213 DPRINTF("Assert that lwp thread %d received event " 5214 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 5215 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 5216 5217 if (strstr(iter, "LWPSTATUS") != NULL) { 5218 DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS " 5219 "for child\n"); 5220 lwpstatus.pl_lwpid = lwp.pl_lwpid; 5221 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus, 5222 sizeof(lwpstatus)) != -1); 5223 } 5224 5225 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5226 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5227 != -1); 5228 5229 DPRINTF("Assert that there exists a single thread only\n"); 5230 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 5231 } else { 5232 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5233 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5234 sizeof(lwpstatus)) != -1); 5235 5236 DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid); 5237 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 5238 5239 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5240 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5241 sizeof(lwpstatus)) != -1); 5242 5243 DPRINTF("Assert that there exists a single thread only\n"); 5244 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 5245 } 5246 5247 DPRINTF("Before resuming the child process where it left off and " 5248 "without signal to be sent\n"); 5249 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5250 5251 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5252 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5253 5254 validate_status_stopped(status, sigval2); 5255 5256 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 5257 SYSCALL_REQUIRE( 5258 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5259 5260 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5261 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5262 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5263 info.psi_siginfo.si_errno); 5264 5265 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 5266 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5267 5268 memset(&lwp, 0, sizeof(lwp)); 5269 memset(&lwpstatus, 0, sizeof(lwpstatus)); 5270 5271 memset(&io, 0, sizeof(io)); 5272 5273 bytes_read = 0; 5274 io.piod_op = PIOD_READ_D; 5275 io.piod_len = sizeof(tcb); 5276 5277 do { 5278 io.piod_addr = (char *)&tcb + bytes_read; 5279 io.piod_offs = io.piod_addr; 5280 5281 rv = ptrace(PT_IO, child, &io, sizeof(io)); 5282 ATF_REQUIRE(rv != -1 && io.piod_len != 0); 5283 5284 bytes_read += io.piod_len; 5285 io.piod_len = sizeof(tcb) - bytes_read; 5286 } while (bytes_read < sizeof(tcb)); 5287 5288 for (n = 0; n <= threads; n++) { 5289 if (strstr(iter, "LWPINFO") != NULL) { 5290 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5291 "child\n"); 5292 SYSCALL_REQUIRE( 5293 ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 5294 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5295 5296 DPRINTF("Assert that the thread exists\n"); 5297 ATF_REQUIRE(lwp.pl_lwpid > 0); 5298 5299 DPRINTF("Assert that lwp thread %d received expected " 5300 "event\n", lwp.pl_lwpid); 5301 FORKEE_ASSERT_EQ(lwp.pl_event, 5302 info.psi_lwpid == lwp.pl_lwpid ? 5303 PL_EVENT_SIGNAL : PL_EVENT_NONE); 5304 5305 if (strstr(iter, "LWPSTATUS") != NULL) { 5306 DPRINTF("Before calling ptrace(2) with " 5307 "PT_LWPSTATUS for child\n"); 5308 lwpstatus.pl_lwpid = lwp.pl_lwpid; 5309 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, 5310 &lwpstatus, sizeof(lwpstatus)) != -1); 5311 5312 goto check_lwpstatus; 5313 } 5314 } else { 5315 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for " 5316 "child\n"); 5317 SYSCALL_REQUIRE( 5318 ptrace(PT_LWPNEXT, child, &lwpstatus, 5319 sizeof(lwpstatus)) != -1); 5320 DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid); 5321 5322 DPRINTF("Assert that the thread exists\n"); 5323 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 5324 5325 check_lwpstatus: 5326 5327 if (strstr(iter, "pl_sigmask") != NULL) { 5328 sigmask = lwpstatus.pl_sigmask; 5329 5330 DPRINTF("Retrieved sigmask: " 5331 "%02x%02x%02x%02x\n", 5332 sigmask.__bits[0], sigmask.__bits[1], 5333 sigmask.__bits[2], sigmask.__bits[3]); 5334 5335 found = false; 5336 for (m = 0; 5337 m < __arraycount(lwpinfo_thread_sigmask); 5338 m++) { 5339 if (sigismember(&sigmask, 5340 lwpinfo_thread_sigmask[m])) { 5341 found = true; 5342 lwpinfo_thread_sigmask[m] = 0; 5343 break; 5344 } 5345 } 5346 ATF_REQUIRE(found == true); 5347 } else if (strstr(iter, "pl_name") != NULL) { 5348 name = lwpstatus.pl_name; 5349 5350 DPRINTF("Retrieved thread name: " 5351 "%s\n", name); 5352 5353 snprintf(namebuf, sizeof namebuf, "thread %d", 5354 lwpstatus.pl_lwpid); 5355 5356 ATF_REQUIRE(strcmp(name, namebuf) == 0); 5357 } else if (strstr(iter, "pl_private") != NULL) { 5358 private = lwpstatus.pl_private; 5359 5360 DPRINTF("Retrieved thread private pointer: " 5361 "%p\n", private); 5362 5363 found = false; 5364 for (m = 0; m < __arraycount(tcb); m++) { 5365 DPRINTF("Comparing %p and %p\n", 5366 private, tcb[m]); 5367 if (private == tcb[m]) { 5368 found = true; 5369 break; 5370 } 5371 } 5372 ATF_REQUIRE(found == true); 5373 } 5374 } 5375 } 5376 5377 if (strstr(iter, "LWPINFO") != NULL) { 5378 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5379 "child\n"); 5380 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5381 != -1); 5382 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5383 5384 DPRINTF("Assert that there are no more threads\n"); 5385 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 5386 } else { 5387 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5388 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5389 sizeof(lwpstatus)) != -1); 5390 5391 DPRINTF("Assert that there exists a single thread only\n"); 5392 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 5393 } 5394 5395 DPRINTF("Before resuming the child process where it left off and " 5396 "without signal to be sent\n"); 5397 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 5398 5399 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5400 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5401 5402 validate_status_signaled(status, SIGKILL, 0); 5403 5404 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5405 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5406} 5407 5408#define TRACEME_LWPINFO(test, threads, iter) \ 5409ATF_TC(test); \ 5410ATF_TC_HEAD(test, tc) \ 5411{ \ 5412 atf_tc_set_md_var(tc, "descr", \ 5413 "Verify " iter " with the child with " #threads \ 5414 " spawned extra threads"); \ 5415} \ 5416 \ 5417ATF_TC_BODY(test, tc) \ 5418{ \ 5419 \ 5420 traceme_lwpinfo(threads, iter); \ 5421} 5422 5423TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO") 5424TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO") 5425TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO") 5426TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO") 5427 5428TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS") 5429TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS") 5430TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS") 5431TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS") 5432 5433TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0, 5434 "LWPINFO+LWPSTATUS+pl_sigmask") 5435TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1, 5436 "LWPINFO+LWPSTATUS+pl_sigmask") 5437TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2, 5438 "LWPINFO+LWPSTATUS+pl_sigmask") 5439TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3, 5440 "LWPINFO+LWPSTATUS+pl_sigmask") 5441 5442TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0, 5443 "LWPINFO+LWPSTATUS+pl_name") 5444TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1, 5445 "LWPINFO+LWPSTATUS+pl_name") 5446TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2, 5447 "LWPINFO+LWPSTATUS+pl_name") 5448TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3, 5449 "LWPINFO+LWPSTATUS+pl_name") 5450 5451TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0, 5452 "LWPINFO+LWPSTATUS+pl_private") 5453TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1, 5454 "LWPINFO+LWPSTATUS+pl_private") 5455TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2, 5456 "LWPINFO+LWPSTATUS+pl_private") 5457TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3, 5458 "LWPINFO+LWPSTATUS+pl_private") 5459 5460TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT") 5461TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT") 5462TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT") 5463TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT") 5464 5465TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask") 5466TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask") 5467TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask") 5468TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask") 5469 5470TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name") 5471TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name") 5472TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name") 5473TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name") 5474 5475TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private") 5476TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private") 5477TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private") 5478TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private") 5479 5480/// ---------------------------------------------------------------------------- 5481 5482#if defined(TWAIT_HAVE_PID) 5483static void 5484attach_lwpinfo(const int threads) 5485{ 5486 const int sigval = SIGINT; 5487 struct msg_fds parent_tracee, parent_tracer; 5488 const int exitval_tracer = 10; 5489 pid_t tracee, tracer, wpid; 5490 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 5491#if defined(TWAIT_HAVE_STATUS) 5492 int status; 5493#endif 5494 struct ptrace_lwpinfo lwp = {0, 0}; 5495 struct ptrace_siginfo info; 5496 5497 /* Maximum number of supported threads in this test */ 5498 pthread_t t[3]; 5499 int n, rv; 5500 5501 DPRINTF("Spawn tracee\n"); 5502 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 5503 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 5504 tracee = atf_utils_fork(); 5505 if (tracee == 0) { 5506 /* Wait for message from the parent */ 5507 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 5508 5509 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 5510 5511 for (n = 0; n < threads; n++) { 5512 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 5513 FORKEE_ASSERT(rv == 0); 5514 } 5515 5516 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 5517 5518 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5519 FORKEE_ASSERT(raise(sigval) == 0); 5520 5521 /* NOTREACHED */ 5522 FORKEE_ASSERTX(0 && "Not reached"); 5523 } 5524 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 5525 5526 DPRINTF("Spawn debugger\n"); 5527 tracer = atf_utils_fork(); 5528 if (tracer == 0) { 5529 /* No IPC to communicate with the child */ 5530 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 5531 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 5532 5533 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 5534 FORKEE_REQUIRE_SUCCESS( 5535 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5536 5537 forkee_status_stopped(status, SIGSTOP); 5538 5539 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5540 "tracee"); 5541 FORKEE_ASSERT( 5542 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5543 5544 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5545 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5546 "si_errno=%#x\n", 5547 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5548 info.psi_siginfo.si_errno); 5549 5550 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 5551 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 5552 5553 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5554 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5555 != -1); 5556 5557 DPRINTF("Assert that there exists a thread\n"); 5558 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 5559 5560 DPRINTF("Assert that lwp thread %d received event " 5561 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 5562 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 5563 5564 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5565 "tracee\n"); 5566 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5567 != -1); 5568 5569 DPRINTF("Assert that there are no more lwp threads in " 5570 "tracee\n"); 5571 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 5572 5573 /* Resume tracee with PT_CONTINUE */ 5574 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 5575 5576 /* Inform parent that tracer has attached to tracee */ 5577 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 5578 5579 /* Wait for parent */ 5580 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 5581 5582 /* Wait for tracee and assert that it raised a signal */ 5583 FORKEE_REQUIRE_SUCCESS( 5584 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5585 5586 forkee_status_stopped(status, SIGINT); 5587 5588 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5589 "child"); 5590 FORKEE_ASSERT( 5591 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5592 5593 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5594 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5595 "si_errno=%#x\n", 5596 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5597 info.psi_siginfo.si_errno); 5598 5599 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 5600 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 5601 5602 memset(&lwp, 0, sizeof(lwp)); 5603 5604 for (n = 0; n <= threads; n++) { 5605 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5606 "child\n"); 5607 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 5608 sizeof(lwp)) != -1); 5609 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5610 5611 DPRINTF("Assert that the thread exists\n"); 5612 FORKEE_ASSERT(lwp.pl_lwpid > 0); 5613 5614 DPRINTF("Assert that lwp thread %d received expected " 5615 "event\n", lwp.pl_lwpid); 5616 FORKEE_ASSERT_EQ(lwp.pl_event, 5617 info.psi_lwpid == lwp.pl_lwpid ? 5618 PL_EVENT_SIGNAL : PL_EVENT_NONE); 5619 } 5620 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5621 "tracee\n"); 5622 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5623 != -1); 5624 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5625 5626 DPRINTF("Assert that there are no more threads\n"); 5627 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 5628 5629 DPRINTF("Before resuming the child process where it left off " 5630 "and without signal to be sent\n"); 5631 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 5632 != -1); 5633 5634 /* Wait for tracee and assert that it exited */ 5635 FORKEE_REQUIRE_SUCCESS( 5636 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5637 5638 forkee_status_signaled(status, SIGKILL, 0); 5639 5640 DPRINTF("Before exiting of the tracer process\n"); 5641 _exit(exitval_tracer); 5642 } 5643 5644 DPRINTF("Wait for the tracer to attach to the tracee\n"); 5645 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 5646 5647 DPRINTF("Resume the tracee and spawn threads\n"); 5648 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 5649 5650 DPRINTF("Resume the tracee and let it exit\n"); 5651 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 5652 5653 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 5654 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 5655 5656 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 5657 TWAIT_FNAME); 5658 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 5659 tracer); 5660 5661 validate_status_exited(status, exitval_tracer); 5662 5663 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 5664 TWAIT_FNAME); 5665 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 5666 tracee); 5667 5668 validate_status_signaled(status, SIGKILL, 0); 5669 5670 msg_close(&parent_tracer); 5671 msg_close(&parent_tracee); 5672} 5673 5674#define ATTACH_LWPINFO(test, threads) \ 5675ATF_TC(test); \ 5676ATF_TC_HEAD(test, tc) \ 5677{ \ 5678 atf_tc_set_md_var(tc, "descr", \ 5679 "Verify LWPINFO with the child with " #threads \ 5680 " spawned extra threads (tracer is not the original " \ 5681 "parent)"); \ 5682} \ 5683 \ 5684ATF_TC_BODY(test, tc) \ 5685{ \ 5686 \ 5687 attach_lwpinfo(threads); \ 5688} 5689 5690ATTACH_LWPINFO(attach_lwpinfo0, 0) 5691ATTACH_LWPINFO(attach_lwpinfo1, 1) 5692ATTACH_LWPINFO(attach_lwpinfo2, 2) 5693ATTACH_LWPINFO(attach_lwpinfo3, 3) 5694#endif 5695 5696/// ---------------------------------------------------------------------------- 5697 5698static void 5699ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 5700{ 5701 const int exitval = 5; 5702 const int sigval = SIGINT; 5703 const int sigfaked = SIGTRAP; 5704 const int sicodefaked = TRAP_BRKPT; 5705 pid_t child, wpid; 5706 struct sigaction sa; 5707#if defined(TWAIT_HAVE_STATUS) 5708 int status; 5709#endif 5710 struct ptrace_siginfo info; 5711 memset(&info, 0, sizeof(info)); 5712 5713 DPRINTF("Before forking process PID=%d\n", getpid()); 5714 SYSCALL_REQUIRE((child = fork()) != -1); 5715 if (child == 0) { 5716 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5717 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5718 5719 sa.sa_sigaction = sah; 5720 sa.sa_flags = SA_SIGINFO; 5721 sigemptyset(&sa.sa_mask); 5722 5723 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 5724 != -1); 5725 5726 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5727 FORKEE_ASSERT(raise(sigval) == 0); 5728 5729 FORKEE_ASSERT_EQ(*signal_caught, 1); 5730 5731 DPRINTF("Before exiting of the child process\n"); 5732 _exit(exitval); 5733 } 5734 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5735 5736 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5737 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5738 5739 validate_status_stopped(status, sigval); 5740 5741 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5742 SYSCALL_REQUIRE( 5743 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5744 5745 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5746 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5747 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5748 info.psi_siginfo.si_errno); 5749 5750 if (faked) { 5751 DPRINTF("Before setting new faked signal to signo=%d " 5752 "si_code=%d\n", sigfaked, sicodefaked); 5753 info.psi_siginfo.si_signo = sigfaked; 5754 info.psi_siginfo.si_code = sicodefaked; 5755 } 5756 5757 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 5758 SYSCALL_REQUIRE( 5759 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 5760 5761 if (faked) { 5762 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5763 "child\n"); 5764 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 5765 sizeof(info)) != -1); 5766 5767 DPRINTF("Before checking siginfo_t\n"); 5768 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 5769 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 5770 } 5771 5772 DPRINTF("Before resuming the child process where it left off and " 5773 "without signal to be sent\n"); 5774 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 5775 faked ? sigfaked : sigval) != -1); 5776 5777 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5778 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5779 5780 validate_status_exited(status, exitval); 5781 5782 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5783 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5784} 5785 5786#define PTRACE_SIGINFO(test, faked) \ 5787ATF_TC(test); \ 5788ATF_TC_HEAD(test, tc) \ 5789{ \ 5790 atf_tc_set_md_var(tc, "descr", \ 5791 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 5792 "with%s setting signal to new value", faked ? "" : "out"); \ 5793} \ 5794 \ 5795static int test##_caught = 0; \ 5796 \ 5797static void \ 5798test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 5799{ \ 5800 if (faked) { \ 5801 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 5802 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 5803 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 5804 } else { \ 5805 FORKEE_ASSERT_EQ(sig, SIGINT); \ 5806 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 5807 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 5808 } \ 5809 \ 5810 ++ test##_caught; \ 5811} \ 5812 \ 5813ATF_TC_BODY(test, tc) \ 5814{ \ 5815 \ 5816 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 5817} 5818 5819PTRACE_SIGINFO(siginfo_set_unmodified, false) 5820PTRACE_SIGINFO(siginfo_set_faked, true) 5821 5822/// ---------------------------------------------------------------------------- 5823 5824static void 5825traceme_exec(bool masked, bool ignored) 5826{ 5827 const int sigval = SIGTRAP; 5828 pid_t child, wpid; 5829#if defined(TWAIT_HAVE_STATUS) 5830 int status; 5831#endif 5832 struct sigaction sa; 5833 struct ptrace_siginfo info; 5834 sigset_t intmask; 5835 struct kinfo_proc2 kp; 5836 size_t len = sizeof(kp); 5837 5838 int name[6]; 5839 const size_t namelen = __arraycount(name); 5840 ki_sigset_t kp_sigmask; 5841 ki_sigset_t kp_sigignore; 5842 5843 memset(&info, 0, sizeof(info)); 5844 5845 DPRINTF("Before forking process PID=%d\n", getpid()); 5846 SYSCALL_REQUIRE((child = fork()) != -1); 5847 if (child == 0) { 5848 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5849 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5850 5851 if (masked) { 5852 sigemptyset(&intmask); 5853 sigaddset(&intmask, sigval); 5854 sigprocmask(SIG_BLOCK, &intmask, NULL); 5855 } 5856 5857 if (ignored) { 5858 memset(&sa, 0, sizeof(sa)); 5859 sa.sa_handler = SIG_IGN; 5860 sigemptyset(&sa.sa_mask); 5861 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 5862 } 5863 5864 DPRINTF("Before calling execve(2) from child\n"); 5865 execlp("/bin/echo", "/bin/echo", NULL); 5866 5867 FORKEE_ASSERT(0 && "Not reached"); 5868 } 5869 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5870 5871 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5872 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5873 5874 validate_status_stopped(status, sigval); 5875 5876 name[0] = CTL_KERN, 5877 name[1] = KERN_PROC2, 5878 name[2] = KERN_PROC_PID; 5879 name[3] = getpid(); 5880 name[4] = sizeof(kp); 5881 name[5] = 1; 5882 5883 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5884 5885 if (masked) 5886 kp_sigmask = kp.p_sigmask; 5887 5888 if (ignored) 5889 kp_sigignore = kp.p_sigignore; 5890 5891 name[3] = getpid(); 5892 5893 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5894 5895 if (masked) { 5896 DPRINTF("kp_sigmask=" 5897 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5898 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5899 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5900 5901 DPRINTF("kp.p_sigmask=" 5902 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5903 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5904 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5905 5906 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5907 sizeof(kp_sigmask))); 5908 } 5909 5910 if (ignored) { 5911 DPRINTF("kp_sigignore=" 5912 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5913 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5914 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5915 5916 DPRINTF("kp.p_sigignore=" 5917 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5918 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5919 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5920 5921 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5922 sizeof(kp_sigignore))); 5923 } 5924 5925 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5926 SYSCALL_REQUIRE( 5927 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5928 5929 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5930 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5931 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5932 info.psi_siginfo.si_errno); 5933 5934 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5935 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 5936 5937 DPRINTF("Before resuming the child process where it left off and " 5938 "without signal to be sent\n"); 5939 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5940 5941 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5942 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5943 5944 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5945 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5946} 5947 5948#define TRACEME_EXEC(test, masked, ignored) \ 5949ATF_TC(test); \ 5950ATF_TC_HEAD(test, tc) \ 5951{ \ 5952 atf_tc_set_md_var(tc, "descr", \ 5953 "Detect SIGTRAP TRAP_EXEC from " \ 5954 "child%s%s", masked ? " with masked signal" : "", \ 5955 masked ? " with ignored signal" : ""); \ 5956} \ 5957 \ 5958ATF_TC_BODY(test, tc) \ 5959{ \ 5960 \ 5961 traceme_exec(masked, ignored); \ 5962} 5963 5964TRACEME_EXEC(traceme_exec, false, false) 5965TRACEME_EXEC(traceme_signalmasked_exec, true, false) 5966TRACEME_EXEC(traceme_signalignored_exec, false, true) 5967 5968/// ---------------------------------------------------------------------------- 5969 5970#define TRACE_THREADS_NUM 100 5971 5972static volatile int done; 5973pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 5974 5975static void * 5976trace_threads_cb(void *arg __unused) 5977{ 5978 5979 pthread_mutex_lock(&trace_threads_mtx); 5980 done++; 5981 pthread_mutex_unlock(&trace_threads_mtx); 5982 5983 while (done < TRACE_THREADS_NUM) 5984 sched_yield(); 5985 5986 return NULL; 5987} 5988 5989static void 5990trace_threads(bool trace_create, bool trace_exit, bool masked) 5991{ 5992 const int sigval = SIGSTOP; 5993 pid_t child, wpid; 5994#if defined(TWAIT_HAVE_STATUS) 5995 int status; 5996#endif 5997 ptrace_state_t state; 5998 const int slen = sizeof(state); 5999 ptrace_event_t event; 6000 const int elen = sizeof(event); 6001 struct ptrace_siginfo info; 6002 6003 sigset_t intmask; 6004 6005 pthread_t t[TRACE_THREADS_NUM]; 6006 int rv; 6007 size_t n; 6008 lwpid_t lid; 6009 6010 /* Track created and exited threads */ 6011 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 6012 6013 DPRINTF("Before forking process PID=%d\n", getpid()); 6014 SYSCALL_REQUIRE((child = fork()) != -1); 6015 if (child == 0) { 6016 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6017 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6018 6019 if (masked) { 6020 sigemptyset(&intmask); 6021 sigaddset(&intmask, SIGTRAP); 6022 sigprocmask(SIG_BLOCK, &intmask, NULL); 6023 } 6024 6025 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6026 FORKEE_ASSERT(raise(sigval) == 0); 6027 6028 for (n = 0; n < __arraycount(t); n++) { 6029 rv = pthread_create(&t[n], NULL, trace_threads_cb, 6030 NULL); 6031 FORKEE_ASSERT(rv == 0); 6032 } 6033 6034 for (n = 0; n < __arraycount(t); n++) { 6035 rv = pthread_join(t[n], NULL); 6036 FORKEE_ASSERT(rv == 0); 6037 } 6038 6039 /* 6040 * There is race between _exit() and pthread_join() detaching 6041 * a thread. For simplicity kill the process after detecting 6042 * LWP events. 6043 */ 6044 while (true) 6045 continue; 6046 6047 FORKEE_ASSERT(0 && "Not reached"); 6048 } 6049 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6050 6051 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6052 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6053 6054 validate_status_stopped(status, sigval); 6055 6056 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6057 SYSCALL_REQUIRE( 6058 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6059 6060 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6061 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6062 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6063 info.psi_siginfo.si_errno); 6064 6065 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6066 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6067 6068 DPRINTF("Set LWP event mask for the child %d\n", child); 6069 memset(&event, 0, sizeof(event)); 6070 if (trace_create) 6071 event.pe_set_event |= PTRACE_LWP_CREATE; 6072 if (trace_exit) 6073 event.pe_set_event |= PTRACE_LWP_EXIT; 6074 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6075 6076 DPRINTF("Before resuming the child process where it left off and " 6077 "without signal to be sent\n"); 6078 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6079 6080 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 6081 DPRINTF("Before calling %s() for the child - expected stopped " 6082 "SIGTRAP\n", TWAIT_FNAME); 6083 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6084 child); 6085 6086 validate_status_stopped(status, SIGTRAP); 6087 6088 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6089 "child\n"); 6090 SYSCALL_REQUIRE( 6091 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6092 6093 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6094 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 6095 "si_errno=%#x\n", 6096 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6097 info.psi_siginfo.si_errno); 6098 6099 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6100 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 6101 6102 SYSCALL_REQUIRE( 6103 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6104 6105 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 6106 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 6107 6108 lid = state.pe_lwp; 6109 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 6110 6111 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 6112 6113 DPRINTF("Before resuming the child process where it left off " 6114 "and without signal to be sent\n"); 6115 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6116 } 6117 6118 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 6119 DPRINTF("Before calling %s() for the child - expected stopped " 6120 "SIGTRAP\n", TWAIT_FNAME); 6121 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6122 child); 6123 6124 validate_status_stopped(status, SIGTRAP); 6125 6126 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6127 "child\n"); 6128 SYSCALL_REQUIRE( 6129 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6130 6131 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6132 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 6133 "si_errno=%#x\n", 6134 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6135 info.psi_siginfo.si_errno); 6136 6137 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6138 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 6139 6140 SYSCALL_REQUIRE( 6141 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6142 6143 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 6144 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 6145 6146 lid = state.pe_lwp; 6147 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 6148 6149 if (trace_create) { 6150 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 6151 ATF_REQUIRE_EQ(*count, 1); 6152 *count = 0; 6153 } 6154 6155 DPRINTF("Before resuming the child process where it left off " 6156 "and without signal to be sent\n"); 6157 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6158 } 6159 6160 kill(child, SIGKILL); 6161 6162 DPRINTF("Before calling %s() for the child - expected exited\n", 6163 TWAIT_FNAME); 6164 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6165 6166 validate_status_signaled(status, SIGKILL, 0); 6167 6168 DPRINTF("Before calling %s() for the child - expected no process\n", 6169 TWAIT_FNAME); 6170 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6171} 6172 6173#define TRACE_THREADS(test, trace_create, trace_exit, mask) \ 6174ATF_TC(test); \ 6175ATF_TC_HEAD(test, tc) \ 6176{ \ 6177 atf_tc_set_md_var(tc, "descr", \ 6178 "Verify spawning threads with%s tracing LWP create and" \ 6179 "with%s tracing LWP exit", trace_create ? "" : "out", \ 6180 trace_exit ? "" : "out"); \ 6181} \ 6182 \ 6183ATF_TC_BODY(test, tc) \ 6184{ \ 6185 \ 6186 trace_threads(trace_create, trace_exit, mask); \ 6187} 6188 6189TRACE_THREADS(trace_thread_nolwpevents, false, false, false) 6190TRACE_THREADS(trace_thread_lwpexit, false, true, false) 6191TRACE_THREADS(trace_thread_lwpcreate, true, false, false) 6192TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false) 6193 6194TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true) 6195TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true) 6196TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true) 6197 6198/// ---------------------------------------------------------------------------- 6199 6200ATF_TC(signal_mask_unrelated); 6201ATF_TC_HEAD(signal_mask_unrelated, tc) 6202{ 6203 atf_tc_set_md_var(tc, "descr", 6204 "Verify that masking single unrelated signal does not stop tracer " 6205 "from catching other signals"); 6206} 6207 6208ATF_TC_BODY(signal_mask_unrelated, tc) 6209{ 6210 const int exitval = 5; 6211 const int sigval = SIGSTOP; 6212 const int sigmasked = SIGTRAP; 6213 const int signotmasked = SIGINT; 6214 pid_t child, wpid; 6215#if defined(TWAIT_HAVE_STATUS) 6216 int status; 6217#endif 6218 sigset_t intmask; 6219 6220 DPRINTF("Before forking process PID=%d\n", getpid()); 6221 SYSCALL_REQUIRE((child = fork()) != -1); 6222 if (child == 0) { 6223 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6224 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6225 6226 sigemptyset(&intmask); 6227 sigaddset(&intmask, sigmasked); 6228 sigprocmask(SIG_BLOCK, &intmask, NULL); 6229 6230 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6231 FORKEE_ASSERT(raise(sigval) == 0); 6232 6233 DPRINTF("Before raising %s from child\n", 6234 strsignal(signotmasked)); 6235 FORKEE_ASSERT(raise(signotmasked) == 0); 6236 6237 DPRINTF("Before exiting of the child process\n"); 6238 _exit(exitval); 6239 } 6240 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6241 6242 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6243 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6244 6245 validate_status_stopped(status, sigval); 6246 6247 DPRINTF("Before resuming the child process where it left off and " 6248 "without signal to be sent\n"); 6249 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6250 6251 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6252 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6253 6254 validate_status_stopped(status, signotmasked); 6255 6256 DPRINTF("Before resuming the child process where it left off and " 6257 "without signal to be sent\n"); 6258 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6259 6260 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6262 6263 validate_status_exited(status, exitval); 6264 6265 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6266 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6267} 6268 6269/// ---------------------------------------------------------------------------- 6270 6271#if defined(TWAIT_HAVE_PID) 6272static void 6273fork2_body(const char *fn, bool masked, bool ignored) 6274{ 6275 const int exitval = 5; 6276 const int exitval2 = 0; /* Match exit status from /bin/echo */ 6277 const int sigval = SIGSTOP; 6278 pid_t child, child2 = 0, wpid; 6279#if defined(TWAIT_HAVE_STATUS) 6280 int status; 6281#endif 6282 ptrace_state_t state; 6283 const int slen = sizeof(state); 6284 ptrace_event_t event; 6285 const int elen = sizeof(event); 6286 struct sigaction sa; 6287 struct ptrace_siginfo info; 6288 sigset_t intmask; 6289 struct kinfo_proc2 kp; 6290 size_t len = sizeof(kp); 6291 6292 int name[6]; 6293 const size_t namelen = __arraycount(name); 6294 ki_sigset_t kp_sigmask; 6295 ki_sigset_t kp_sigignore; 6296 6297 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 6298 6299 DPRINTF("Before forking process PID=%d\n", getpid()); 6300 SYSCALL_REQUIRE((child = fork()) != -1); 6301 if (child == 0) { 6302 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6303 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6304 6305 if (masked) { 6306 sigemptyset(&intmask); 6307 sigaddset(&intmask, SIGTRAP); 6308 sigprocmask(SIG_BLOCK, &intmask, NULL); 6309 } 6310 6311 if (ignored) { 6312 memset(&sa, 0, sizeof(sa)); 6313 sa.sa_handler = SIG_IGN; 6314 sigemptyset(&sa.sa_mask); 6315 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 6316 } 6317 6318 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6319 FORKEE_ASSERT(raise(sigval) == 0); 6320 6321 if (strcmp(fn, "spawn") == 0) { 6322 FORKEE_ASSERT_EQ(posix_spawn(&child2, 6323 arg[0], NULL, NULL, arg, NULL), 0); 6324 } else { 6325 if (strcmp(fn, "fork") == 0) { 6326 FORKEE_ASSERT((child2 = fork()) != -1); 6327 } else { 6328 FORKEE_ASSERT((child2 = vfork()) != -1); 6329 } 6330 if (child2 == 0) 6331 _exit(exitval2); 6332 } 6333 6334 FORKEE_REQUIRE_SUCCESS 6335 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6336 6337 forkee_status_exited(status, exitval2); 6338 6339 DPRINTF("Before exiting of the child process\n"); 6340 _exit(exitval); 6341 } 6342 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6343 6344 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6345 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6346 6347 validate_status_stopped(status, sigval); 6348 6349 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6350 SYSCALL_REQUIRE( 6351 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6352 6353 DPRINTF("Before checking siginfo_t\n"); 6354 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6355 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6356 6357 name[0] = CTL_KERN, 6358 name[1] = KERN_PROC2, 6359 name[2] = KERN_PROC_PID; 6360 name[3] = child; 6361 name[4] = sizeof(kp); 6362 name[5] = 1; 6363 6364 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6365 6366 if (masked) 6367 kp_sigmask = kp.p_sigmask; 6368 6369 if (ignored) 6370 kp_sigignore = kp.p_sigignore; 6371 6372 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 6373 strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "", 6374 strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "", 6375 strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "", 6376 strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child); 6377 event.pe_set_event = 0; 6378 if (strcmp(fn, "spawn") == 0) 6379 event.pe_set_event |= PTRACE_POSIX_SPAWN; 6380 if (strcmp(fn, "fork") == 0) 6381 event.pe_set_event |= PTRACE_FORK; 6382 if (strcmp(fn, "vfork") == 0) 6383 event.pe_set_event |= PTRACE_VFORK; 6384 if (strcmp(fn, "vforkdone") == 0) 6385 event.pe_set_event |= PTRACE_VFORK_DONE; 6386 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6387 6388 DPRINTF("Before resuming the child process where it left off and " 6389 "without signal to be sent\n"); 6390 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6391 6392 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6393 strcmp(fn, "vfork") == 0) { 6394 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6395 child); 6396 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6397 child); 6398 6399 validate_status_stopped(status, SIGTRAP); 6400 6401 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6402 6403 if (masked) { 6404 DPRINTF("kp_sigmask=" 6405 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6406 PRIx32 "\n", 6407 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6408 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6409 6410 DPRINTF("kp.p_sigmask=" 6411 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6412 PRIx32 "\n", 6413 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6414 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6415 6416 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6417 sizeof(kp_sigmask))); 6418 } 6419 6420 if (ignored) { 6421 DPRINTF("kp_sigignore=" 6422 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6423 PRIx32 "\n", 6424 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6425 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6426 6427 DPRINTF("kp.p_sigignore=" 6428 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6429 PRIx32 "\n", 6430 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6431 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6432 6433 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6434 sizeof(kp_sigignore))); 6435 } 6436 6437 SYSCALL_REQUIRE( 6438 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6439 if (strcmp(fn, "spawn") == 0) { 6440 ATF_REQUIRE_EQ( 6441 state.pe_report_event & PTRACE_POSIX_SPAWN, 6442 PTRACE_POSIX_SPAWN); 6443 } 6444 if (strcmp(fn, "fork") == 0) { 6445 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6446 PTRACE_FORK); 6447 } 6448 if (strcmp(fn, "vfork") == 0) { 6449 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6450 PTRACE_VFORK); 6451 } 6452 6453 child2 = state.pe_other_pid; 6454 DPRINTF("Reported ptrace event with forkee %d\n", child2); 6455 6456 DPRINTF("Before calling %s() for the forkee %d of the child " 6457 "%d\n", TWAIT_FNAME, child2, child); 6458 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 6459 child2); 6460 6461 validate_status_stopped(status, SIGTRAP); 6462 6463 name[3] = child2; 6464 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6465 6466 if (masked) { 6467 DPRINTF("kp_sigmask=" 6468 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6469 PRIx32 "\n", 6470 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6471 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6472 6473 DPRINTF("kp.p_sigmask=" 6474 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6475 PRIx32 "\n", 6476 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6477 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6478 6479 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6480 sizeof(kp_sigmask))); 6481 } 6482 6483 if (ignored) { 6484 DPRINTF("kp_sigignore=" 6485 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6486 PRIx32 "\n", 6487 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6488 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6489 6490 DPRINTF("kp.p_sigignore=" 6491 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6492 PRIx32 "\n", 6493 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6494 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6495 6496 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6497 sizeof(kp_sigignore))); 6498 } 6499 6500 SYSCALL_REQUIRE( 6501 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 6502 if (strcmp(fn, "spawn") == 0) { 6503 ATF_REQUIRE_EQ( 6504 state.pe_report_event & PTRACE_POSIX_SPAWN, 6505 PTRACE_POSIX_SPAWN); 6506 } 6507 if (strcmp(fn, "fork") == 0) { 6508 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6509 PTRACE_FORK); 6510 } 6511 if (strcmp(fn, "vfork") == 0) { 6512 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6513 PTRACE_VFORK); 6514 } 6515 6516 ATF_REQUIRE_EQ(state.pe_other_pid, child); 6517 6518 DPRINTF("Before resuming the forkee process where it left off " 6519 "and without signal to be sent\n"); 6520 SYSCALL_REQUIRE( 6521 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6522 6523 DPRINTF("Before resuming the child process where it left off " 6524 "and without signal to be sent\n"); 6525 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6526 } 6527 6528 if (strcmp(fn, "vforkdone") == 0) { 6529 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6530 child); 6531 TWAIT_REQUIRE_SUCCESS( 6532 wpid = TWAIT_GENERIC(child, &status, 0), child); 6533 6534 validate_status_stopped(status, SIGTRAP); 6535 6536 name[3] = child; 6537 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6538 6539 /* 6540 * SIGCHLD is now pending in the signal queue and 6541 * the kernel presents it to userland as a masked signal. 6542 */ 6543 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 6544 6545 if (masked) { 6546 DPRINTF("kp_sigmask=" 6547 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6548 PRIx32 "\n", 6549 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6550 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6551 6552 DPRINTF("kp.p_sigmask=" 6553 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6554 PRIx32 "\n", 6555 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6556 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6557 6558 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6559 sizeof(kp_sigmask))); 6560 } 6561 6562 if (ignored) { 6563 DPRINTF("kp_sigignore=" 6564 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6565 PRIx32 "\n", 6566 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6567 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6568 6569 DPRINTF("kp.p_sigignore=" 6570 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6571 PRIx32 "\n", 6572 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6573 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6574 6575 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6576 sizeof(kp_sigignore))); 6577 } 6578 6579 SYSCALL_REQUIRE( 6580 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6581 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6582 6583 child2 = state.pe_other_pid; 6584 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6585 child2); 6586 6587 DPRINTF("Before resuming the child process where it left off " 6588 "and without signal to be sent\n"); 6589 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6590 } 6591 6592 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6593 strcmp(fn, "vfork") == 0) { 6594 DPRINTF("Before calling %s() for the forkee - expected exited" 6595 "\n", TWAIT_FNAME); 6596 TWAIT_REQUIRE_SUCCESS( 6597 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6598 6599 validate_status_exited(status, exitval2); 6600 6601 DPRINTF("Before calling %s() for the forkee - expected no " 6602 "process\n", TWAIT_FNAME); 6603 TWAIT_REQUIRE_FAILURE(ECHILD, 6604 wpid = TWAIT_GENERIC(child2, &status, 0)); 6605 } 6606 6607 DPRINTF("Before calling %s() for the child - expected stopped " 6608 "SIGCHLD\n", TWAIT_FNAME); 6609 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6610 6611 validate_status_stopped(status, SIGCHLD); 6612 6613 DPRINTF("Before resuming the child process where it left off and " 6614 "without signal to be sent\n"); 6615 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6616 6617 DPRINTF("Before calling %s() for the child - expected exited\n", 6618 TWAIT_FNAME); 6619 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6620 6621 validate_status_exited(status, exitval); 6622 6623 DPRINTF("Before calling %s() for the child - expected no process\n", 6624 TWAIT_FNAME); 6625 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6626} 6627 6628#define FORK2_TEST(name,fn,masked,ignored) \ 6629ATF_TC(name); \ 6630ATF_TC_HEAD(name, tc) \ 6631{ \ 6632 atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught " \ 6633 "regardless of signal %s%s", \ 6634 masked ? "masked" : "", ignored ? "ignored" : ""); \ 6635} \ 6636 \ 6637ATF_TC_BODY(name, tc) \ 6638{ \ 6639 \ 6640 fork2_body(fn, masked, ignored); \ 6641} 6642 6643FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false) 6644FORK2_TEST(posix_spawn_singalignored, "spawn", false, true) 6645FORK2_TEST(fork_singalmasked, "fork", true, false) 6646FORK2_TEST(fork_singalignored, "fork", false, true) 6647FORK2_TEST(vfork_singalmasked, "vfork", true, false) 6648FORK2_TEST(vfork_singalignored, "vfork", false, true) 6649FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false) 6650FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true) 6651#endif 6652 6653/// ---------------------------------------------------------------------------- 6654 6655static void * 6656thread_and_exec_thread_cb(void *arg __unused) 6657{ 6658 6659 execlp("/bin/echo", "/bin/echo", NULL); 6660 6661 abort(); 6662} 6663 6664static void 6665threads_and_exec(void) 6666{ 6667 const int sigval = SIGSTOP; 6668 pid_t child, wpid; 6669#if defined(TWAIT_HAVE_STATUS) 6670 int status; 6671#endif 6672 ptrace_state_t state; 6673 const int slen = sizeof(state); 6674 ptrace_event_t event; 6675 const int elen = sizeof(event); 6676 struct ptrace_siginfo info; 6677 6678 pthread_t t; 6679 lwpid_t lid; 6680 6681 DPRINTF("Before forking process PID=%d\n", getpid()); 6682 SYSCALL_REQUIRE((child = fork()) != -1); 6683 if (child == 0) { 6684 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6685 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6686 6687 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6688 FORKEE_ASSERT(raise(sigval) == 0); 6689 6690 FORKEE_ASSERT(pthread_create(&t, NULL, 6691 thread_and_exec_thread_cb, NULL) == 0); 6692 6693 for (;;) 6694 continue; 6695 6696 FORKEE_ASSERT(0 && "Not reached"); 6697 } 6698 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6699 6700 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6701 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6702 6703 validate_status_stopped(status, sigval); 6704 6705 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6706 SYSCALL_REQUIRE( 6707 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6708 6709 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6710 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6711 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6712 info.psi_siginfo.si_errno); 6713 6714 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6715 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6716 6717 DPRINTF("Set LWP event mask for the child %d\n", child); 6718 memset(&event, 0, sizeof(event)); 6719 event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; 6720 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6721 6722 DPRINTF("Before resuming the child process where it left off and " 6723 "without signal to be sent\n"); 6724 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6725 6726 DPRINTF("Before calling %s() for the child - expected stopped " 6727 "SIGTRAP\n", TWAIT_FNAME); 6728 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6729 child); 6730 6731 validate_status_stopped(status, SIGTRAP); 6732 6733 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6734 "child\n"); 6735 SYSCALL_REQUIRE( 6736 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6737 6738 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6739 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 6740 "si_errno=%#x\n", 6741 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6742 info.psi_siginfo.si_errno); 6743 6744 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6745 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 6746 6747 SYSCALL_REQUIRE( 6748 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6749 6750 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 6751 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 6752 6753 lid = state.pe_lwp; 6754 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 6755 6756 DPRINTF("Before resuming the child process where it left off " 6757 "and without signal to be sent\n"); 6758 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6759 6760 DPRINTF("Before calling %s() for the child - expected stopped " 6761 "SIGTRAP\n", TWAIT_FNAME); 6762 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6763 child); 6764 6765 validate_status_stopped(status, SIGTRAP); 6766 6767 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6768 "child\n"); 6769 SYSCALL_REQUIRE( 6770 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6771 6772 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6773 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 6774 "si_errno=%#x\n", 6775 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6776 info.psi_siginfo.si_errno); 6777 6778 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6779 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 6780 6781 SYSCALL_REQUIRE( 6782 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6783 6784 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 6785 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 6786 6787 lid = state.pe_lwp; 6788 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 6789 6790 DPRINTF("Before resuming the child process where it left off " 6791 "and without signal to be sent\n"); 6792 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6793 6794 DPRINTF("Before calling %s() for the child - expected stopped " 6795 "SIGTRAP\n", TWAIT_FNAME); 6796 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6797 child); 6798 6799 validate_status_stopped(status, SIGTRAP); 6800 6801 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 6802 "child\n"); 6803 SYSCALL_REQUIRE( 6804 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6805 6806 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6807 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 6808 "si_errno=%#x\n", 6809 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6810 info.psi_siginfo.si_errno); 6811 6812 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6813 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 6814 6815 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 6816 6817 DPRINTF("Before calling %s() for the child - expected exited\n", 6818 TWAIT_FNAME); 6819 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6820 6821 validate_status_signaled(status, SIGKILL, 0); 6822 6823 DPRINTF("Before calling %s() for the child - expected no process\n", 6824 TWAIT_FNAME); 6825 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6826} 6827 6828ATF_TC(threads_and_exec); 6829ATF_TC_HEAD(threads_and_exec, tc) 6830{ 6831 atf_tc_set_md_var(tc, "descr", 6832 "Verify that multithreaded application on exec() will report " 6833 "LWP_EXIT events"); 6834} 6835 6836ATF_TC_BODY(threads_and_exec, tc) 6837{ 6838 6839 threads_and_exec(); 6840} 6841 6842/// ---------------------------------------------------------------------------- 6843 6844ATF_TC(suspend_no_deadlock); 6845ATF_TC_HEAD(suspend_no_deadlock, tc) 6846{ 6847 atf_tc_set_md_var(tc, "descr", 6848 "Verify that the while the only thread within a process is " 6849 "suspended, the whole process cannot be unstopped"); 6850} 6851 6852ATF_TC_BODY(suspend_no_deadlock, tc) 6853{ 6854 const int exitval = 5; 6855 const int sigval = SIGSTOP; 6856 pid_t child, wpid; 6857#if defined(TWAIT_HAVE_STATUS) 6858 int status; 6859#endif 6860 struct ptrace_siginfo psi; 6861 6862 DPRINTF("Before forking process PID=%d\n", getpid()); 6863 SYSCALL_REQUIRE((child = fork()) != -1); 6864 if (child == 0) { 6865 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6866 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6867 6868 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6869 FORKEE_ASSERT(raise(sigval) == 0); 6870 6871 DPRINTF("Before exiting of the child process\n"); 6872 _exit(exitval); 6873 } 6874 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6875 6876 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6877 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6878 6879 validate_status_stopped(status, sigval); 6880 6881 DPRINTF("Before reading siginfo and lwpid_t\n"); 6882 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6883 6884 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6885 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6886 6887 DPRINTF("Before resuming the child process where it left off and " 6888 "without signal to be sent\n"); 6889 ATF_REQUIRE_ERRNO(EDEADLK, 6890 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 6891 6892 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6893 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6894 6895 DPRINTF("Before resuming the child process where it left off and " 6896 "without signal to be sent\n"); 6897 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6898 6899 DPRINTF("Before calling %s() for the child - expected exited\n", 6900 TWAIT_FNAME); 6901 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6902 6903 validate_status_exited(status, exitval); 6904 6905 DPRINTF("Before calling %s() for the child - expected no process\n", 6906 TWAIT_FNAME); 6907 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6908} 6909 6910/// ---------------------------------------------------------------------------- 6911 6912static pthread_barrier_t barrier1_resume; 6913static pthread_barrier_t barrier2_resume; 6914 6915static void * 6916resume_thread(void *arg) 6917{ 6918 6919 raise(SIGUSR1); 6920 6921 pthread_barrier_wait(&barrier1_resume); 6922 6923 /* Debugger will suspend the process here */ 6924 6925 pthread_barrier_wait(&barrier2_resume); 6926 6927 raise(SIGUSR2); 6928 6929 return infinite_thread(arg); 6930} 6931 6932ATF_TC(resume); 6933ATF_TC_HEAD(resume, tc) 6934{ 6935 atf_tc_set_md_var(tc, "descr", 6936 "Verify that a thread can be suspended by a debugger and later " 6937 "resumed by the debugger"); 6938} 6939 6940ATF_TC_BODY(resume, tc) 6941{ 6942 const int sigval = SIGSTOP; 6943 pid_t child, wpid; 6944#if defined(TWAIT_HAVE_STATUS) 6945 int status; 6946#endif 6947 lwpid_t lid; 6948 struct ptrace_siginfo psi; 6949 pthread_t t; 6950 6951 DPRINTF("Before forking process PID=%d\n", getpid()); 6952 SYSCALL_REQUIRE((child = fork()) != -1); 6953 if (child == 0) { 6954 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6955 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6956 6957 pthread_barrier_init(&barrier1_resume, NULL, 2); 6958 pthread_barrier_init(&barrier2_resume, NULL, 2); 6959 6960 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6961 FORKEE_ASSERT(raise(sigval) == 0); 6962 6963 DPRINTF("Before creating new thread in child\n"); 6964 FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0); 6965 6966 pthread_barrier_wait(&barrier1_resume); 6967 6968 pthread_barrier_wait(&barrier2_resume); 6969 6970 infinite_thread(NULL); 6971 } 6972 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6973 6974 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6975 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6976 6977 validate_status_stopped(status, sigval); 6978 6979 DPRINTF("Before resuming the child process where it left off and " 6980 "without signal to be sent\n"); 6981 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6982 6983 DPRINTF("Before calling %s() for the child - expected stopped " 6984 "SIGUSR1\n", TWAIT_FNAME); 6985 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6986 6987 validate_status_stopped(status, SIGUSR1); 6988 6989 DPRINTF("Before reading siginfo and lwpid_t\n"); 6990 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6991 6992 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6993 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6994 6995 lid = psi.psi_lwpid; 6996 6997 DPRINTF("Before resuming the child process where it left off and " 6998 "without signal to be sent\n"); 6999 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7000 7001 DPRINTF("Before suspending the parent for 1 second, we expect no signals\n"); 7002 SYSCALL_REQUIRE(sleep(1) == 0); 7003 7004#if defined(TWAIT_HAVE_OPTIONS) 7005 DPRINTF("Before calling %s() for the child - expected no status\n", 7006 TWAIT_FNAME); 7007 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0); 7008#endif 7009 7010 DPRINTF("Before resuming the child process where it left off and " 7011 "without signal to be sent\n"); 7012 SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1); 7013 7014 DPRINTF("Before calling %s() for the child - expected stopped " 7015 "SIGSTOP\n", TWAIT_FNAME); 7016 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7017 7018 validate_status_stopped(status, SIGSTOP); 7019 7020 DPRINTF("Before resuming LWP %d\n", lid); 7021 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1); 7022 7023 DPRINTF("Before resuming the child process where it left off and " 7024 "without signal to be sent\n"); 7025 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7026 7027 DPRINTF("Before calling %s() for the child - expected stopped " 7028 "SIGUSR2\n", TWAIT_FNAME); 7029 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7030 7031 validate_status_stopped(status, SIGUSR2); 7032 7033 DPRINTF("Before resuming the child process where it left off and " 7034 "without signal to be sent\n"); 7035 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 7036 7037 DPRINTF("Before calling %s() for the child - expected exited\n", 7038 TWAIT_FNAME); 7039 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7040 7041 validate_status_signaled(status, SIGKILL, 0); 7042 7043 DPRINTF("Before calling %s() for the child - expected no process\n", 7044 TWAIT_FNAME); 7045 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7046} 7047 7048/// ---------------------------------------------------------------------------- 7049 7050static void 7051clone_body(int flags, bool trackfork, bool trackvfork, 7052 bool trackvforkdone) 7053{ 7054 const int exitval = 5; 7055 const int exitval2 = 15; 7056 const int sigval = SIGSTOP; 7057 pid_t child, child2 = 0, wpid; 7058#if defined(TWAIT_HAVE_STATUS) 7059 int status; 7060#endif 7061 ptrace_state_t state; 7062 const int slen = sizeof(state); 7063 ptrace_event_t event; 7064 const int elen = sizeof(event); 7065 7066 const size_t stack_size = 1024 * 1024; 7067 void *stack, *stack_base; 7068 7069 stack = malloc(stack_size); 7070 ATF_REQUIRE(stack != NULL); 7071 7072#ifdef __MACHINE_STACK_GROWS_UP 7073 stack_base = stack; 7074#else 7075 stack_base = (char *)stack + stack_size; 7076#endif 7077 7078 DPRINTF("Before forking process PID=%d\n", getpid()); 7079 SYSCALL_REQUIRE((child = fork()) != -1); 7080 if (child == 0) { 7081 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7082 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7083 7084 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7085 FORKEE_ASSERT(raise(sigval) == 0); 7086 7087 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7088 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7089 7090 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7091 child2); 7092 7093 // XXX WALLSIG? 7094 FORKEE_REQUIRE_SUCCESS 7095 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7096 7097 forkee_status_exited(status, exitval2); 7098 7099 DPRINTF("Before exiting of the child process\n"); 7100 _exit(exitval); 7101 } 7102 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7103 7104 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7105 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7106 7107 validate_status_stopped(status, sigval); 7108 7109 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 7110 trackfork ? "|PTRACE_FORK" : "", 7111 trackvfork ? "|PTRACE_VFORK" : "", 7112 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 7113 event.pe_set_event = 0; 7114 if (trackfork) 7115 event.pe_set_event |= PTRACE_FORK; 7116 if (trackvfork) 7117 event.pe_set_event |= PTRACE_VFORK; 7118 if (trackvforkdone) 7119 event.pe_set_event |= PTRACE_VFORK_DONE; 7120 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7121 7122 DPRINTF("Before resuming the child process where it left off and " 7123 "without signal to be sent\n"); 7124 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7125 7126#if defined(TWAIT_HAVE_PID) 7127 if ((trackfork && !(flags & CLONE_VFORK)) || 7128 (trackvfork && (flags & CLONE_VFORK))) { 7129 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7130 child); 7131 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7132 child); 7133 7134 validate_status_stopped(status, SIGTRAP); 7135 7136 SYSCALL_REQUIRE( 7137 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7138 if (trackfork && !(flags & CLONE_VFORK)) { 7139 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7140 PTRACE_FORK); 7141 } 7142 if (trackvfork && (flags & CLONE_VFORK)) { 7143 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7144 PTRACE_VFORK); 7145 } 7146 7147 child2 = state.pe_other_pid; 7148 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7149 7150 DPRINTF("Before calling %s() for the forkee %d of the child " 7151 "%d\n", TWAIT_FNAME, child2, child); 7152 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7153 child2); 7154 7155 validate_status_stopped(status, SIGTRAP); 7156 7157 SYSCALL_REQUIRE( 7158 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7159 if (trackfork && !(flags & CLONE_VFORK)) { 7160 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7161 PTRACE_FORK); 7162 } 7163 if (trackvfork && (flags & CLONE_VFORK)) { 7164 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7165 PTRACE_VFORK); 7166 } 7167 7168 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7169 7170 DPRINTF("Before resuming the forkee process where it left off " 7171 "and without signal to be sent\n"); 7172 SYSCALL_REQUIRE( 7173 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7174 7175 DPRINTF("Before resuming the child process where it left off " 7176 "and without signal to be sent\n"); 7177 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7178 } 7179#endif 7180 7181 if (trackvforkdone && (flags & CLONE_VFORK)) { 7182 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7183 child); 7184 TWAIT_REQUIRE_SUCCESS( 7185 wpid = TWAIT_GENERIC(child, &status, 0), child); 7186 7187 validate_status_stopped(status, SIGTRAP); 7188 7189 SYSCALL_REQUIRE( 7190 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7191 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7192 7193 child2 = state.pe_other_pid; 7194 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7195 child2); 7196 7197 DPRINTF("Before resuming the child process where it left off " 7198 "and without signal to be sent\n"); 7199 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7200 } 7201 7202#if defined(TWAIT_HAVE_PID) 7203 if ((trackfork && !(flags & CLONE_VFORK)) || 7204 (trackvfork && (flags & CLONE_VFORK))) { 7205 DPRINTF("Before calling %s() for the forkee - expected exited" 7206 "\n", TWAIT_FNAME); 7207 TWAIT_REQUIRE_SUCCESS( 7208 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7209 7210 validate_status_exited(status, exitval2); 7211 7212 DPRINTF("Before calling %s() for the forkee - expected no " 7213 "process\n", TWAIT_FNAME); 7214 TWAIT_REQUIRE_FAILURE(ECHILD, 7215 wpid = TWAIT_GENERIC(child2, &status, 0)); 7216 } 7217#endif 7218 7219 DPRINTF("Before calling %s() for the child - expected stopped " 7220 "SIGCHLD\n", TWAIT_FNAME); 7221 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7222 7223 validate_status_stopped(status, SIGCHLD); 7224 7225 DPRINTF("Before resuming the child process where it left off and " 7226 "without signal to be sent\n"); 7227 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7228 7229 DPRINTF("Before calling %s() for the child - expected exited\n", 7230 TWAIT_FNAME); 7231 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7232 7233 validate_status_exited(status, exitval); 7234 7235 DPRINTF("Before calling %s() for the child - expected no process\n", 7236 TWAIT_FNAME); 7237 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7238} 7239 7240#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \ 7241ATF_TC(name); \ 7242ATF_TC_HEAD(name, tc) \ 7243{ \ 7244 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \ 7245 "called with 0%s%s%s in EVENT_MASK", \ 7246 #flags, \ 7247 tfork ? "|PTRACE_FORK" : "", \ 7248 tvfork ? "|PTRACE_VFORK" : "", \ 7249 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 7250} \ 7251 \ 7252ATF_TC_BODY(name, tc) \ 7253{ \ 7254 \ 7255 clone_body(flags, tfork, tvfork, tvforkdone); \ 7256} 7257 7258CLONE_TEST(clone1, 0, false, false, false) 7259#if defined(TWAIT_HAVE_PID) 7260CLONE_TEST(clone2, 0, true, false, false) 7261CLONE_TEST(clone3, 0, false, true, false) 7262CLONE_TEST(clone4, 0, true, true, false) 7263#endif 7264CLONE_TEST(clone5, 0, false, false, true) 7265#if defined(TWAIT_HAVE_PID) 7266CLONE_TEST(clone6, 0, true, false, true) 7267CLONE_TEST(clone7, 0, false, true, true) 7268CLONE_TEST(clone8, 0, true, true, true) 7269#endif 7270 7271CLONE_TEST(clone_vm1, CLONE_VM, false, false, false) 7272#if defined(TWAIT_HAVE_PID) 7273CLONE_TEST(clone_vm2, CLONE_VM, true, false, false) 7274CLONE_TEST(clone_vm3, CLONE_VM, false, true, false) 7275CLONE_TEST(clone_vm4, CLONE_VM, true, true, false) 7276#endif 7277CLONE_TEST(clone_vm5, CLONE_VM, false, false, true) 7278#if defined(TWAIT_HAVE_PID) 7279CLONE_TEST(clone_vm6, CLONE_VM, true, false, true) 7280CLONE_TEST(clone_vm7, CLONE_VM, false, true, true) 7281CLONE_TEST(clone_vm8, CLONE_VM, true, true, true) 7282#endif 7283 7284CLONE_TEST(clone_fs1, CLONE_FS, false, false, false) 7285#if defined(TWAIT_HAVE_PID) 7286CLONE_TEST(clone_fs2, CLONE_FS, true, false, false) 7287CLONE_TEST(clone_fs3, CLONE_FS, false, true, false) 7288CLONE_TEST(clone_fs4, CLONE_FS, true, true, false) 7289#endif 7290CLONE_TEST(clone_fs5, CLONE_FS, false, false, true) 7291#if defined(TWAIT_HAVE_PID) 7292CLONE_TEST(clone_fs6, CLONE_FS, true, false, true) 7293CLONE_TEST(clone_fs7, CLONE_FS, false, true, true) 7294CLONE_TEST(clone_fs8, CLONE_FS, true, true, true) 7295#endif 7296 7297CLONE_TEST(clone_files1, CLONE_FILES, false, false, false) 7298#if defined(TWAIT_HAVE_PID) 7299CLONE_TEST(clone_files2, CLONE_FILES, true, false, false) 7300CLONE_TEST(clone_files3, CLONE_FILES, false, true, false) 7301CLONE_TEST(clone_files4, CLONE_FILES, true, true, false) 7302#endif 7303CLONE_TEST(clone_files5, CLONE_FILES, false, false, true) 7304#if defined(TWAIT_HAVE_PID) 7305CLONE_TEST(clone_files6, CLONE_FILES, true, false, true) 7306CLONE_TEST(clone_files7, CLONE_FILES, false, true, true) 7307CLONE_TEST(clone_files8, CLONE_FILES, true, true, true) 7308#endif 7309 7310//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false) 7311#if defined(TWAIT_HAVE_PID) 7312//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false) 7313//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false) 7314//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false) 7315#endif 7316//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true) 7317#if defined(TWAIT_HAVE_PID) 7318//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true) 7319//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true) 7320//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true) 7321#endif 7322 7323CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false) 7324#if defined(TWAIT_HAVE_PID) 7325CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false) 7326CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false) 7327CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false) 7328#endif 7329CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true) 7330#if defined(TWAIT_HAVE_PID) 7331CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true) 7332CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true) 7333CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true) 7334#endif 7335 7336/// ---------------------------------------------------------------------------- 7337 7338#if defined(TWAIT_HAVE_PID) 7339static void 7340clone_body2(int flags, bool masked, bool ignored) 7341{ 7342 const int exitval = 5; 7343 const int exitval2 = 15; 7344 const int sigval = SIGSTOP; 7345 pid_t child, child2 = 0, wpid; 7346#if defined(TWAIT_HAVE_STATUS) 7347 int status; 7348#endif 7349 ptrace_state_t state; 7350 const int slen = sizeof(state); 7351 ptrace_event_t event; 7352 const int elen = sizeof(event); 7353 struct sigaction sa; 7354 struct ptrace_siginfo info; 7355 sigset_t intmask; 7356 struct kinfo_proc2 kp; 7357 size_t len = sizeof(kp); 7358 7359 int name[6]; 7360 const size_t namelen = __arraycount(name); 7361 ki_sigset_t kp_sigmask; 7362 ki_sigset_t kp_sigignore; 7363 7364 const size_t stack_size = 1024 * 1024; 7365 void *stack, *stack_base; 7366 7367 stack = malloc(stack_size); 7368 ATF_REQUIRE(stack != NULL); 7369 7370#ifdef __MACHINE_STACK_GROWS_UP 7371 stack_base = stack; 7372#else 7373 stack_base = (char *)stack + stack_size; 7374#endif 7375 7376 SYSCALL_REQUIRE((child = fork()) != -1); 7377 if (child == 0) { 7378 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7379 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7380 7381 if (masked) { 7382 sigemptyset(&intmask); 7383 sigaddset(&intmask, SIGTRAP); 7384 sigprocmask(SIG_BLOCK, &intmask, NULL); 7385 } 7386 7387 if (ignored) { 7388 memset(&sa, 0, sizeof(sa)); 7389 sa.sa_handler = SIG_IGN; 7390 sigemptyset(&sa.sa_mask); 7391 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 7392 } 7393 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7394 FORKEE_ASSERT(raise(sigval) == 0); 7395 7396 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7397 flags); 7398 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7399 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7400 7401 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7402 child2); 7403 7404 // XXX WALLSIG? 7405 FORKEE_REQUIRE_SUCCESS 7406 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7407 7408 forkee_status_exited(status, exitval2); 7409 7410 DPRINTF("Before exiting of the child process\n"); 7411 _exit(exitval); 7412 } 7413 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7414 7415 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7416 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7417 7418 validate_status_stopped(status, sigval); 7419 7420 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7421 SYSCALL_REQUIRE( 7422 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7423 7424 DPRINTF("Before checking siginfo_t\n"); 7425 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7426 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7427 7428 name[0] = CTL_KERN, 7429 name[1] = KERN_PROC2, 7430 name[2] = KERN_PROC_PID; 7431 name[3] = child; 7432 name[4] = sizeof(kp); 7433 name[5] = 1; 7434 7435 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7436 7437 if (masked) 7438 kp_sigmask = kp.p_sigmask; 7439 7440 if (ignored) 7441 kp_sigignore = kp.p_sigignore; 7442 7443 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in " 7444 "EVENT_MASK for the child %d\n", child); 7445 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; 7446 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7447 7448 DPRINTF("Before resuming the child process where it left off and " 7449 "without signal to be sent\n"); 7450 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7451 7452 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7453 child); 7454 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7455 child); 7456 7457 validate_status_stopped(status, SIGTRAP); 7458 7459 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7460 7461 if (masked) { 7462 DPRINTF("kp_sigmask=" 7463 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7464 PRIx32 "\n", 7465 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7466 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7467 7468 DPRINTF("kp.p_sigmask=" 7469 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7470 PRIx32 "\n", 7471 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7472 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7473 7474 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7475 sizeof(kp_sigmask))); 7476 } 7477 7478 if (ignored) { 7479 DPRINTF("kp_sigignore=" 7480 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7481 PRIx32 "\n", 7482 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7483 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7484 7485 DPRINTF("kp.p_sigignore=" 7486 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7487 PRIx32 "\n", 7488 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7489 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7490 7491 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7492 sizeof(kp_sigignore))); 7493 } 7494 7495 SYSCALL_REQUIRE( 7496 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7497 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event, 7498 child2); 7499 if (!(flags & CLONE_VFORK)) { 7500 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7501 PTRACE_FORK); 7502 } else { 7503 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7504 PTRACE_VFORK); 7505 } 7506 7507 child2 = state.pe_other_pid; 7508 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7509 7510 DPRINTF("Before calling %s() for the forkee %d of the child " 7511 "%d\n", TWAIT_FNAME, child2, child); 7512 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7513 child2); 7514 7515 validate_status_stopped(status, SIGTRAP); 7516 7517 name[3] = child2; 7518 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7519 7520 if (masked) { 7521 DPRINTF("kp_sigmask=" 7522 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7523 PRIx32 "\n", 7524 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7525 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7526 7527 DPRINTF("kp.p_sigmask=" 7528 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7529 PRIx32 "\n", 7530 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7531 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7532 7533 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7534 sizeof(kp_sigmask))); 7535 } 7536 7537 if (ignored) { 7538 DPRINTF("kp_sigignore=" 7539 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7540 PRIx32 "\n", 7541 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7542 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7543 7544 DPRINTF("kp.p_sigignore=" 7545 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7546 PRIx32 "\n", 7547 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7548 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7549 7550 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7551 sizeof(kp_sigignore))); 7552 } 7553 7554 SYSCALL_REQUIRE( 7555 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7556 if (!(flags & CLONE_VFORK)) { 7557 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7558 PTRACE_FORK); 7559 } else { 7560 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7561 PTRACE_VFORK); 7562 } 7563 7564 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7565 7566 DPRINTF("Before resuming the forkee process where it left off " 7567 "and without signal to be sent\n"); 7568 SYSCALL_REQUIRE( 7569 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7570 7571 DPRINTF("Before resuming the child process where it left off " 7572 "and without signal to be sent\n"); 7573 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7574 7575 if (flags & CLONE_VFORK) { 7576 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7577 child); 7578 TWAIT_REQUIRE_SUCCESS( 7579 wpid = TWAIT_GENERIC(child, &status, 0), child); 7580 7581 validate_status_stopped(status, SIGTRAP); 7582 7583 name[3] = child; 7584 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7585 7586 /* 7587 * SIGCHLD is now pending in the signal queue and 7588 * the kernel presents it to userland as a masked signal. 7589 */ 7590 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 7591 7592 if (masked) { 7593 DPRINTF("kp_sigmask=" 7594 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7595 PRIx32 "\n", 7596 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7597 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7598 7599 DPRINTF("kp.p_sigmask=" 7600 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7601 PRIx32 "\n", 7602 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7603 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7604 7605 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7606 sizeof(kp_sigmask))); 7607 } 7608 7609 if (ignored) { 7610 DPRINTF("kp_sigignore=" 7611 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7612 PRIx32 "\n", 7613 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7614 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7615 7616 DPRINTF("kp.p_sigignore=" 7617 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7618 PRIx32 "\n", 7619 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7620 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7621 7622 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7623 sizeof(kp_sigignore))); 7624 } 7625 7626 SYSCALL_REQUIRE( 7627 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7628 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7629 7630 child2 = state.pe_other_pid; 7631 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7632 child2); 7633 7634 DPRINTF("Before resuming the child process where it left off " 7635 "and without signal to be sent\n"); 7636 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7637 } 7638 7639 DPRINTF("Before calling %s() for the forkee - expected exited" 7640 "\n", TWAIT_FNAME); 7641 TWAIT_REQUIRE_SUCCESS( 7642 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7643 7644 validate_status_exited(status, exitval2); 7645 7646 DPRINTF("Before calling %s() for the forkee - expected no " 7647 "process\n", TWAIT_FNAME); 7648 TWAIT_REQUIRE_FAILURE(ECHILD, 7649 wpid = TWAIT_GENERIC(child2, &status, 0)); 7650 7651 DPRINTF("Before calling %s() for the child - expected stopped " 7652 "SIGCHLD\n", TWAIT_FNAME); 7653 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7654 7655 validate_status_stopped(status, SIGCHLD); 7656 7657 DPRINTF("Before resuming the child process where it left off and " 7658 "without signal to be sent\n"); 7659 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7660 7661 DPRINTF("Before calling %s() for the child - expected exited\n", 7662 TWAIT_FNAME); 7663 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7664 7665 validate_status_exited(status, exitval); 7666 7667 DPRINTF("Before calling %s() for the child - expected no process\n", 7668 TWAIT_FNAME); 7669 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7670} 7671 7672#define CLONE_TEST2(name,flags,masked,ignored) \ 7673ATF_TC(name); \ 7674ATF_TC_HEAD(name, tc) \ 7675{ \ 7676 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\ 7677 " regardless of signal %s%s", \ 7678 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \ 7679} \ 7680 \ 7681ATF_TC_BODY(name, tc) \ 7682{ \ 7683 \ 7684 clone_body2(flags, masked, ignored); \ 7685} 7686 7687CLONE_TEST2(clone_signalignored, 0, true, false) 7688CLONE_TEST2(clone_signalmasked, 0, false, true) 7689CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false) 7690CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true) 7691CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false) 7692CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true) 7693CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false) 7694CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true) 7695//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX 7696//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX 7697CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false) 7698CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true) 7699#endif 7700 7701/// ---------------------------------------------------------------------------- 7702 7703#if defined(TWAIT_HAVE_PID) 7704static void 7705traceme_vfork_clone_body(int flags) 7706{ 7707 const int exitval = 5; 7708 const int exitval2 = 15; 7709 pid_t child, child2 = 0, wpid; 7710#if defined(TWAIT_HAVE_STATUS) 7711 int status; 7712#endif 7713 7714 const size_t stack_size = 1024 * 1024; 7715 void *stack, *stack_base; 7716 7717 stack = malloc(stack_size); 7718 ATF_REQUIRE(stack != NULL); 7719 7720#ifdef __MACHINE_STACK_GROWS_UP 7721 stack_base = stack; 7722#else 7723 stack_base = (char *)stack + stack_size; 7724#endif 7725 7726 SYSCALL_REQUIRE((child = vfork()) != -1); 7727 if (child == 0) { 7728 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7729 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7730 7731 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7732 flags); 7733 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7734 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7735 7736 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7737 child2); 7738 7739 // XXX WALLSIG? 7740 FORKEE_REQUIRE_SUCCESS 7741 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7742 7743 forkee_status_exited(status, exitval2); 7744 7745 DPRINTF("Before exiting of the child process\n"); 7746 _exit(exitval); 7747 } 7748 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7749 7750 DPRINTF("Before calling %s() for the child - expected exited\n", 7751 TWAIT_FNAME); 7752 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7753 7754 validate_status_exited(status, exitval); 7755 7756 DPRINTF("Before calling %s() for the child - expected no process\n", 7757 TWAIT_FNAME); 7758 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7759} 7760 7761#define TRACEME_VFORK_CLONE_TEST(name,flags) \ 7762ATF_TC(name); \ 7763ATF_TC_HEAD(name, tc) \ 7764{ \ 7765 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \ 7766 "handled correctly with vfork(2)ed tracer", \ 7767 #flags); \ 7768} \ 7769 \ 7770ATF_TC_BODY(name, tc) \ 7771{ \ 7772 \ 7773 traceme_vfork_clone_body(flags); \ 7774} 7775 7776TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0) 7777TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM) 7778TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS) 7779TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES) 7780//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX 7781TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK) 7782#endif 7783 7784/// ---------------------------------------------------------------------------- 7785 7786static void 7787user_va0_disable(int operation) 7788{ 7789 pid_t child, wpid; 7790#if defined(TWAIT_HAVE_STATUS) 7791 int status; 7792#endif 7793 const int sigval = SIGSTOP; 7794 int rv; 7795 7796 struct ptrace_siginfo info; 7797 7798 if (get_user_va0_disable() == 0) 7799 atf_tc_skip("vm.user_va0_disable is set to 0"); 7800 7801 memset(&info, 0, sizeof(info)); 7802 7803 DPRINTF("Before forking process PID=%d\n", getpid()); 7804 SYSCALL_REQUIRE((child = fork()) != -1); 7805 if (child == 0) { 7806 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7807 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7808 7809 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7810 FORKEE_ASSERT(raise(sigval) == 0); 7811 7812 /* NOTREACHED */ 7813 FORKEE_ASSERTX(0 && "This shall not be reached"); 7814 __unreachable(); 7815 } 7816 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7817 7818 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7819 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7820 7821 validate_status_stopped(status, sigval); 7822 7823 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7824 "child\n"); 7825 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 7826 sizeof(info)) != -1); 7827 7828 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7829 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7830 "si_errno=%#x\n", 7831 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7832 info.psi_siginfo.si_errno); 7833 7834 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7835 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7836 7837 DPRINTF("Before resuming the child process in PC=0x0 " 7838 "and without signal to be sent\n"); 7839 errno = 0; 7840 rv = ptrace(operation, child, (void *)0, 0); 7841 ATF_REQUIRE_EQ(errno, EINVAL); 7842 ATF_REQUIRE_EQ(rv, -1); 7843 7844 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 7845 7846 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7847 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7848 validate_status_signaled(status, SIGKILL, 0); 7849 7850 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7851 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7852} 7853 7854#define USER_VA0_DISABLE(test, operation) \ 7855ATF_TC(test); \ 7856ATF_TC_HEAD(test, tc) \ 7857{ \ 7858 atf_tc_set_md_var(tc, "descr", \ 7859 "Verify behavior of " #operation " with PC set to 0x0"); \ 7860} \ 7861 \ 7862ATF_TC_BODY(test, tc) \ 7863{ \ 7864 \ 7865 user_va0_disable(operation); \ 7866} 7867 7868USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 7869USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 7870USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 7871 7872/// ---------------------------------------------------------------------------- 7873 7874/* 7875 * Parse the core file and find the requested note. If the reading or parsing 7876 * fails, the test is failed. If the note is found, it is read onto buf, up to 7877 * buf_len. The actual length of the note is returned (which can be greater 7878 * than buf_len, indicating that it has been truncated). If the note is not 7879 * found, -1 is returned. 7880 * 7881 * If the note_name ends in '*', then we find the first note that matches 7882 * the note_name prefix up to the '*' character, e.g.: 7883 * 7884 * NetBSD-CORE@* 7885 * 7886 * finds the first note whose name prefix matches "NetBSD-CORE@". 7887 */ 7888static ssize_t core_find_note(const char *core_path, 7889 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 7890{ 7891 int core_fd; 7892 Elf *core_elf; 7893 size_t core_numhdr, i; 7894 ssize_t ret = -1; 7895 size_t name_len = strlen(note_name); 7896 bool prefix_match = false; 7897 7898 if (note_name[name_len - 1] == '*') { 7899 prefix_match = true; 7900 name_len--; 7901 } else { 7902 /* note: we assume note name will be null-terminated */ 7903 name_len++; 7904 } 7905 7906 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 7907 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 7908 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 7909 7910 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 7911 for (i = 0; i < core_numhdr && ret == -1; i++) { 7912 GElf_Phdr core_hdr; 7913 size_t offset; 7914 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 7915 if (core_hdr.p_type != PT_NOTE) 7916 continue; 7917 7918 for (offset = core_hdr.p_offset; 7919 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 7920 Elf64_Nhdr note_hdr; 7921 char name_buf[64]; 7922 7923 switch (gelf_getclass(core_elf)) { 7924 case ELFCLASS64: 7925 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 7926 sizeof(note_hdr), offset) 7927 == sizeof(note_hdr)); 7928 offset += sizeof(note_hdr); 7929 break; 7930 case ELFCLASS32: 7931 { 7932 Elf32_Nhdr tmp_hdr; 7933 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 7934 sizeof(tmp_hdr), offset) 7935 == sizeof(tmp_hdr)); 7936 offset += sizeof(tmp_hdr); 7937 note_hdr.n_namesz = tmp_hdr.n_namesz; 7938 note_hdr.n_descsz = tmp_hdr.n_descsz; 7939 note_hdr.n_type = tmp_hdr.n_type; 7940 } 7941 break; 7942 } 7943 7944 /* indicates end of notes */ 7945 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 7946 break; 7947 if (((prefix_match && 7948 note_hdr.n_namesz > name_len) || 7949 (!prefix_match && 7950 note_hdr.n_namesz == name_len)) && 7951 note_hdr.n_namesz <= sizeof(name_buf)) { 7952 SYSCALL_REQUIRE(pread(core_fd, name_buf, 7953 note_hdr.n_namesz, offset) 7954 == (ssize_t)(size_t)note_hdr.n_namesz); 7955 7956 if (!strncmp(note_name, name_buf, name_len) && 7957 note_hdr.n_type == note_type) 7958 ret = note_hdr.n_descsz; 7959 } 7960 7961 offset += note_hdr.n_namesz; 7962 /* fix to alignment */ 7963 offset = roundup(offset, core_hdr.p_align); 7964 7965 /* if name & type matched above */ 7966 if (ret != -1) { 7967 ssize_t read_len = MIN(buf_len, 7968 note_hdr.n_descsz); 7969 SYSCALL_REQUIRE(pread(core_fd, buf, 7970 read_len, offset) == read_len); 7971 break; 7972 } 7973 7974 offset += note_hdr.n_descsz; 7975 /* fix to alignment */ 7976 offset = roundup(offset, core_hdr.p_align); 7977 } 7978 } 7979 7980 elf_end(core_elf); 7981 close(core_fd); 7982 7983 return ret; 7984} 7985 7986ATF_TC(core_dump_procinfo); 7987ATF_TC_HEAD(core_dump_procinfo, tc) 7988{ 7989 atf_tc_set_md_var(tc, "descr", 7990 "Trigger a core dump and verify its contents."); 7991} 7992 7993ATF_TC_BODY(core_dump_procinfo, tc) 7994{ 7995 const int exitval = 5; 7996 pid_t child, wpid; 7997#if defined(TWAIT_HAVE_STATUS) 7998 const int sigval = SIGTRAP; 7999 int status; 8000#endif 8001 char core_path[] = "/tmp/core.XXXXXX"; 8002 int core_fd; 8003 struct netbsd_elfcore_procinfo procinfo; 8004 8005 DPRINTF("Before forking process PID=%d\n", getpid()); 8006 SYSCALL_REQUIRE((child = fork()) != -1); 8007 if (child == 0) { 8008 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8009 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8010 8011 DPRINTF("Before triggering SIGTRAP\n"); 8012 trigger_trap(); 8013 8014 DPRINTF("Before exiting of the child process\n"); 8015 _exit(exitval); 8016 } 8017 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8018 8019 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8020 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8021 8022 validate_status_stopped(status, sigval); 8023 8024 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 8025 close(core_fd); 8026 8027 DPRINTF("Call DUMPCORE for the child process\n"); 8028 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 8029 != -1); 8030 8031 DPRINTF("Read core file\n"); 8032 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 8033 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 8034 sizeof(procinfo)); 8035 8036 ATF_CHECK_EQ(procinfo.cpi_version, 1); 8037 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 8038 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 8039 ATF_CHECK_EQ(procinfo.cpi_pid, child); 8040 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 8041 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 8042 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 8043 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 8044 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 8045 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 8046 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 8047 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 8048 ATF_CHECK(procinfo.cpi_siglwp > 0); 8049 8050 unlink(core_path); 8051 8052 DPRINTF("Before resuming the child process where it left off and " 8053 "without signal to be sent\n"); 8054 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8055 8056 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8057 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8058 8059 validate_status_exited(status, exitval); 8060 8061 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8062 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 8063} 8064 8065/// ---------------------------------------------------------------------------- 8066 8067#if defined(TWAIT_HAVE_STATUS) 8068 8069#define THREAD_CONCURRENT_BREAKPOINT_NUM 50 8070#define THREAD_CONCURRENT_SIGNALS_NUM 50 8071#define THREAD_CONCURRENT_WATCHPOINT_NUM 50 8072 8073/* List of signals to use for the test */ 8074const int thread_concurrent_signals_list[] = { 8075 SIGIO, 8076 SIGXCPU, 8077 SIGXFSZ, 8078 SIGVTALRM, 8079 SIGPROF, 8080 SIGWINCH, 8081 SIGINFO, 8082 SIGUSR1, 8083 SIGUSR2 8084}; 8085 8086enum thread_concurrent_signal_handling { 8087 /* the signal is discarded by debugger */ 8088 TCSH_DISCARD, 8089 /* the handler is set to SIG_IGN */ 8090 TCSH_SIG_IGN, 8091 /* an actual handler is used */ 8092 TCSH_HANDLER 8093}; 8094 8095static pthread_barrier_t thread_concurrent_barrier; 8096static pthread_key_t thread_concurrent_key; 8097static uint32_t thread_concurrent_watchpoint_var = 0; 8098 8099static void * 8100thread_concurrent_breakpoint_thread(void *arg) 8101{ 8102 static volatile int watchme = 1; 8103 pthread_barrier_wait(&thread_concurrent_barrier); 8104 DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self()); 8105 check_happy(watchme); 8106 return NULL; 8107} 8108 8109static void 8110thread_concurrent_sig_handler(int sig) 8111{ 8112 void *tls_val = pthread_getspecific(thread_concurrent_key); 8113 DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 8114 FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key, 8115 (void*)((uintptr_t)tls_val + 1)) == 0); 8116} 8117 8118static void * 8119thread_concurrent_signals_thread(void *arg) 8120{ 8121 int sigval = thread_concurrent_signals_list[ 8122 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 8123 enum thread_concurrent_signal_handling *signal_handle = arg; 8124 void *tls_val; 8125 8126 pthread_barrier_wait(&thread_concurrent_barrier); 8127 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 8128 _lwp_self()); 8129 pthread_kill(pthread_self(), sigval); 8130 if (*signal_handle == TCSH_HANDLER) { 8131 tls_val = pthread_getspecific(thread_concurrent_key); 8132 DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 8133 FORKEE_ASSERT(tls_val == (void*)1); 8134 } 8135 return NULL; 8136} 8137 8138static void * 8139thread_concurrent_watchpoint_thread(void *arg) 8140{ 8141 pthread_barrier_wait(&thread_concurrent_barrier); 8142 DPRINTF("Before modifying var from LWP %d\n", _lwp_self()); 8143 thread_concurrent_watchpoint_var = 1; 8144 return NULL; 8145} 8146 8147#if defined(__i386__) || defined(__x86_64__) 8148enum thread_concurrent_sigtrap_event { 8149 TCSE_UNKNOWN, 8150 TCSE_BREAKPOINT, 8151 TCSE_WATCHPOINT 8152}; 8153 8154static void 8155thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid); 8156static enum thread_concurrent_sigtrap_event 8157thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info); 8158#endif 8159 8160static void 8161thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle, 8162 int breakpoint_threads, int signal_threads, int watchpoint_threads) 8163{ 8164 const int exitval = 5; 8165 const int sigval = SIGSTOP; 8166 pid_t child, wpid; 8167 int status; 8168 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 8169 = {{0, 0}}; 8170 struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 8171 = {{0, 0}}; 8172 struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 8173 = {{0, 0}}; 8174 ptrace_event_t event; 8175 int i; 8176 8177#if defined(HAVE_DBREGS) 8178 if (!can_we_set_dbregs()) { 8179 atf_tc_skip("Either run this test as root or set sysctl(3) " 8180 "security.models.extensions.user_set_dbregs to 1"); 8181 } 8182#endif 8183 8184 atf_tc_skip("PR kern/54960"); 8185 8186 /* Protect against out-of-bounds array access. */ 8187 ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM); 8188 ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM); 8189 ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM); 8190 8191 DPRINTF("Before forking process PID=%d\n", getpid()); 8192 SYSCALL_REQUIRE((child = fork()) != -1); 8193 if (child == 0) { 8194 pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM]; 8195 pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM]; 8196 pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM]; 8197 8198 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8199 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8200 8201 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8202 FORKEE_ASSERT(raise(sigval) == 0); 8203 8204 if (signal_handle != TCSH_DISCARD) { 8205 struct sigaction sa; 8206 unsigned int j; 8207 8208 memset(&sa, 0, sizeof(sa)); 8209 if (signal_handle == TCSH_SIG_IGN) 8210 sa.sa_handler = SIG_IGN; 8211 else 8212 sa.sa_handler = thread_concurrent_sig_handler; 8213 sigemptyset(&sa.sa_mask); 8214 8215 for (j = 0; 8216 j < __arraycount(thread_concurrent_signals_list); 8217 j++) 8218 FORKEE_ASSERT(sigaction( 8219 thread_concurrent_signals_list[j], &sa, NULL) 8220 != -1); 8221 } 8222 8223 DPRINTF("Before starting threads from the child\n"); 8224 FORKEE_ASSERT(pthread_barrier_init( 8225 &thread_concurrent_barrier, NULL, 8226 breakpoint_threads + signal_threads + watchpoint_threads) 8227 == 0); 8228 FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL) 8229 == 0); 8230 8231 for (i = 0; i < signal_threads; i++) { 8232 FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL, 8233 thread_concurrent_signals_thread, 8234 &signal_handle) == 0); 8235 } 8236 for (i = 0; i < breakpoint_threads; i++) { 8237 FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL, 8238 thread_concurrent_breakpoint_thread, NULL) == 0); 8239 } 8240 for (i = 0; i < watchpoint_threads; i++) { 8241 FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL, 8242 thread_concurrent_watchpoint_thread, NULL) == 0); 8243 } 8244 8245 DPRINTF("Before joining threads from the child\n"); 8246 for (i = 0; i < watchpoint_threads; i++) { 8247 FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0); 8248 } 8249 for (i = 0; i < breakpoint_threads; i++) { 8250 FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0); 8251 } 8252 for (i = 0; i < signal_threads; i++) { 8253 FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0); 8254 } 8255 8256 FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0); 8257 FORKEE_ASSERT(pthread_barrier_destroy( 8258 &thread_concurrent_barrier) == 0); 8259 8260 DPRINTF("Before exiting of the child process\n"); 8261 _exit(exitval); 8262 } 8263 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8264 8265 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8266 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8267 8268 validate_status_stopped(status, sigval); 8269 8270 DPRINTF("Set LWP event mask for the child process\n"); 8271 memset(&event, 0, sizeof(event)); 8272 event.pe_set_event |= PTRACE_LWP_CREATE; 8273 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event)) 8274 != -1); 8275 8276 DPRINTF("Before resuming the child process where it left off\n"); 8277 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8278 8279 DPRINTF("Before entering signal collection loop\n"); 8280 while (1) { 8281 ptrace_siginfo_t info; 8282 8283 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8284 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 8285 child); 8286 if (WIFEXITED(status)) 8287 break; 8288 /* Note: we use validate_status_stopped() to get nice error 8289 * message. Signal is irrelevant since it won't be reached. 8290 */ 8291 else if (!WIFSTOPPED(status)) 8292 validate_status_stopped(status, 0); 8293 8294 DPRINTF("Before calling PT_GET_SIGINFO\n"); 8295 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 8296 sizeof(info)) != -1); 8297 8298 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 8299 info.psi_siginfo.si_signo, info.psi_lwpid, 8300 WSTOPSIG(status)); 8301 8302 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status), 8303 "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid, 8304 WSTOPSIG(status), info.psi_siginfo.si_signo); 8305 8306 if (WSTOPSIG(status) != SIGTRAP) { 8307 int expected_sig = 8308 thread_concurrent_signals_list[info.psi_lwpid % 8309 __arraycount(thread_concurrent_signals_list)]; 8310 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 8311 "lwp=%d, expected %d, got %d", info.psi_lwpid, 8312 expected_sig, WSTOPSIG(status)); 8313 8314 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 8315 } else if (info.psi_siginfo.si_code == TRAP_LWP) { 8316#if defined(__i386__) || defined(__x86_64__) 8317 thread_concurrent_lwp_setup(child, info.psi_lwpid); 8318#endif 8319 } else { 8320#if defined(__i386__) || defined(__x86_64__) 8321 switch (thread_concurrent_handle_sigtrap(child, &info)) { 8322 case TCSE_UNKNOWN: 8323 /* already reported inside the function */ 8324 break; 8325 case TCSE_BREAKPOINT: 8326 *FIND_EVENT_COUNT(bp_counts, 8327 info.psi_lwpid) += 1; 8328 break; 8329 case TCSE_WATCHPOINT: 8330 *FIND_EVENT_COUNT(wp_counts, 8331 info.psi_lwpid) += 1; 8332 break; 8333 } 8334#else 8335 ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n", 8336 info.psi_siginfo.si_code); 8337#endif 8338 } 8339 8340 DPRINTF("Before resuming the child process\n"); 8341 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 8342 signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP 8343 ? WSTOPSIG(status) : 0) != -1); 8344 } 8345 8346 for (i = 0; i < signal_threads; i++) 8347 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 8348 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 8349 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 8350 for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++) 8351 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0, 8352 "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d", 8353 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 8354 8355 for (i = 0; i < breakpoint_threads; i++) 8356 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1, 8357 "bp_counts[%d].lec_count=%d; lec_lwp=%d", 8358 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 8359 for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++) 8360 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0, 8361 "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d", 8362 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 8363 8364 for (i = 0; i < watchpoint_threads; i++) 8365 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1, 8366 "wp_counts[%d].lec_count=%d; lec_lwp=%d", 8367 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 8368 for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++) 8369 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0, 8370 "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d", 8371 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 8372 8373 validate_status_exited(status, exitval); 8374} 8375 8376#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr) \ 8377ATF_TC(test); \ 8378ATF_TC_HEAD(test, tc) \ 8379{ \ 8380 atf_tc_set_md_var(tc, "descr", descr); \ 8381} \ 8382 \ 8383ATF_TC_BODY(test, tc) \ 8384{ \ 8385 thread_concurrent_test(sig_hdl, bps, sigs, wps); \ 8386} 8387 8388THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD, 8389 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 8390 "Verify that concurrent signals issued to a single thread are reported " 8391 "correctly"); 8392THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN, 8393 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 8394 "Verify that concurrent signals issued to a single thread are reported " 8395 "correctly and passed back to SIG_IGN handler"); 8396THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER, 8397 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 8398 "Verify that concurrent signals issued to a single thread are reported " 8399 "correctly and passed back to a handler function"); 8400 8401#if defined(__i386__) || defined(__x86_64__) 8402THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD, 8403 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0, 8404 "Verify that concurrent breakpoints are reported correctly"); 8405THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD, 8406 0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 8407 "Verify that concurrent breakpoints are reported correctly"); 8408THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD, 8409 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 8410 "Verify that concurrent breakpoints and watchpoints are reported " 8411 "correctly"); 8412 8413THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD, 8414 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 8415 "Verify that concurrent breakpoints and signals are reported correctly"); 8416THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN, 8417 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 8418 "Verify that concurrent breakpoints and signals are reported correctly " 8419 "and passed back to SIG_IGN handler"); 8420THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER, 8421 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 8422 "Verify that concurrent breakpoints and signals are reported correctly " 8423 "and passed back to a handler function"); 8424 8425THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD, 8426 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 8427 "Verify that concurrent watchpoints and signals are reported correctly"); 8428THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN, 8429 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 8430 "Verify that concurrent watchpoints and signals are reported correctly " 8431 "and passed back to SIG_IGN handler"); 8432THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER, 8433 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 8434 "Verify that concurrent watchpoints and signals are reported correctly " 8435 "and passed back to a handler function"); 8436 8437THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD, 8438 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 8439 THREAD_CONCURRENT_WATCHPOINT_NUM, 8440 "Verify that concurrent breakpoints, watchpoints and signals are reported " 8441 "correctly"); 8442THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN, 8443 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 8444 THREAD_CONCURRENT_WATCHPOINT_NUM, 8445 "Verify that concurrent breakpoints, watchpoints and signals are reported " 8446 "correctly and passed back to SIG_IGN handler"); 8447THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER, 8448 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 8449 THREAD_CONCURRENT_WATCHPOINT_NUM, 8450 "Verify that concurrent breakpoints, watchpoints and signals are reported " 8451 "correctly and passed back to a handler function"); 8452#endif 8453 8454#endif /*defined(TWAIT_HAVE_STATUS)*/ 8455 8456/// ---------------------------------------------------------------------------- 8457 8458#include "t_ptrace_register_wait.h" 8459#include "t_ptrace_syscall_wait.h" 8460#include "t_ptrace_step_wait.h" 8461 8462/// ---------------------------------------------------------------------------- 8463 8464#include "t_ptrace_amd64_wait.h" 8465#include "t_ptrace_i386_wait.h" 8466#include "t_ptrace_x86_wait.h" 8467 8468/// ---------------------------------------------------------------------------- 8469 8470#else 8471ATF_TC(dummy); 8472ATF_TC_HEAD(dummy, tc) 8473{ 8474 atf_tc_set_md_var(tc, "descr", "A dummy test"); 8475} 8476 8477ATF_TC_BODY(dummy, tc) 8478{ 8479 8480 // Dummy, skipped 8481 // The ATF framework requires at least a single defined test. 8482} 8483#endif 8484 8485ATF_TP_ADD_TCS(tp) 8486{ 8487 setvbuf(stdout, NULL, _IONBF, 0); 8488 setvbuf(stderr, NULL, _IONBF, 0); 8489 8490#ifdef ENABLE_TESTS 8491 ATF_TP_ADD_TC(tp, traceme_raise1); 8492 ATF_TP_ADD_TC(tp, traceme_raise2); 8493 ATF_TP_ADD_TC(tp, traceme_raise3); 8494 ATF_TP_ADD_TC(tp, traceme_raise4); 8495 ATF_TP_ADD_TC(tp, traceme_raise5); 8496 ATF_TP_ADD_TC(tp, traceme_raise6); 8497 ATF_TP_ADD_TC(tp, traceme_raise7); 8498 ATF_TP_ADD_TC(tp, traceme_raise8); 8499 ATF_TP_ADD_TC(tp, traceme_raise9); 8500 ATF_TP_ADD_TC(tp, traceme_raise10); 8501 8502 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 8503 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 8504 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 8505 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 8506 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 8507 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 8508 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 8509 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 8510 8511 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 8512 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 8513 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 8514 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 8515 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 8516 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 8517 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 8518 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 8519 8520 ATF_TP_ADD_TC(tp, traceme_crash_trap); 8521 ATF_TP_ADD_TC(tp, traceme_crash_segv); 8522 ATF_TP_ADD_TC(tp, traceme_crash_ill); 8523 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 8524 ATF_TP_ADD_TC(tp, traceme_crash_bus); 8525 8526 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 8527 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 8528 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 8529 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 8530 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 8531 8532 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 8533 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 8534 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 8535 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 8536 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 8537 8538 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 8539 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 8540 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 8541 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 8542 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 8543 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 8544 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 8545 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 8546 8547 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 8548 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 8549 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 8550 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 8551 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 8552 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 8553 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 8554 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 8555 8556 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 8557 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 8558 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 8559 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 8560 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 8561 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 8562 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 8563 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 8564 8565 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 8566 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 8567 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 8568 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 8569 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 8570 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 8571 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 8572 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 8573 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 8574 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 8575 8576 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 8577 8578 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 8579 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 8580 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 8581 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 8582 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 8583 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 8584 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 8585 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 8586 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 8587 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 8588 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 8589 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 8590 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 8591 8592 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 8593 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 8594 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 8595 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 8596 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 8597 8598 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 8599 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 8600 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 8601 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 8602 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 8603 8604 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 8605 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 8606 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 8607 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 8608 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 8609 8610 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 8611 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 8612 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 8613 8614 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 8615 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 8616 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 8617 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 8618 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 8619 8620 ATF_TP_ADD_TC_HAVE_PID(tp, 8621 unrelated_tracer_sees_signalmasked_crash_trap); 8622 ATF_TP_ADD_TC_HAVE_PID(tp, 8623 unrelated_tracer_sees_signalmasked_crash_segv); 8624 ATF_TP_ADD_TC_HAVE_PID(tp, 8625 unrelated_tracer_sees_signalmasked_crash_ill); 8626 ATF_TP_ADD_TC_HAVE_PID(tp, 8627 unrelated_tracer_sees_signalmasked_crash_fpe); 8628 ATF_TP_ADD_TC_HAVE_PID(tp, 8629 unrelated_tracer_sees_signalmasked_crash_bus); 8630 8631 ATF_TP_ADD_TC_HAVE_PID(tp, 8632 unrelated_tracer_sees_signalignored_crash_trap); 8633 ATF_TP_ADD_TC_HAVE_PID(tp, 8634 unrelated_tracer_sees_signalignored_crash_segv); 8635 ATF_TP_ADD_TC_HAVE_PID(tp, 8636 unrelated_tracer_sees_signalignored_crash_ill); 8637 ATF_TP_ADD_TC_HAVE_PID(tp, 8638 unrelated_tracer_sees_signalignored_crash_fpe); 8639 ATF_TP_ADD_TC_HAVE_PID(tp, 8640 unrelated_tracer_sees_signalignored_crash_bus); 8641 8642 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 8643 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 8644 ATF_TP_ADD_TC_HAVE_PID(tp, 8645 unrelated_tracer_sees_terminaton_before_the_parent); 8646 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 8647 8648 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 8649 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 8650 8651 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 8652 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 8653 8654 ATF_TP_ADD_TC_HAVE_PID(tp, 8655 tracee_sees_its_original_parent_getppid); 8656 ATF_TP_ADD_TC_HAVE_PID(tp, 8657 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 8658 ATF_TP_ADD_TC_HAVE_PID(tp, 8659 tracee_sees_its_original_parent_procfs_status); 8660 8661 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 8662 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 8663 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 8664 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 8665 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 8666 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 8667 ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn); 8668 8669 ATF_TP_ADD_TC(tp, fork1); 8670 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 8671 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 8672 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 8673 ATF_TP_ADD_TC(tp, fork5); 8674 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 8675 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 8676 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 8677 ATF_TP_ADD_TC(tp, fork9); 8678 ATF_TP_ADD_TC_HAVE_PID(tp, fork10); 8679 ATF_TP_ADD_TC_HAVE_PID(tp, fork11); 8680 ATF_TP_ADD_TC_HAVE_PID(tp, fork12); 8681 ATF_TP_ADD_TC(tp, fork13); 8682 ATF_TP_ADD_TC_HAVE_PID(tp, fork14); 8683 ATF_TP_ADD_TC_HAVE_PID(tp, fork15); 8684 ATF_TP_ADD_TC_HAVE_PID(tp, fork16); 8685 8686 ATF_TP_ADD_TC(tp, vfork1); 8687 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 8688 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 8689 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 8690 ATF_TP_ADD_TC(tp, vfork5); 8691 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 8692 ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 8693 ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 8694 ATF_TP_ADD_TC(tp, vfork9); 8695 ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); 8696 ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); 8697 ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); 8698 ATF_TP_ADD_TC(tp, vfork13); 8699 ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); 8700 ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); 8701 ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); 8702 8703 ATF_TP_ADD_TC(tp, posix_spawn1); 8704 ATF_TP_ADD_TC(tp, posix_spawn2); 8705 ATF_TP_ADD_TC(tp, posix_spawn3); 8706 ATF_TP_ADD_TC(tp, posix_spawn4); 8707 ATF_TP_ADD_TC(tp, posix_spawn5); 8708 ATF_TP_ADD_TC(tp, posix_spawn6); 8709 ATF_TP_ADD_TC(tp, posix_spawn7); 8710 ATF_TP_ADD_TC(tp, posix_spawn8); 8711 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); 8712 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); 8713 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); 8714 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); 8715 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); 8716 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); 8717 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); 8718 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); 8719 8720 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1); 8721 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2); 8722 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3); 8723 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4); 8724 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5); 8725 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6); 8726 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7); 8727 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8); 8728 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9); 8729 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10); 8730 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11); 8731 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12); 8732 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13); 8733 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14); 8734 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15); 8735 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16); 8736 8737 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1); 8738 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2); 8739 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3); 8740 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4); 8741 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5); 8742 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6); 8743 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7); 8744 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8); 8745 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9); 8746 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10); 8747 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11); 8748 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12); 8749 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13); 8750 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14); 8751 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15); 8752 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16); 8753 8754 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1); 8755 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2); 8756 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3); 8757 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4); 8758 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5); 8759 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6); 8760 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7); 8761 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8); 8762 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9); 8763 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10); 8764 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11); 8765 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12); 8766 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13); 8767 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14); 8768 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15); 8769 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16); 8770 8771 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); 8772 ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); 8773 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); 8774 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); 8775 8776 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); 8777 ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); 8778 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); 8779 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); 8780 8781 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner); 8782 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker); 8783 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker); 8784 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone); 8785 8786 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner); 8787 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker); 8788 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker); 8789 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone); 8790 8791 ATF_TP_ADD_TC(tp, traceme_vfork_fork); 8792 ATF_TP_ADD_TC(tp, traceme_vfork_vfork); 8793 8794 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 8795 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 8796 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 8797 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 8798 8799 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 8800 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 8801 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 8802 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 8803 8804 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 8805 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 8806 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 8807 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 8808 8809 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 8810 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 8811 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 8812 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 8813 8814 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 8815 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 8816 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 8817 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 8818 8819 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 8820 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 8821 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 8822 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 8823 8824 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 8825 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 8826 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 8827 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 8828 8829 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 8830 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 8831 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 8832 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 8833 8834 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 8835 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 8836 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 8837 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 8838 8839 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 8840 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 8841 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 8842 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 8843 8844 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 8845 8846 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); 8847 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); 8848 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); 8849 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); 8850 8851 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); 8852 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); 8853 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); 8854 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); 8855 8856 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); 8857 8858 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); 8859 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); 8860 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); 8861 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); 8862 8863 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); 8864 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); 8865 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); 8866 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d); 8867 8868 ATF_TP_ADD_TC(tp, kill1); 8869 ATF_TP_ADD_TC(tp, kill2); 8870 ATF_TP_ADD_TC(tp, kill3); 8871 8872 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 8873 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 8874 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 8875 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 8876 8877 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus); 8878 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus); 8879 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus); 8880 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus); 8881 8882 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask); 8883 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask); 8884 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask); 8885 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask); 8886 8887 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name); 8888 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name); 8889 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name); 8890 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name); 8891 8892 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private); 8893 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private); 8894 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private); 8895 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private); 8896 8897 ATF_TP_ADD_TC(tp, traceme_lwpnext0); 8898 ATF_TP_ADD_TC(tp, traceme_lwpnext1); 8899 ATF_TP_ADD_TC(tp, traceme_lwpnext2); 8900 ATF_TP_ADD_TC(tp, traceme_lwpnext3); 8901 8902 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask); 8903 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask); 8904 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask); 8905 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask); 8906 8907 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name); 8908 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name); 8909 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name); 8910 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name); 8911 8912 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private); 8913 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private); 8914 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private); 8915 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private); 8916 8917 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 8918 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 8919 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 8920 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 8921 8922 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 8923 ATF_TP_ADD_TC(tp, siginfo_set_faked); 8924 8925 ATF_TP_ADD_TC(tp, traceme_exec); 8926 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 8927 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 8928 8929 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 8930 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 8931 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 8932 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 8933 8934 ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap); 8935 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap); 8936 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap); 8937 8938 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 8939 8940 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked); 8941 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored); 8942 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked); 8943 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored); 8944 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked); 8945 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored); 8946 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked); 8947 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored); 8948 8949 ATF_TP_ADD_TC(tp, threads_and_exec); 8950 8951 ATF_TP_ADD_TC(tp, suspend_no_deadlock); 8952 8953 ATF_TP_ADD_TC(tp, resume); 8954 8955 ATF_TP_ADD_TC(tp, clone1); 8956 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); 8957 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); 8958 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); 8959 ATF_TP_ADD_TC(tp, clone5); 8960 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); 8961 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); 8962 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); 8963 8964 ATF_TP_ADD_TC(tp, clone_vm1); 8965 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); 8966 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); 8967 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); 8968 ATF_TP_ADD_TC(tp, clone_vm5); 8969 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); 8970 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); 8971 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); 8972 8973 ATF_TP_ADD_TC(tp, clone_fs1); 8974 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); 8975 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); 8976 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); 8977 ATF_TP_ADD_TC(tp, clone_fs5); 8978 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); 8979 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); 8980 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); 8981 8982 ATF_TP_ADD_TC(tp, clone_files1); 8983 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); 8984 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); 8985 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); 8986 ATF_TP_ADD_TC(tp, clone_files5); 8987 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); 8988 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); 8989 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); 8990 8991// ATF_TP_ADD_TC(tp, clone_sighand1); // XXX 8992// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX 8993// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX 8994// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX 8995// ATF_TP_ADD_TC(tp, clone_sighand5); // XXX 8996// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX 8997// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX 8998// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX 8999 9000 ATF_TP_ADD_TC(tp, clone_vfork1); 9001 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); 9002 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); 9003 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); 9004 ATF_TP_ADD_TC(tp, clone_vfork5); 9005 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); 9006 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); 9007 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); 9008 9009 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); 9010 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); 9011 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); 9012 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); 9013 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); 9014 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); 9015 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); 9016 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); 9017// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX 9018// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX 9019 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); 9020 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); 9021 9022 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); 9023 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); 9024 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); 9025 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); 9026// ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX 9027 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork); 9028 9029 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 9030 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 9031 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 9032 9033 ATF_TP_ADD_TC(tp, core_dump_procinfo); 9034 9035#if defined(TWAIT_HAVE_STATUS) 9036 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 9037 ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign); 9038 ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler); 9039#if defined(__i386__) || defined(__x86_64__) 9040 ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints); 9041 ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints); 9042 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp); 9043 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig); 9044 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign); 9045 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler); 9046 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig); 9047 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign); 9048 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler); 9049 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig); 9050 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign); 9051 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler); 9052#endif 9053#endif 9054 9055 ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER(); 9056 ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL(); 9057 ATF_TP_ADD_TCS_PTRACE_WAIT_STEP(); 9058 9059 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 9060 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 9061 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 9062 9063#else 9064 ATF_TP_ADD_TC(tp, dummy); 9065#endif 9066 9067 return atf_no_error(); 9068} 9069