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