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