t_ptrace_wait.c revision 1.180
1/* $NetBSD: t_ptrace_wait.c,v 1.180 2020/05/04 22:34:22 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.180 2020/05/04 22:34:22 kamil Exp $"); 31 32#define __LEGACY_PT_LWPINFO 33 34#include <sys/param.h> 35#include <sys/types.h> 36#include <sys/exec_elf.h> 37#include <sys/mman.h> 38#include <sys/ptrace.h> 39#include <sys/resource.h> 40#include <sys/stat.h> 41#include <sys/syscall.h> 42#include <sys/sysctl.h> 43#include <sys/uio.h> 44#include <sys/wait.h> 45#include <machine/reg.h> 46#include <assert.h> 47#include <elf.h> 48#include <err.h> 49#include <errno.h> 50#include <fcntl.h> 51#include <lwp.h> 52#include <pthread.h> 53#include <sched.h> 54#include <signal.h> 55#include <spawn.h> 56#include <stdint.h> 57#include <stdio.h> 58#include <stdlib.h> 59#include <strings.h> 60#include <time.h> 61#include <unistd.h> 62 63#if defined(__i386__) || defined(__x86_64__) 64#include <cpuid.h> 65#include <x86/cpu_extended_state.h> 66#include <x86/specialreg.h> 67#endif 68 69#include <libelf.h> 70#include <gelf.h> 71 72#include <atf-c.h> 73 74#ifdef ENABLE_TESTS 75 76/* Assumptions in the kernel code that must be kept. */ 77__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) == 78 sizeof(((siginfo_t *)0)->si_pe_report_event)); 79__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 80 sizeof(((siginfo_t *)0)->si_pe_other_pid)); 81__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) == 82 sizeof(((siginfo_t *)0)->si_pe_lwp)); 83__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 84 sizeof(((struct ptrace_state *)0)->pe_lwp)); 85 86#include "h_macros.h" 87 88#include "t_ptrace_wait.h" 89#include "msg.h" 90 91#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 92 strerror(errno)) 93#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 94 "%d(%s) != %d", res, strerror(res), exp) 95 96static int debug = 0; 97 98#define DPRINTF(a, ...) do \ 99 if (debug) \ 100 printf("%s() %d.%d %s:%d " a, \ 101 __func__, getpid(), _lwp_self(), __FILE__, __LINE__, ##__VA_ARGS__); \ 102 while (/*CONSTCOND*/0) 103 104/// ---------------------------------------------------------------------------- 105 106static void 107traceme_raise(int sigval) 108{ 109 const int exitval = 5; 110 pid_t child, wpid; 111#if defined(TWAIT_HAVE_STATUS) 112 int status; 113#endif 114 115 ptrace_state_t state, zero_state; 116 const int slen = sizeof(state); 117 struct ptrace_siginfo info; 118 memset(&zero_state, 0, sizeof(zero_state)); 119 memset(&info, 0, sizeof(info)); 120 121 DPRINTF("Before forking process PID=%d\n", getpid()); 122 SYSCALL_REQUIRE((child = fork()) != -1); 123 if (child == 0) { 124 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 125 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 126 127 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 128 FORKEE_ASSERT(raise(sigval) == 0); 129 130 switch (sigval) { 131 case SIGKILL: 132 /* NOTREACHED */ 133 FORKEE_ASSERTX(0 && "This shall not be reached"); 134 __unreachable(); 135 default: 136 DPRINTF("Before exiting of the child process\n"); 137 _exit(exitval); 138 } 139 } 140 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 141 142 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 143 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 144 145 switch (sigval) { 146 case SIGKILL: 147 validate_status_signaled(status, sigval, 0); 148 SYSCALL_REQUIRE( 149 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) == -1); 150 151 break; 152 default: 153 validate_status_stopped(status, sigval); 154 155 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 156 "child\n"); 157 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 158 sizeof(info)) != -1); 159 160 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 161 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 162 "si_errno=%#x\n", 163 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 164 info.psi_siginfo.si_errno); 165 166 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 167 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 168 169 DPRINTF("Assert that PT_GET_PROCESS_STATE returns non-error"); 170 SYSCALL_REQUIRE( 171 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 172 ATF_REQUIRE(memcmp(&state, &zero_state, slen) == 0); 173 174 DPRINTF("Before resuming the child process where it left off " 175 "and without signal to be sent\n"); 176 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 177 178 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 179 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 180 child); 181 break; 182 } 183 184 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 185 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 186} 187 188#define TRACEME_RAISE(test, sig) \ 189ATF_TC(test); \ 190ATF_TC_HEAD(test, tc) \ 191{ \ 192 atf_tc_set_md_var(tc, "descr", \ 193 "Verify " #sig " followed by _exit(2) in a child"); \ 194} \ 195 \ 196ATF_TC_BODY(test, tc) \ 197{ \ 198 \ 199 traceme_raise(sig); \ 200} 201 202TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ 203TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */ 204TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */ 205TRACEME_RAISE(traceme_raise4, SIGHUP) /* hangup */ 206TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */ 207TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */ 208TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */ 209TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */ 210TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */ 211TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */ 212 213/// ---------------------------------------------------------------------------- 214 215static void 216traceme_raisesignal_ignored(int sigignored) 217{ 218 const int exitval = 5; 219 const int sigval = SIGSTOP; 220 pid_t child, wpid; 221 struct sigaction sa; 222#if defined(TWAIT_HAVE_STATUS) 223 int status; 224#endif 225 struct ptrace_siginfo info; 226 227 memset(&info, 0, sizeof(info)); 228 229 DPRINTF("Before forking process PID=%d\n", getpid()); 230 SYSCALL_REQUIRE((child = fork()) != -1); 231 if (child == 0) { 232 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 233 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 234 235 memset(&sa, 0, sizeof(sa)); 236 sa.sa_handler = SIG_IGN; 237 sigemptyset(&sa.sa_mask); 238 FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1); 239 240 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 241 FORKEE_ASSERT(raise(sigval) == 0); 242 243 DPRINTF("Before raising %s from child\n", 244 strsignal(sigignored)); 245 FORKEE_ASSERT(raise(sigignored) == 0); 246 247 DPRINTF("Before exiting of the child process\n"); 248 _exit(exitval); 249 } 250 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 251 252 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 253 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 254 255 validate_status_stopped(status, sigval); 256 257 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 258 SYSCALL_REQUIRE( 259 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 260 261 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 262 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 263 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 264 info.psi_siginfo.si_errno); 265 266 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 267 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 268 269 DPRINTF("Before resuming the child process where it left off and " 270 "without signal to be sent\n"); 271 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 272 273 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 274 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 275 276 validate_status_stopped(status, sigignored); 277 278 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 279 SYSCALL_REQUIRE( 280 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 281 282 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 283 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 284 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 285 info.psi_siginfo.si_errno); 286 287 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored); 288 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 289 290 DPRINTF("Before resuming the child process where it left off and " 291 "without signal to be sent\n"); 292 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 293 294 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 295 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 296 297 validate_status_exited(status, exitval); 298 299 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 300 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 301} 302 303#define TRACEME_RAISESIGNAL_IGNORED(test, sig) \ 304ATF_TC(test); \ 305ATF_TC_HEAD(test, tc) \ 306{ \ 307 atf_tc_set_md_var(tc, "descr", \ 308 "Verify that ignoring (with SIG_IGN) " #sig " in tracee " \ 309 "does not stop tracer from catching this raised signal"); \ 310} \ 311 \ 312ATF_TC_BODY(test, tc) \ 313{ \ 314 \ 315 traceme_raisesignal_ignored(sig); \ 316} 317 318// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 319TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */ 320TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP) /* hangup */ 321TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */ 322TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */ 323TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */ 324TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */ 325TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */ 326TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */ 327 328/// ---------------------------------------------------------------------------- 329 330static void 331traceme_raisesignal_masked(int sigmasked) 332{ 333 const int exitval = 5; 334 const int sigval = SIGSTOP; 335 pid_t child, wpid; 336#if defined(TWAIT_HAVE_STATUS) 337 int status; 338#endif 339 sigset_t intmask; 340 struct ptrace_siginfo info; 341 342 memset(&info, 0, sizeof(info)); 343 344 DPRINTF("Before forking process PID=%d\n", getpid()); 345 SYSCALL_REQUIRE((child = fork()) != -1); 346 if (child == 0) { 347 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 348 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 349 350 sigemptyset(&intmask); 351 sigaddset(&intmask, sigmasked); 352 sigprocmask(SIG_BLOCK, &intmask, NULL); 353 354 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 355 FORKEE_ASSERT(raise(sigval) == 0); 356 357 DPRINTF("Before raising %s breakpoint from child\n", 358 strsignal(sigmasked)); 359 FORKEE_ASSERT(raise(sigmasked) == 0); 360 361 DPRINTF("Before exiting of the child process\n"); 362 _exit(exitval); 363 } 364 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 365 366 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 367 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 368 369 validate_status_stopped(status, sigval); 370 371 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 372 SYSCALL_REQUIRE( 373 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 374 375 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 376 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 377 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 378 info.psi_siginfo.si_errno); 379 380 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 381 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 382 383 DPRINTF("Before resuming the child process where it left off and " 384 "without signal to be sent\n"); 385 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 386 387 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 388 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 389 390 validate_status_exited(status, exitval); 391 392 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 393 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 394} 395 396#define TRACEME_RAISESIGNAL_MASKED(test, sig) \ 397ATF_TC(test); \ 398ATF_TC_HEAD(test, tc) \ 399{ \ 400 atf_tc_set_md_var(tc, "descr", \ 401 "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \ 402 "stops tracer from catching this raised signal"); \ 403} \ 404 \ 405ATF_TC_BODY(test, tc) \ 406{ \ 407 \ 408 traceme_raisesignal_masked(sig); \ 409} 410 411// A signal handler for SIGKILL and SIGSTOP cannot be masked. 412TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */ 413TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */ 414TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */ 415TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */ 416TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */ 417TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */ 418TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */ 419TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */ 420 421/// ---------------------------------------------------------------------------- 422 423static void 424traceme_crash(int sig) 425{ 426 pid_t child, wpid; 427#if defined(TWAIT_HAVE_STATUS) 428 int status; 429#endif 430 struct ptrace_siginfo info; 431 432#ifndef PTRACE_ILLEGAL_ASM 433 if (sig == SIGILL) 434 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 435#endif 436 437 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 438 atf_tc_skip("FP exceptions are not supported"); 439 440 memset(&info, 0, sizeof(info)); 441 442 DPRINTF("Before forking process PID=%d\n", getpid()); 443 SYSCALL_REQUIRE((child = fork()) != -1); 444 if (child == 0) { 445 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 446 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 447 448 DPRINTF("Before executing a trap\n"); 449 switch (sig) { 450 case SIGTRAP: 451 trigger_trap(); 452 break; 453 case SIGSEGV: 454 trigger_segv(); 455 break; 456 case SIGILL: 457 trigger_ill(); 458 break; 459 case SIGFPE: 460 trigger_fpe(); 461 break; 462 case SIGBUS: 463 trigger_bus(); 464 break; 465 default: 466 /* NOTREACHED */ 467 FORKEE_ASSERTX(0 && "This shall not be reached"); 468 } 469 470 /* NOTREACHED */ 471 FORKEE_ASSERTX(0 && "This shall not be reached"); 472 } 473 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 474 475 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 476 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 477 478 validate_status_stopped(status, sig); 479 480 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 481 SYSCALL_REQUIRE( 482 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 483 484 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 485 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 486 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 487 info.psi_siginfo.si_errno); 488 489 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 490 switch (sig) { 491 case SIGTRAP: 492 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 493 break; 494 case SIGSEGV: 495 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 496 break; 497 case SIGILL: 498 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 499 info.psi_siginfo.si_code <= ILL_BADSTK); 500 break; 501 case SIGFPE: 502 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 503 break; 504 case SIGBUS: 505 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 506 break; 507 } 508 509 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 510 511 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 512 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 513 514 validate_status_signaled(status, SIGKILL, 0); 515 516 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 517 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 518} 519 520#define TRACEME_CRASH(test, sig) \ 521ATF_TC(test); \ 522ATF_TC_HEAD(test, tc) \ 523{ \ 524 atf_tc_set_md_var(tc, "descr", \ 525 "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \ 526} \ 527 \ 528ATF_TC_BODY(test, tc) \ 529{ \ 530 \ 531 traceme_crash(sig); \ 532} 533 534TRACEME_CRASH(traceme_crash_trap, SIGTRAP) 535TRACEME_CRASH(traceme_crash_segv, SIGSEGV) 536TRACEME_CRASH(traceme_crash_ill, SIGILL) 537TRACEME_CRASH(traceme_crash_fpe, SIGFPE) 538TRACEME_CRASH(traceme_crash_bus, SIGBUS) 539 540/// ---------------------------------------------------------------------------- 541 542static void 543traceme_signalmasked_crash(int sig) 544{ 545 const int sigval = SIGSTOP; 546 pid_t child, wpid; 547#if defined(TWAIT_HAVE_STATUS) 548 int status; 549#endif 550 struct ptrace_siginfo info; 551 sigset_t intmask; 552 struct kinfo_proc2 kp; 553 size_t len = sizeof(kp); 554 555 int name[6]; 556 const size_t namelen = __arraycount(name); 557 ki_sigset_t kp_sigmask; 558 559#ifndef PTRACE_ILLEGAL_ASM 560 if (sig == SIGILL) 561 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 562#endif 563 564 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 565 atf_tc_skip("FP exceptions are not supported"); 566 567 memset(&info, 0, sizeof(info)); 568 569 DPRINTF("Before forking process PID=%d\n", getpid()); 570 SYSCALL_REQUIRE((child = fork()) != -1); 571 if (child == 0) { 572 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 573 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 574 575 sigemptyset(&intmask); 576 sigaddset(&intmask, sig); 577 sigprocmask(SIG_BLOCK, &intmask, NULL); 578 579 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 580 FORKEE_ASSERT(raise(sigval) == 0); 581 582 DPRINTF("Before executing a trap\n"); 583 switch (sig) { 584 case SIGTRAP: 585 trigger_trap(); 586 break; 587 case SIGSEGV: 588 trigger_segv(); 589 break; 590 case SIGILL: 591 trigger_ill(); 592 break; 593 case SIGFPE: 594 trigger_fpe(); 595 break; 596 case SIGBUS: 597 trigger_bus(); 598 break; 599 default: 600 /* NOTREACHED */ 601 FORKEE_ASSERTX(0 && "This shall not be reached"); 602 } 603 604 /* NOTREACHED */ 605 FORKEE_ASSERTX(0 && "This shall not be reached"); 606 } 607 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 608 609 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 610 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 611 612 validate_status_stopped(status, sigval); 613 614 name[0] = CTL_KERN, 615 name[1] = KERN_PROC2, 616 name[2] = KERN_PROC_PID; 617 name[3] = child; 618 name[4] = sizeof(kp); 619 name[5] = 1; 620 621 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 622 623 kp_sigmask = kp.p_sigmask; 624 625 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 626 SYSCALL_REQUIRE( 627 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 628 629 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 630 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 631 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 632 info.psi_siginfo.si_errno); 633 634 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 635 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 636 637 DPRINTF("Before resuming the child process where it left off and " 638 "without signal to be sent\n"); 639 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 640 641 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 642 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 643 644 validate_status_stopped(status, sig); 645 646 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 647 SYSCALL_REQUIRE( 648 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 649 650 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 651 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 652 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 653 info.psi_siginfo.si_errno); 654 655 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 656 657 DPRINTF("kp_sigmask=" 658 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 659 kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2], 660 kp_sigmask.__bits[3]); 661 662 DPRINTF("kp.p_sigmask=" 663 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 664 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 665 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 666 667 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask))); 668 669 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 670 switch (sig) { 671 case SIGTRAP: 672 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 673 break; 674 case SIGSEGV: 675 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 676 break; 677 case SIGILL: 678 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 679 info.psi_siginfo.si_code <= ILL_BADSTK); 680 break; 681 case SIGFPE: 682 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 683 break; 684 case SIGBUS: 685 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 686 break; 687 } 688 689 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 690 691 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 692 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 693 694 validate_status_signaled(status, SIGKILL, 0); 695 696 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 697 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 698} 699 700#define TRACEME_SIGNALMASKED_CRASH(test, sig) \ 701ATF_TC(test); \ 702ATF_TC_HEAD(test, tc) \ 703{ \ 704 atf_tc_set_md_var(tc, "descr", \ 705 "Verify masked crash signal " #sig " in a child after " \ 706 "PT_TRACE_ME is delivered to its tracer"); \ 707} \ 708 \ 709ATF_TC_BODY(test, tc) \ 710{ \ 711 \ 712 traceme_signalmasked_crash(sig); \ 713} 714 715TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP) 716TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV) 717TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL) 718TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE) 719TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS) 720 721/// ---------------------------------------------------------------------------- 722 723static void 724traceme_signalignored_crash(int sig) 725{ 726 const int sigval = SIGSTOP; 727 pid_t child, wpid; 728#if defined(TWAIT_HAVE_STATUS) 729 int status; 730#endif 731 struct sigaction sa; 732 struct ptrace_siginfo info; 733 struct kinfo_proc2 kp; 734 size_t len = sizeof(kp); 735 736 int name[6]; 737 const size_t namelen = __arraycount(name); 738 ki_sigset_t kp_sigignore; 739 740#ifndef PTRACE_ILLEGAL_ASM 741 if (sig == SIGILL) 742 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 743#endif 744 745 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 746 atf_tc_skip("FP exceptions are not supported"); 747 748 memset(&info, 0, sizeof(info)); 749 750 DPRINTF("Before forking process PID=%d\n", getpid()); 751 SYSCALL_REQUIRE((child = fork()) != -1); 752 if (child == 0) { 753 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 754 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 755 756 memset(&sa, 0, sizeof(sa)); 757 sa.sa_handler = SIG_IGN; 758 sigemptyset(&sa.sa_mask); 759 760 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 761 762 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 763 FORKEE_ASSERT(raise(sigval) == 0); 764 765 DPRINTF("Before executing a trap\n"); 766 switch (sig) { 767 case SIGTRAP: 768 trigger_trap(); 769 break; 770 case SIGSEGV: 771 trigger_segv(); 772 break; 773 case SIGILL: 774 trigger_ill(); 775 break; 776 case SIGFPE: 777 trigger_fpe(); 778 break; 779 case SIGBUS: 780 trigger_bus(); 781 break; 782 default: 783 /* NOTREACHED */ 784 FORKEE_ASSERTX(0 && "This shall not be reached"); 785 } 786 787 /* NOTREACHED */ 788 FORKEE_ASSERTX(0 && "This shall not be reached"); 789 } 790 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 791 792 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 793 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 794 795 validate_status_stopped(status, sigval); 796 797 name[0] = CTL_KERN, 798 name[1] = KERN_PROC2, 799 name[2] = KERN_PROC_PID; 800 name[3] = child; 801 name[4] = sizeof(kp); 802 name[5] = 1; 803 804 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 805 806 kp_sigignore = kp.p_sigignore; 807 808 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 809 SYSCALL_REQUIRE( 810 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 811 812 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 813 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 814 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 815 info.psi_siginfo.si_errno); 816 817 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 818 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 819 820 DPRINTF("Before resuming the child process where it left off and " 821 "without signal to be sent\n"); 822 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 823 824 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 825 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 826 827 validate_status_stopped(status, sig); 828 829 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 830 SYSCALL_REQUIRE( 831 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 832 833 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 834 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 835 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 836 info.psi_siginfo.si_errno); 837 838 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 839 840 DPRINTF("kp_sigignore=" 841 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 842 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 843 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 844 845 DPRINTF("kp.p_sigignore=" 846 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 847 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 848 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 849 850 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore))); 851 852 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 853 switch (sig) { 854 case SIGTRAP: 855 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 856 break; 857 case SIGSEGV: 858 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 859 break; 860 case SIGILL: 861 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 862 info.psi_siginfo.si_code <= ILL_BADSTK); 863 break; 864 case SIGFPE: 865 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 866 break; 867 case SIGBUS: 868 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 869 break; 870 } 871 872 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 873 874 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 875 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 876 877 validate_status_signaled(status, SIGKILL, 0); 878 879 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 880 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 881} 882 883#define TRACEME_SIGNALIGNORED_CRASH(test, sig) \ 884ATF_TC(test); \ 885ATF_TC_HEAD(test, tc) \ 886{ \ 887 atf_tc_set_md_var(tc, "descr", \ 888 "Verify ignored crash signal " #sig " in a child after " \ 889 "PT_TRACE_ME is delivered to its tracer"); \ 890} \ 891 \ 892ATF_TC_BODY(test, tc) \ 893{ \ 894 \ 895 traceme_signalignored_crash(sig); \ 896} 897 898TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP) 899TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV) 900TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL) 901TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE) 902TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS) 903 904/// ---------------------------------------------------------------------------- 905 906static void 907traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 908{ 909 const int exitval = 5; 910 const int sigval = SIGSTOP; 911 pid_t child, wpid; 912 struct sigaction sa; 913#if defined(TWAIT_HAVE_STATUS) 914 int status; 915#endif 916 struct ptrace_siginfo info; 917 918 memset(&info, 0, sizeof(info)); 919 920 DPRINTF("Before forking process PID=%d\n", getpid()); 921 SYSCALL_REQUIRE((child = fork()) != -1); 922 if (child == 0) { 923 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 924 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 925 926 sa.sa_handler = sah; 927 sa.sa_flags = SA_SIGINFO; 928 sigemptyset(&sa.sa_mask); 929 930 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 931 932 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 933 FORKEE_ASSERT(raise(sigval) == 0); 934 935 FORKEE_ASSERT_EQ(*traceme_caught, 1); 936 937 DPRINTF("Before exiting of the child process\n"); 938 _exit(exitval); 939 } 940 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 941 942 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 943 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 944 945 validate_status_stopped(status, sigval); 946 947 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 948 SYSCALL_REQUIRE( 949 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 950 951 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 952 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 953 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 954 info.psi_siginfo.si_errno); 955 956 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 957 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 958 959 DPRINTF("Before resuming the child process where it left off and with " 960 "signal %s to be sent\n", strsignal(sigsent)); 961 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 962 963 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 964 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 965 966 validate_status_exited(status, exitval); 967 968 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 969 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 970} 971 972#define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 973ATF_TC(test); \ 974ATF_TC_HEAD(test, tc) \ 975{ \ 976 atf_tc_set_md_var(tc, "descr", \ 977 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 978 "handled correctly and caught by a signal handler"); \ 979} \ 980 \ 981static int test##_caught = 0; \ 982 \ 983static void \ 984test##_sighandler(int arg) \ 985{ \ 986 FORKEE_ASSERT_EQ(arg, sig); \ 987 \ 988 ++ test##_caught; \ 989} \ 990 \ 991ATF_TC_BODY(test, tc) \ 992{ \ 993 \ 994 traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 995} 996 997// A signal handler for SIGKILL and SIGSTOP cannot be registered. 998TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 999TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 1000TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 1001TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 1002TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 1003TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 1004TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 1005TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 1006 1007/// ---------------------------------------------------------------------------- 1008 1009static void 1010traceme_sendsignal_masked(int sigsent) 1011{ 1012 const int exitval = 5; 1013 const int sigval = SIGSTOP; 1014 pid_t child, wpid; 1015 sigset_t set; 1016#if defined(TWAIT_HAVE_STATUS) 1017 int status; 1018#endif 1019 struct ptrace_siginfo info; 1020 1021 memset(&info, 0, sizeof(info)); 1022 1023 DPRINTF("Before forking process PID=%d\n", getpid()); 1024 SYSCALL_REQUIRE((child = fork()) != -1); 1025 if (child == 0) { 1026 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1027 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1028 1029 sigemptyset(&set); 1030 sigaddset(&set, sigsent); 1031 FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 1032 1033 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1034 FORKEE_ASSERT(raise(sigval) == 0); 1035 1036 _exit(exitval); 1037 } 1038 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1039 1040 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1041 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1042 1043 validate_status_stopped(status, sigval); 1044 1045 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1046 SYSCALL_REQUIRE( 1047 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1048 1049 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1050 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1051 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1052 info.psi_siginfo.si_errno); 1053 1054 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1055 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1056 1057 DPRINTF("Before resuming the child process where it left off and with " 1058 "signal %s to be sent\n", strsignal(sigsent)); 1059 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1060 1061 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1062 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1063 1064 validate_status_exited(status, exitval); 1065 1066 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1067 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1068} 1069 1070#define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 1071ATF_TC(test); \ 1072ATF_TC_HEAD(test, tc) \ 1073{ \ 1074 atf_tc_set_md_var(tc, "descr", \ 1075 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1076 "handled correctly and the signal is masked by SIG_BLOCK"); \ 1077} \ 1078 \ 1079ATF_TC_BODY(test, tc) \ 1080{ \ 1081 \ 1082 traceme_sendsignal_masked(sig); \ 1083} 1084 1085// A signal handler for SIGKILL and SIGSTOP cannot be masked. 1086TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 1087TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 1088TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 1089TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 1090TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 1091TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 1092TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 1093TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 1094 1095/// ---------------------------------------------------------------------------- 1096 1097static void 1098traceme_sendsignal_ignored(int sigsent) 1099{ 1100 const int exitval = 5; 1101 const int sigval = SIGSTOP; 1102 pid_t child, wpid; 1103 struct sigaction sa; 1104#if defined(TWAIT_HAVE_STATUS) 1105 int status; 1106#endif 1107 struct ptrace_siginfo info; 1108 1109 memset(&info, 0, sizeof(info)); 1110 1111 DPRINTF("Before forking process PID=%d\n", getpid()); 1112 SYSCALL_REQUIRE((child = fork()) != -1); 1113 if (child == 0) { 1114 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1115 1116 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1117 1118 memset(&sa, 0, sizeof(sa)); 1119 sa.sa_handler = SIG_IGN; 1120 sigemptyset(&sa.sa_mask); 1121 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 1122 1123 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1124 FORKEE_ASSERT(raise(sigval) == 0); 1125 1126 _exit(exitval); 1127 } 1128 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1129 1130 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1131 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1132 1133 validate_status_stopped(status, sigval); 1134 1135 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1136 SYSCALL_REQUIRE( 1137 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1138 1139 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1140 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1141 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1142 info.psi_siginfo.si_errno); 1143 1144 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1145 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1146 1147 DPRINTF("Before resuming the child process where it left off and with " 1148 "signal %s to be sent\n", strsignal(sigsent)); 1149 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1150 1151 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1152 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1153 1154 validate_status_exited(status, exitval); 1155 1156 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1157 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1158} 1159 1160#define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 1161ATF_TC(test); \ 1162ATF_TC_HEAD(test, tc) \ 1163{ \ 1164 atf_tc_set_md_var(tc, "descr", \ 1165 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1166 "handled correctly and the signal is masked by SIG_IGN"); \ 1167} \ 1168 \ 1169ATF_TC_BODY(test, tc) \ 1170{ \ 1171 \ 1172 traceme_sendsignal_ignored(sig); \ 1173} 1174 1175// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 1176TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 1177TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 1178TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 1179TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 1180TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 1181TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 1182TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 1183TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 1184 1185/// ---------------------------------------------------------------------------- 1186 1187static void 1188traceme_sendsignal_simple(int sigsent) 1189{ 1190 const int sigval = SIGSTOP; 1191 int exitval = 0; 1192 pid_t child, wpid; 1193#if defined(TWAIT_HAVE_STATUS) 1194 int status; 1195 int expect_core; 1196 1197 switch (sigsent) { 1198 case SIGABRT: 1199 case SIGTRAP: 1200 case SIGBUS: 1201 case SIGILL: 1202 case SIGFPE: 1203 case SIGSEGV: 1204 expect_core = 1; 1205 break; 1206 default: 1207 expect_core = 0; 1208 break; 1209 } 1210#endif 1211 struct ptrace_siginfo info; 1212 1213 memset(&info, 0, sizeof(info)); 1214 1215 DPRINTF("Before forking process PID=%d\n", getpid()); 1216 SYSCALL_REQUIRE((child = fork()) != -1); 1217 if (child == 0) { 1218 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1219 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1220 1221 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1222 FORKEE_ASSERT(raise(sigval) == 0); 1223 1224 switch (sigsent) { 1225 case SIGCONT: 1226 case SIGSTOP: 1227 _exit(exitval); 1228 default: 1229 /* NOTREACHED */ 1230 FORKEE_ASSERTX(0 && "This shall not be reached"); 1231 } 1232 } 1233 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1234 1235 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1236 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1237 1238 validate_status_stopped(status, sigval); 1239 1240 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1241 SYSCALL_REQUIRE( 1242 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1243 1244 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1245 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1246 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1247 info.psi_siginfo.si_errno); 1248 1249 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1250 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1251 1252 DPRINTF("Before resuming the child process where it left off and with " 1253 "signal %s to be sent\n", strsignal(sigsent)); 1254 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1255 1256 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1257 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1258 1259 switch (sigsent) { 1260 case SIGSTOP: 1261 validate_status_stopped(status, sigsent); 1262 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1263 "child\n"); 1264 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1265 sizeof(info)) != -1); 1266 1267 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1268 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1269 "si_errno=%#x\n", 1270 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1271 info.psi_siginfo.si_errno); 1272 1273 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1274 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1275 1276 DPRINTF("Before resuming the child process where it left off " 1277 "and with signal %s to be sent\n", strsignal(sigsent)); 1278 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1279 1280 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1281 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1282 child); 1283 /* FALLTHROUGH */ 1284 case SIGCONT: 1285 validate_status_exited(status, exitval); 1286 break; 1287 default: 1288 validate_status_signaled(status, sigsent, expect_core); 1289 break; 1290 } 1291 1292 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1293 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1294} 1295 1296#define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 1297ATF_TC(test); \ 1298ATF_TC_HEAD(test, tc) \ 1299{ \ 1300 atf_tc_set_md_var(tc, "descr", \ 1301 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1302 "handled correctly in a child without a signal handler"); \ 1303} \ 1304 \ 1305ATF_TC_BODY(test, tc) \ 1306{ \ 1307 \ 1308 traceme_sendsignal_simple(sig); \ 1309} 1310 1311TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 1312TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 1313TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 1314TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 1315TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 1316TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 1317TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 1318TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 1319TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 1320TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 1321 1322/// ---------------------------------------------------------------------------- 1323 1324ATF_TC(traceme_pid1_parent); 1325ATF_TC_HEAD(traceme_pid1_parent, tc) 1326{ 1327 atf_tc_set_md_var(tc, "descr", 1328 "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 1329} 1330 1331ATF_TC_BODY(traceme_pid1_parent, tc) 1332{ 1333 struct msg_fds parent_child; 1334 int exitval_child1 = 1, exitval_child2 = 2; 1335 pid_t child1, child2, wpid; 1336 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1337#if defined(TWAIT_HAVE_STATUS) 1338 int status; 1339#endif 1340 1341 SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 1342 1343 DPRINTF("Before forking process PID=%d\n", getpid()); 1344 SYSCALL_REQUIRE((child1 = fork()) != -1); 1345 if (child1 == 0) { 1346 DPRINTF("Before forking process PID=%d\n", getpid()); 1347 SYSCALL_REQUIRE((child2 = fork()) != -1); 1348 if (child2 != 0) { 1349 DPRINTF("Parent process PID=%d, child2's PID=%d\n", 1350 getpid(), child2); 1351 _exit(exitval_child1); 1352 } 1353 CHILD_FROM_PARENT("exit child1", parent_child, msg); 1354 1355 DPRINTF("Assert that our parent is PID1 (initproc)\n"); 1356 FORKEE_ASSERT_EQ(getppid(), 1); 1357 1358 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1359 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 1360 SYSCALL_REQUIRE_ERRNO(errno, EPERM); 1361 1362 CHILD_TO_PARENT("child2 exiting", parent_child, msg); 1363 1364 _exit(exitval_child2); 1365 } 1366 DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 1367 1368 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1369 TWAIT_REQUIRE_SUCCESS( 1370 wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 1371 1372 validate_status_exited(status, exitval_child1); 1373 1374 DPRINTF("Notify that child1 is dead\n"); 1375 PARENT_TO_CHILD("exit child1", parent_child, msg); 1376 1377 DPRINTF("Wait for exiting of child2\n"); 1378 PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 1379} 1380 1381/// ---------------------------------------------------------------------------- 1382 1383static void 1384traceme_vfork_raise(int sigval) 1385{ 1386 const int exitval = 5, exitval_watcher = 10; 1387 pid_t child, parent, watcher, wpid; 1388 int rv; 1389#if defined(TWAIT_HAVE_STATUS) 1390 int status; 1391 1392 /* volatile workarounds GCC -Werror=clobbered */ 1393 volatile int expect_core; 1394 1395 switch (sigval) { 1396 case SIGABRT: 1397 case SIGTRAP: 1398 case SIGBUS: 1399 case SIGILL: 1400 case SIGFPE: 1401 case SIGSEGV: 1402 expect_core = 1; 1403 break; 1404 default: 1405 expect_core = 0; 1406 break; 1407 } 1408#endif 1409 1410 /* 1411 * Spawn a dedicated thread to watch for a stopped child and emit 1412 * the SIGKILL signal to it. 1413 * 1414 * vfork(2) might clobber watcher, this means that it's safer and 1415 * simpler to reparent this process to initproc and forget about it. 1416 */ 1417 if (sigval == SIGSTOP) { 1418 parent = getpid(); 1419 1420 watcher = fork(); 1421 ATF_REQUIRE(watcher != 1); 1422 if (watcher == 0) { 1423 /* Double fork(2) trick to reparent to initproc */ 1424 watcher = fork(); 1425 FORKEE_ASSERT_NEQ(watcher, -1); 1426 if (watcher != 0) 1427 _exit(exitval_watcher); 1428 1429 child = await_stopped_child(parent); 1430 1431 errno = 0; 1432 rv = kill(child, SIGKILL); 1433 FORKEE_ASSERT_EQ(rv, 0); 1434 FORKEE_ASSERT_EQ(errno, 0); 1435 1436 /* This exit value will be collected by initproc */ 1437 _exit(0); 1438 } 1439 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1440 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 1441 watcher); 1442 1443 validate_status_exited(status, exitval_watcher); 1444 1445 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1446 TWAIT_REQUIRE_FAILURE(ECHILD, 1447 wpid = TWAIT_GENERIC(watcher, &status, 0)); 1448 } 1449 1450 DPRINTF("Before forking process PID=%d\n", getpid()); 1451 SYSCALL_REQUIRE((child = vfork()) != -1); 1452 if (child == 0) { 1453 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1454 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1455 1456 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1457 FORKEE_ASSERT(raise(sigval) == 0); 1458 1459 switch (sigval) { 1460 case SIGSTOP: 1461 case SIGKILL: 1462 case SIGABRT: 1463 case SIGHUP: 1464 case SIGTRAP: 1465 case SIGBUS: 1466 case SIGILL: 1467 case SIGFPE: 1468 case SIGSEGV: 1469 /* NOTREACHED */ 1470 FORKEE_ASSERTX(0 && "This shall not be reached"); 1471 __unreachable(); 1472 default: 1473 DPRINTF("Before exiting of the child process\n"); 1474 _exit(exitval); 1475 } 1476 } 1477 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1478 1479 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1480 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1481 1482 switch (sigval) { 1483 case SIGKILL: 1484 case SIGABRT: 1485 case SIGHUP: 1486 case SIGTRAP: 1487 case SIGBUS: 1488 case SIGILL: 1489 case SIGFPE: 1490 case SIGSEGV: 1491 validate_status_signaled(status, sigval, expect_core); 1492 break; 1493 case SIGSTOP: 1494 validate_status_signaled(status, SIGKILL, 0); 1495 break; 1496 case SIGCONT: 1497 case SIGTSTP: 1498 case SIGTTIN: 1499 case SIGTTOU: 1500 validate_status_exited(status, exitval); 1501 break; 1502 default: 1503 /* NOTREACHED */ 1504 ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 1505 break; 1506 } 1507 1508 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1509 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1510} 1511 1512#define TRACEME_VFORK_RAISE(test, sig) \ 1513ATF_TC(test); \ 1514ATF_TC_HEAD(test, tc) \ 1515{ \ 1516 atf_tc_set_md_var(tc, "descr", \ 1517 "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 1518 "vfork(2)ed child"); \ 1519} \ 1520 \ 1521ATF_TC_BODY(test, tc) \ 1522{ \ 1523 \ 1524 traceme_vfork_raise(sig); \ 1525} 1526 1527TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 1528TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 1529TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 1530TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 1531TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 1532TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 1533TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 1534TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 1535TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 1536TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 1537TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 1538TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 1539TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 1540 1541/// ---------------------------------------------------------------------------- 1542 1543static void 1544traceme_vfork_crash(int sig) 1545{ 1546 pid_t child, wpid; 1547#if defined(TWAIT_HAVE_STATUS) 1548 int status; 1549#endif 1550 1551#ifndef PTRACE_ILLEGAL_ASM 1552 if (sig == SIGILL) 1553 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1554#endif 1555 1556 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1557 atf_tc_skip("FP exceptions are not supported"); 1558 1559 DPRINTF("Before forking process PID=%d\n", getpid()); 1560 SYSCALL_REQUIRE((child = vfork()) != -1); 1561 if (child == 0) { 1562 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1563 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1564 1565 DPRINTF("Before executing a trap\n"); 1566 switch (sig) { 1567 case SIGTRAP: 1568 trigger_trap(); 1569 break; 1570 case SIGSEGV: 1571 trigger_segv(); 1572 break; 1573 case SIGILL: 1574 trigger_ill(); 1575 break; 1576 case SIGFPE: 1577 trigger_fpe(); 1578 break; 1579 case SIGBUS: 1580 trigger_bus(); 1581 break; 1582 default: 1583 /* NOTREACHED */ 1584 FORKEE_ASSERTX(0 && "This shall not be reached"); 1585 } 1586 1587 /* NOTREACHED */ 1588 FORKEE_ASSERTX(0 && "This shall not be reached"); 1589 } 1590 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1591 1592 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1593 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1594 1595 validate_status_signaled(status, sig, 1); 1596 1597 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1598 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1599} 1600 1601#define TRACEME_VFORK_CRASH(test, sig) \ 1602ATF_TC(test); \ 1603ATF_TC_HEAD(test, tc) \ 1604{ \ 1605 atf_tc_set_md_var(tc, "descr", \ 1606 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1607 "vfork(2)ed child"); \ 1608} \ 1609 \ 1610ATF_TC_BODY(test, tc) \ 1611{ \ 1612 \ 1613 traceme_vfork_crash(sig); \ 1614} 1615 1616TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 1617TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 1618TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 1619TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 1620TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 1621 1622/// ---------------------------------------------------------------------------- 1623 1624static void 1625traceme_vfork_signalmasked_crash(int sig) 1626{ 1627 pid_t child, wpid; 1628#if defined(TWAIT_HAVE_STATUS) 1629 int status; 1630#endif 1631 sigset_t intmask; 1632 1633#ifndef PTRACE_ILLEGAL_ASM 1634 if (sig == SIGILL) 1635 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1636#endif 1637 1638 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1639 atf_tc_skip("FP exceptions are not supported"); 1640 1641 DPRINTF("Before forking process PID=%d\n", getpid()); 1642 SYSCALL_REQUIRE((child = vfork()) != -1); 1643 if (child == 0) { 1644 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1645 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1646 1647 sigemptyset(&intmask); 1648 sigaddset(&intmask, sig); 1649 sigprocmask(SIG_BLOCK, &intmask, NULL); 1650 1651 DPRINTF("Before executing a trap\n"); 1652 switch (sig) { 1653 case SIGTRAP: 1654 trigger_trap(); 1655 break; 1656 case SIGSEGV: 1657 trigger_segv(); 1658 break; 1659 case SIGILL: 1660 trigger_ill(); 1661 break; 1662 case SIGFPE: 1663 trigger_fpe(); 1664 break; 1665 case SIGBUS: 1666 trigger_bus(); 1667 break; 1668 default: 1669 /* NOTREACHED */ 1670 FORKEE_ASSERTX(0 && "This shall not be reached"); 1671 } 1672 1673 /* NOTREACHED */ 1674 FORKEE_ASSERTX(0 && "This shall not be reached"); 1675 } 1676 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1677 1678 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1679 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1680 1681 validate_status_signaled(status, sig, 1); 1682 1683 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1684 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1685} 1686 1687#define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig) \ 1688ATF_TC(test); \ 1689ATF_TC_HEAD(test, tc) \ 1690{ \ 1691 atf_tc_set_md_var(tc, "descr", \ 1692 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1693 "vfork(2)ed child with a masked signal"); \ 1694} \ 1695 \ 1696ATF_TC_BODY(test, tc) \ 1697{ \ 1698 \ 1699 traceme_vfork_signalmasked_crash(sig); \ 1700} 1701 1702TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP) 1703TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV) 1704TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL) 1705TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE) 1706TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS) 1707 1708/// ---------------------------------------------------------------------------- 1709 1710static void 1711traceme_vfork_signalignored_crash(int sig) 1712{ 1713 pid_t child, wpid; 1714#if defined(TWAIT_HAVE_STATUS) 1715 int status; 1716#endif 1717 struct sigaction sa; 1718 1719#ifndef PTRACE_ILLEGAL_ASM 1720 if (sig == SIGILL) 1721 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1722#endif 1723 1724 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1725 atf_tc_skip("FP exceptions are not supported"); 1726 1727 DPRINTF("Before forking process PID=%d\n", getpid()); 1728 SYSCALL_REQUIRE((child = vfork()) != -1); 1729 if (child == 0) { 1730 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1731 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1732 1733 memset(&sa, 0, sizeof(sa)); 1734 sa.sa_handler = SIG_IGN; 1735 sigemptyset(&sa.sa_mask); 1736 1737 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 1738 1739 DPRINTF("Before executing a trap\n"); 1740 switch (sig) { 1741 case SIGTRAP: 1742 trigger_trap(); 1743 break; 1744 case SIGSEGV: 1745 trigger_segv(); 1746 break; 1747 case SIGILL: 1748 trigger_ill(); 1749 break; 1750 case SIGFPE: 1751 trigger_fpe(); 1752 break; 1753 case SIGBUS: 1754 trigger_bus(); 1755 break; 1756 default: 1757 /* NOTREACHED */ 1758 FORKEE_ASSERTX(0 && "This shall not be reached"); 1759 } 1760 1761 /* NOTREACHED */ 1762 FORKEE_ASSERTX(0 && "This shall not be reached"); 1763 } 1764 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1765 1766 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1767 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1768 1769 validate_status_signaled(status, sig, 1); 1770 1771 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1772 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1773} 1774 1775#define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig) \ 1776ATF_TC(test); \ 1777ATF_TC_HEAD(test, tc) \ 1778{ \ 1779 atf_tc_set_md_var(tc, "descr", \ 1780 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1781 "vfork(2)ed child with ignored signal"); \ 1782} \ 1783 \ 1784ATF_TC_BODY(test, tc) \ 1785{ \ 1786 \ 1787 traceme_vfork_signalignored_crash(sig); \ 1788} 1789 1790TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap, 1791 SIGTRAP) 1792TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv, 1793 SIGSEGV) 1794TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill, 1795 SIGILL) 1796TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe, 1797 SIGFPE) 1798TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus, 1799 SIGBUS) 1800 1801/// ---------------------------------------------------------------------------- 1802 1803static void 1804traceme_vfork_exec(bool masked, bool ignored) 1805{ 1806 const int sigval = SIGTRAP; 1807 pid_t child, wpid; 1808#if defined(TWAIT_HAVE_STATUS) 1809 int status; 1810#endif 1811 struct sigaction sa; 1812 struct ptrace_siginfo info; 1813 sigset_t intmask; 1814 struct kinfo_proc2 kp; 1815 size_t len = sizeof(kp); 1816 1817 int name[6]; 1818 const size_t namelen = __arraycount(name); 1819 ki_sigset_t kp_sigmask; 1820 ki_sigset_t kp_sigignore; 1821 1822 memset(&info, 0, sizeof(info)); 1823 1824 DPRINTF("Before forking process PID=%d\n", getpid()); 1825 SYSCALL_REQUIRE((child = vfork()) != -1); 1826 if (child == 0) { 1827 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1828 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1829 1830 if (masked) { 1831 sigemptyset(&intmask); 1832 sigaddset(&intmask, sigval); 1833 sigprocmask(SIG_BLOCK, &intmask, NULL); 1834 } 1835 1836 if (ignored) { 1837 memset(&sa, 0, sizeof(sa)); 1838 sa.sa_handler = SIG_IGN; 1839 sigemptyset(&sa.sa_mask); 1840 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 1841 } 1842 1843 DPRINTF("Before calling execve(2) from child\n"); 1844 execlp("/bin/echo", "/bin/echo", NULL); 1845 1846 /* NOTREACHED */ 1847 FORKEE_ASSERTX(0 && "Not reached"); 1848 } 1849 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1850 1851 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1852 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1853 1854 validate_status_stopped(status, sigval); 1855 1856 name[0] = CTL_KERN, 1857 name[1] = KERN_PROC2, 1858 name[2] = KERN_PROC_PID; 1859 name[3] = getpid(); 1860 name[4] = sizeof(kp); 1861 name[5] = 1; 1862 1863 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1864 1865 if (masked) 1866 kp_sigmask = kp.p_sigmask; 1867 1868 if (ignored) 1869 kp_sigignore = kp.p_sigignore; 1870 1871 name[3] = getpid(); 1872 1873 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1874 1875 if (masked) { 1876 DPRINTF("kp_sigmask=" 1877 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1878 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1879 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1880 1881 DPRINTF("kp.p_sigmask=" 1882 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1883 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1884 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1885 1886 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 1887 sizeof(kp_sigmask))); 1888 } 1889 1890 if (ignored) { 1891 DPRINTF("kp_sigignore=" 1892 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1893 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1894 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1895 1896 DPRINTF("kp.p_sigignore=" 1897 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1898 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1899 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1900 1901 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 1902 sizeof(kp_sigignore))); 1903 } 1904 1905 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1906 SYSCALL_REQUIRE( 1907 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1908 1909 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1910 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1911 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1912 info.psi_siginfo.si_errno); 1913 1914 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1915 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1916 1917 DPRINTF("Before resuming the child process where it left off and " 1918 "without signal to be sent\n"); 1919 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1920 1921 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1922 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1923 1924 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1925 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1926} 1927 1928#define TRACEME_VFORK_EXEC(test, masked, ignored) \ 1929ATF_TC(test); \ 1930ATF_TC_HEAD(test, tc) \ 1931{ \ 1932 atf_tc_set_md_var(tc, "descr", \ 1933 "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed " \ 1934 "child%s%s", masked ? " with masked signal" : "", \ 1935 masked ? " with ignored signal" : ""); \ 1936} \ 1937 \ 1938ATF_TC_BODY(test, tc) \ 1939{ \ 1940 \ 1941 traceme_vfork_exec(masked, ignored); \ 1942} 1943 1944TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false) 1945TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false) 1946TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true) 1947 1948/// ---------------------------------------------------------------------------- 1949 1950#if defined(TWAIT_HAVE_PID) 1951static void 1952unrelated_tracer_sees_crash(int sig, bool masked, bool ignored) 1953{ 1954 const int sigval = SIGSTOP; 1955 struct msg_fds parent_tracee, parent_tracer; 1956 const int exitval = 10; 1957 pid_t tracee, tracer, wpid; 1958 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1959#if defined(TWAIT_HAVE_STATUS) 1960 int status; 1961#endif 1962 struct sigaction sa; 1963 struct ptrace_siginfo info; 1964 sigset_t intmask; 1965 struct kinfo_proc2 kp; 1966 size_t len = sizeof(kp); 1967 1968 int name[6]; 1969 const size_t namelen = __arraycount(name); 1970 ki_sigset_t kp_sigmask; 1971 ki_sigset_t kp_sigignore; 1972 1973#ifndef PTRACE_ILLEGAL_ASM 1974 if (sig == SIGILL) 1975 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1976#endif 1977 1978 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1979 atf_tc_skip("FP exceptions are not supported"); 1980 1981 memset(&info, 0, sizeof(info)); 1982 1983 DPRINTF("Spawn tracee\n"); 1984 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1985 tracee = atf_utils_fork(); 1986 if (tracee == 0) { 1987 // Wait for parent to let us crash 1988 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 1989 1990 if (masked) { 1991 sigemptyset(&intmask); 1992 sigaddset(&intmask, sig); 1993 sigprocmask(SIG_BLOCK, &intmask, NULL); 1994 } 1995 1996 if (ignored) { 1997 memset(&sa, 0, sizeof(sa)); 1998 sa.sa_handler = SIG_IGN; 1999 sigemptyset(&sa.sa_mask); 2000 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 2001 } 2002 2003 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2004 FORKEE_ASSERT(raise(sigval) == 0); 2005 2006 DPRINTF("Before executing a trap\n"); 2007 switch (sig) { 2008 case SIGTRAP: 2009 trigger_trap(); 2010 break; 2011 case SIGSEGV: 2012 trigger_segv(); 2013 break; 2014 case SIGILL: 2015 trigger_ill(); 2016 break; 2017 case SIGFPE: 2018 trigger_fpe(); 2019 break; 2020 case SIGBUS: 2021 trigger_bus(); 2022 break; 2023 default: 2024 /* NOTREACHED */ 2025 FORKEE_ASSERTX(0 && "This shall not be reached"); 2026 } 2027 2028 /* NOTREACHED */ 2029 FORKEE_ASSERTX(0 && "This shall not be reached"); 2030 } 2031 2032 DPRINTF("Spawn debugger\n"); 2033 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2034 tracer = atf_utils_fork(); 2035 if (tracer == 0) { 2036 /* Fork again and drop parent to reattach to PID 1 */ 2037 tracer = atf_utils_fork(); 2038 if (tracer != 0) 2039 _exit(exitval); 2040 2041 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2042 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2043 2044 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2045 FORKEE_REQUIRE_SUCCESS( 2046 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2047 2048 forkee_status_stopped(status, SIGSTOP); 2049 2050 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2051 "traced process\n"); 2052 SYSCALL_REQUIRE( 2053 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2054 2055 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2056 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2057 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2058 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2059 2060 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 2061 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 2062 2063 /* Resume tracee with PT_CONTINUE */ 2064 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2065 2066 /* Inform parent that tracer has attached to tracee */ 2067 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2068 2069 /* Wait for parent to tell use that tracee should have exited */ 2070 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2071 2072 /* Wait for tracee and assert that it exited */ 2073 FORKEE_REQUIRE_SUCCESS( 2074 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2075 2076 forkee_status_stopped(status, sigval); 2077 2078 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2079 "traced process\n"); 2080 SYSCALL_REQUIRE( 2081 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2082 2083 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2084 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2085 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2086 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2087 2088 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 2089 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 2090 2091 name[0] = CTL_KERN, 2092 name[1] = KERN_PROC2, 2093 name[2] = KERN_PROC_PID; 2094 name[3] = tracee; 2095 name[4] = sizeof(kp); 2096 name[5] = 1; 2097 2098 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2099 2100 if (masked) 2101 kp_sigmask = kp.p_sigmask; 2102 2103 if (ignored) 2104 kp_sigignore = kp.p_sigignore; 2105 2106 /* Resume tracee with PT_CONTINUE */ 2107 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2108 2109 /* Wait for tracee and assert that it exited */ 2110 FORKEE_REQUIRE_SUCCESS( 2111 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2112 2113 forkee_status_stopped(status, sig); 2114 2115 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2116 "traced process\n"); 2117 SYSCALL_REQUIRE( 2118 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2119 2120 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2121 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2122 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2123 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2124 2125 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig); 2126 2127 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2128 2129 if (masked) { 2130 DPRINTF("kp_sigmask=" 2131 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2132 PRIx32 "\n", 2133 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 2134 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 2135 2136 DPRINTF("kp.p_sigmask=" 2137 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2138 PRIx32 "\n", 2139 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 2140 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 2141 2142 FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask, 2143 sizeof(kp_sigmask))); 2144 } 2145 2146 if (ignored) { 2147 DPRINTF("kp_sigignore=" 2148 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2149 PRIx32 "\n", 2150 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 2151 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 2152 2153 DPRINTF("kp.p_sigignore=" 2154 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2155 PRIx32 "\n", 2156 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 2157 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 2158 2159 FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore, 2160 sizeof(kp_sigignore))); 2161 } 2162 2163 switch (sig) { 2164 case SIGTRAP: 2165 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 2166 break; 2167 case SIGSEGV: 2168 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 2169 break; 2170 case SIGILL: 2171 FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC && 2172 info.psi_siginfo.si_code <= ILL_BADSTK); 2173 break; 2174 case SIGFPE: 2175 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 2176 break; 2177 case SIGBUS: 2178 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 2179 break; 2180 } 2181 2182 FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 2183 DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 2184 FORKEE_REQUIRE_SUCCESS( 2185 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2186 2187 forkee_status_signaled(status, SIGKILL, 0); 2188 2189 /* Inform parent that tracer is exiting normally */ 2190 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 2191 2192 DPRINTF("Before exiting of the tracer process\n"); 2193 _exit(0 /* collect by initproc */); 2194 } 2195 2196 DPRINTF("Wait for the tracer process (direct child) to exit " 2197 "calling %s()\n", TWAIT_FNAME); 2198 TWAIT_REQUIRE_SUCCESS( 2199 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2200 2201 validate_status_exited(status, exitval); 2202 2203 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2204 TWAIT_FNAME); 2205 TWAIT_REQUIRE_SUCCESS( 2206 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2207 2208 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2209 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2210 2211 DPRINTF("Resume the tracee and let it crash\n"); 2212 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2213 2214 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 2215 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2216 2217 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2218 TWAIT_FNAME); 2219 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2220 2221 validate_status_signaled(status, SIGKILL, 0); 2222 2223 DPRINTF("Await normal exit of tracer\n"); 2224 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 2225 2226 msg_close(&parent_tracer); 2227 msg_close(&parent_tracee); 2228} 2229 2230#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 2231ATF_TC(test); \ 2232ATF_TC_HEAD(test, tc) \ 2233{ \ 2234 atf_tc_set_md_var(tc, "descr", \ 2235 "Assert that an unrelated tracer sees crash signal from " \ 2236 "the debuggee"); \ 2237} \ 2238 \ 2239ATF_TC_BODY(test, tc) \ 2240{ \ 2241 \ 2242 unrelated_tracer_sees_crash(sig, false, false); \ 2243} 2244 2245UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 2246UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 2247UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 2248UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 2249UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 2250 2251#define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig) \ 2252ATF_TC(test); \ 2253ATF_TC_HEAD(test, tc) \ 2254{ \ 2255 atf_tc_set_md_var(tc, "descr", \ 2256 "Assert that an unrelated tracer sees crash signal from " \ 2257 "the debuggee with masked signal"); \ 2258} \ 2259 \ 2260ATF_TC_BODY(test, tc) \ 2261{ \ 2262 \ 2263 unrelated_tracer_sees_crash(sig, true, false); \ 2264} 2265 2266UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2267 unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP) 2268UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2269 unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV) 2270UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2271 unrelated_tracer_sees_signalmasked_crash_ill, SIGILL) 2272UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2273 unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE) 2274UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2275 unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS) 2276 2277#define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig) \ 2278ATF_TC(test); \ 2279ATF_TC_HEAD(test, tc) \ 2280{ \ 2281 atf_tc_set_md_var(tc, "descr", \ 2282 "Assert that an unrelated tracer sees crash signal from " \ 2283 "the debuggee with signal ignored"); \ 2284} \ 2285 \ 2286ATF_TC_BODY(test, tc) \ 2287{ \ 2288 \ 2289 unrelated_tracer_sees_crash(sig, false, true); \ 2290} 2291 2292UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2293 unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP) 2294UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2295 unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV) 2296UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2297 unrelated_tracer_sees_signalignored_crash_ill, SIGILL) 2298UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2299 unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE) 2300UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2301 unrelated_tracer_sees_signalignored_crash_bus, SIGBUS) 2302#endif 2303 2304/// ---------------------------------------------------------------------------- 2305 2306#if defined(TWAIT_HAVE_PID) 2307static void 2308tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 2309 bool stopped) 2310{ 2311 /* 2312 * notimeout - disable timeout in await zombie function 2313 * unrelated - attach from unrelated tracer reparented to initproc 2314 * stopped - attach to a stopped process 2315 */ 2316 2317 struct msg_fds parent_tracee, parent_tracer; 2318 const int exitval_tracee = 5; 2319 const int exitval_tracer = 10; 2320 pid_t tracee, tracer, wpid; 2321 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2322#if defined(TWAIT_HAVE_STATUS) 2323 int status; 2324#endif 2325 2326 /* 2327 * Only a subset of options are supported. 2328 */ 2329 ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 2330 (!notimeout && unrelated && !stopped) || 2331 (notimeout && !unrelated && !stopped) || 2332 (!notimeout && unrelated && stopped)); 2333 2334 DPRINTF("Spawn tracee\n"); 2335 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2336 tracee = atf_utils_fork(); 2337 if (tracee == 0) { 2338 if (stopped) { 2339 DPRINTF("Stop self PID %d\n", getpid()); 2340 raise(SIGSTOP); 2341 } 2342 2343 // Wait for parent to let us exit 2344 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2345 _exit(exitval_tracee); 2346 } 2347 2348 DPRINTF("Spawn debugger\n"); 2349 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2350 tracer = atf_utils_fork(); 2351 if (tracer == 0) { 2352 if(unrelated) { 2353 /* Fork again and drop parent to reattach to PID 1 */ 2354 tracer = atf_utils_fork(); 2355 if (tracer != 0) 2356 _exit(exitval_tracer); 2357 } 2358 2359 if (stopped) { 2360 DPRINTF("Await for a stopped parent PID %d\n", tracee); 2361 await_stopped(tracee); 2362 } 2363 2364 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2365 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2366 2367 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2368 FORKEE_REQUIRE_SUCCESS( 2369 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2370 2371 forkee_status_stopped(status, SIGSTOP); 2372 2373 /* Resume tracee with PT_CONTINUE */ 2374 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2375 2376 /* Inform parent that tracer has attached to tracee */ 2377 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2378 2379 /* Wait for parent to tell use that tracee should have exited */ 2380 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2381 2382 /* Wait for tracee and assert that it exited */ 2383 FORKEE_REQUIRE_SUCCESS( 2384 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2385 2386 forkee_status_exited(status, exitval_tracee); 2387 DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 2388 2389 DPRINTF("Before exiting of the tracer process\n"); 2390 _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 2391 } 2392 2393 if (unrelated) { 2394 DPRINTF("Wait for the tracer process (direct child) to exit " 2395 "calling %s()\n", TWAIT_FNAME); 2396 TWAIT_REQUIRE_SUCCESS( 2397 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2398 2399 validate_status_exited(status, exitval_tracer); 2400 2401 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2402 TWAIT_FNAME); 2403 TWAIT_REQUIRE_SUCCESS( 2404 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2405 } 2406 2407 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2408 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2409 2410 DPRINTF("Resume the tracee and let it exit\n"); 2411 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2412 2413 DPRINTF("Detect that tracee is zombie\n"); 2414 if (notimeout) 2415 await_zombie_raw(tracee, 0); 2416 else 2417 await_zombie(tracee); 2418 2419 DPRINTF("Assert that there is no status about tracee %d - " 2420 "Tracer must detect zombie first - calling %s()\n", tracee, 2421 TWAIT_FNAME); 2422 TWAIT_REQUIRE_SUCCESS( 2423 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2424 2425 if (unrelated) { 2426 DPRINTF("Resume the tracer and let it detect exited tracee\n"); 2427 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2428 } else { 2429 DPRINTF("Tell the tracer child should have exited\n"); 2430 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2431 DPRINTF("Wait for tracer to finish its job and exit - calling " 2432 "%s()\n", TWAIT_FNAME); 2433 2434 DPRINTF("Wait from tracer child to complete waiting for " 2435 "tracee\n"); 2436 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2437 tracer); 2438 2439 validate_status_exited(status, exitval_tracer); 2440 } 2441 2442 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2443 TWAIT_FNAME); 2444 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2445 2446 validate_status_exited(status, exitval_tracee); 2447 2448 msg_close(&parent_tracer); 2449 msg_close(&parent_tracee); 2450} 2451 2452ATF_TC(tracer_sees_terminaton_before_the_parent); 2453ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 2454{ 2455 atf_tc_set_md_var(tc, "descr", 2456 "Assert that tracer sees process termination before the parent"); 2457} 2458 2459ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 2460{ 2461 2462 tracer_sees_terminaton_before_the_parent_raw(false, false, false); 2463} 2464 2465ATF_TC(tracer_sysctl_lookup_without_duplicates); 2466ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 2467{ 2468 atf_tc_set_md_var(tc, "timeout", "15"); 2469 atf_tc_set_md_var(tc, "descr", 2470 "Assert that await_zombie() in attach1 always finds a single " 2471 "process and no other error is reported"); 2472} 2473 2474ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 2475{ 2476 time_t start, end; 2477 double diff; 2478 unsigned long N = 0; 2479 2480 /* 2481 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 2482 * This test body isn't specific to this race, however it's just good 2483 * enough for this purposes, no need to invent a dedicated code flow. 2484 */ 2485 2486 start = time(NULL); 2487 while (true) { 2488 DPRINTF("Step: %lu\n", N); 2489 tracer_sees_terminaton_before_the_parent_raw(true, false, 2490 false); 2491 end = time(NULL); 2492 diff = difftime(end, start); 2493 if (diff >= 5.0) 2494 break; 2495 ++N; 2496 } 2497 DPRINTF("Iterations: %lu\n", N); 2498} 2499 2500ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 2501ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2502{ 2503 atf_tc_set_md_var(tc, "descr", 2504 "Assert that tracer sees process termination before the parent"); 2505} 2506 2507ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2508{ 2509 2510 tracer_sees_terminaton_before_the_parent_raw(false, true, false); 2511} 2512 2513ATF_TC(tracer_attach_to_unrelated_stopped_process); 2514ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 2515{ 2516 atf_tc_set_md_var(tc, "descr", 2517 "Assert that tracer can attach to an unrelated stopped process"); 2518} 2519 2520ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 2521{ 2522 2523 tracer_sees_terminaton_before_the_parent_raw(false, true, true); 2524} 2525#endif 2526 2527/// ---------------------------------------------------------------------------- 2528 2529static void 2530parent_attach_to_its_child(bool stopped) 2531{ 2532 struct msg_fds parent_tracee; 2533 const int exitval_tracee = 5; 2534 pid_t tracee, wpid; 2535 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2536#if defined(TWAIT_HAVE_STATUS) 2537 int status; 2538#endif 2539 2540 DPRINTF("Spawn tracee\n"); 2541 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2542 tracee = atf_utils_fork(); 2543 if (tracee == 0) { 2544 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2545 DPRINTF("Parent should now attach to tracee\n"); 2546 2547 if (stopped) { 2548 DPRINTF("Stop self PID %d\n", getpid()); 2549 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2550 } 2551 2552 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 2553 /* Wait for message from the parent */ 2554 _exit(exitval_tracee); 2555 } 2556 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2557 2558 if (stopped) { 2559 DPRINTF("Await for a stopped tracee PID %d\n", tracee); 2560 await_stopped(tracee); 2561 } 2562 2563 DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 2564 SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2565 2566 DPRINTF("Wait for the stopped tracee process with %s()\n", 2567 TWAIT_FNAME); 2568 TWAIT_REQUIRE_SUCCESS( 2569 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2570 2571 validate_status_stopped(status, SIGSTOP); 2572 2573 DPRINTF("Resume tracee with PT_CONTINUE\n"); 2574 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2575 2576 DPRINTF("Let the tracee exit now\n"); 2577 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 2578 2579 DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 2580 TWAIT_REQUIRE_SUCCESS( 2581 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2582 2583 validate_status_exited(status, exitval_tracee); 2584 2585 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 2586 TWAIT_REQUIRE_FAILURE(ECHILD, 2587 wpid = TWAIT_GENERIC(tracee, &status, 0)); 2588 2589 msg_close(&parent_tracee); 2590} 2591 2592ATF_TC(parent_attach_to_its_child); 2593ATF_TC_HEAD(parent_attach_to_its_child, tc) 2594{ 2595 atf_tc_set_md_var(tc, "descr", 2596 "Assert that tracer parent can PT_ATTACH to its child"); 2597} 2598 2599ATF_TC_BODY(parent_attach_to_its_child, tc) 2600{ 2601 2602 parent_attach_to_its_child(false); 2603} 2604 2605ATF_TC(parent_attach_to_its_stopped_child); 2606ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 2607{ 2608 atf_tc_set_md_var(tc, "descr", 2609 "Assert that tracer parent can PT_ATTACH to its stopped child"); 2610} 2611 2612ATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 2613{ 2614 2615 parent_attach_to_its_child(true); 2616} 2617 2618/// ---------------------------------------------------------------------------- 2619 2620static void 2621child_attach_to_its_parent(bool stopped) 2622{ 2623 struct msg_fds parent_tracee; 2624 const int exitval_tracer = 5; 2625 pid_t tracer, wpid; 2626 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2627#if defined(TWAIT_HAVE_STATUS) 2628 int status; 2629#endif 2630 2631 DPRINTF("Spawn tracer\n"); 2632 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2633 tracer = atf_utils_fork(); 2634 if (tracer == 0) { 2635 /* Wait for message from the parent */ 2636 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2637 2638 if (stopped) { 2639 DPRINTF("Await for a stopped parent PID %d\n", 2640 getppid()); 2641 await_stopped(getppid()); 2642 } 2643 2644 DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 2645 getppid()); 2646 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 2647 2648 DPRINTF("Wait for the stopped parent process with %s()\n", 2649 TWAIT_FNAME); 2650 FORKEE_REQUIRE_SUCCESS( 2651 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 2652 2653 forkee_status_stopped(status, SIGSTOP); 2654 2655 DPRINTF("Resume parent with PT_DETACH\n"); 2656 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 2657 != -1); 2658 2659 /* Tell parent we are ready */ 2660 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 2661 2662 _exit(exitval_tracer); 2663 } 2664 2665 DPRINTF("Wait for the tracer to become ready\n"); 2666 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2667 2668 if (stopped) { 2669 DPRINTF("Stop self PID %d\n", getpid()); 2670 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2671 } 2672 2673 DPRINTF("Allow the tracer to exit now\n"); 2674 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 2675 2676 DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 2677 TWAIT_REQUIRE_SUCCESS( 2678 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2679 2680 validate_status_exited(status, exitval_tracer); 2681 2682 DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 2683 TWAIT_REQUIRE_FAILURE(ECHILD, 2684 wpid = TWAIT_GENERIC(tracer, &status, 0)); 2685 2686 msg_close(&parent_tracee); 2687} 2688 2689ATF_TC(child_attach_to_its_parent); 2690ATF_TC_HEAD(child_attach_to_its_parent, tc) 2691{ 2692 atf_tc_set_md_var(tc, "descr", 2693 "Assert that tracer child can PT_ATTACH to its parent"); 2694} 2695 2696ATF_TC_BODY(child_attach_to_its_parent, tc) 2697{ 2698 2699 child_attach_to_its_parent(false); 2700} 2701 2702ATF_TC(child_attach_to_its_stopped_parent); 2703ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 2704{ 2705 atf_tc_set_md_var(tc, "descr", 2706 "Assert that tracer child can PT_ATTACH to its stopped parent"); 2707} 2708 2709ATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 2710{ 2711 /* 2712 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 2713 * this causes a pipe (established from atf-run) to be broken. 2714 * atf-run uses this mechanism to monitor whether a test is alive. 2715 * 2716 * As a workaround spawn this test as a subprocess. 2717 */ 2718 2719 const int exitval = 15; 2720 pid_t child, wpid; 2721#if defined(TWAIT_HAVE_STATUS) 2722 int status; 2723#endif 2724 2725 SYSCALL_REQUIRE((child = fork()) != -1); 2726 if (child == 0) { 2727 child_attach_to_its_parent(true); 2728 _exit(exitval); 2729 } else { 2730 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2731 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2732 2733 validate_status_exited(status, exitval); 2734 2735 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 2736 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2737 } 2738} 2739 2740/// ---------------------------------------------------------------------------- 2741 2742#if defined(TWAIT_HAVE_PID) 2743 2744enum tracee_sees_its_original_parent_type { 2745 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2746 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2747 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 2748}; 2749 2750static void 2751tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 2752{ 2753 struct msg_fds parent_tracer, parent_tracee; 2754 const int exitval_tracee = 5; 2755 const int exitval_tracer = 10; 2756 pid_t parent, tracee, tracer, wpid; 2757 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2758#if defined(TWAIT_HAVE_STATUS) 2759 int status; 2760#endif 2761 /* sysctl(3) - kinfo_proc2 */ 2762 int name[CTL_MAXNAME]; 2763 struct kinfo_proc2 kp; 2764 size_t len = sizeof(kp); 2765 unsigned int namelen; 2766 2767 /* procfs - status */ 2768 FILE *fp; 2769 struct stat st; 2770 const char *fname = "/proc/curproc/status"; 2771 char s_executable[MAXPATHLEN]; 2772 int s_pid, s_ppid; 2773 int rv; 2774 2775 if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 2776 SYSCALL_REQUIRE( 2777 (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 2778 if (rv != 0) 2779 atf_tc_skip("/proc/curproc/status not found"); 2780 } 2781 2782 DPRINTF("Spawn tracee\n"); 2783 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2784 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2785 tracee = atf_utils_fork(); 2786 if (tracee == 0) { 2787 parent = getppid(); 2788 2789 /* Emit message to the parent */ 2790 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 2791 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2792 2793 switch (type) { 2794 case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 2795 FORKEE_ASSERT_EQ(parent, getppid()); 2796 break; 2797 case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 2798 namelen = 0; 2799 name[namelen++] = CTL_KERN; 2800 name[namelen++] = KERN_PROC2; 2801 name[namelen++] = KERN_PROC_PID; 2802 name[namelen++] = getpid(); 2803 name[namelen++] = len; 2804 name[namelen++] = 1; 2805 2806 FORKEE_ASSERT_EQ( 2807 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2808 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 2809 break; 2810 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 2811 /* 2812 * Format: 2813 * EXECUTABLE PID PPID ... 2814 */ 2815 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 2816 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 2817 FORKEE_ASSERT_EQ(fclose(fp), 0); 2818 FORKEE_ASSERT_EQ(parent, s_ppid); 2819 break; 2820 } 2821 2822 _exit(exitval_tracee); 2823 } 2824 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 2825 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 2826 2827 DPRINTF("Spawn debugger\n"); 2828 tracer = atf_utils_fork(); 2829 if (tracer == 0) { 2830 /* No IPC to communicate with the child */ 2831 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2832 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2833 2834 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2835 FORKEE_REQUIRE_SUCCESS( 2836 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2837 2838 forkee_status_stopped(status, SIGSTOP); 2839 2840 /* Resume tracee with PT_CONTINUE */ 2841 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2842 2843 /* Inform parent that tracer has attached to tracee */ 2844 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2845 2846 /* Wait for parent to tell use that tracee should have exited */ 2847 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2848 2849 /* Wait for tracee and assert that it exited */ 2850 FORKEE_REQUIRE_SUCCESS( 2851 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2852 2853 forkee_status_exited(status, exitval_tracee); 2854 2855 DPRINTF("Before exiting of the tracer process\n"); 2856 _exit(exitval_tracer); 2857 } 2858 2859 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2860 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2861 2862 DPRINTF("Resume the tracee and let it exit\n"); 2863 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2864 2865 DPRINTF("Detect that tracee is zombie\n"); 2866 await_zombie(tracee); 2867 2868 DPRINTF("Assert that there is no status about tracee - " 2869 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 2870 TWAIT_REQUIRE_SUCCESS( 2871 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2872 2873 DPRINTF("Tell the tracer child should have exited\n"); 2874 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2875 2876 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 2877 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2878 tracer); 2879 2880 validate_status_exited(status, exitval_tracer); 2881 2882 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2883 TWAIT_FNAME); 2884 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 2885 tracee); 2886 2887 validate_status_exited(status, exitval_tracee); 2888 2889 msg_close(&parent_tracer); 2890 msg_close(&parent_tracee); 2891} 2892 2893#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 2894ATF_TC(test); \ 2895ATF_TC_HEAD(test, tc) \ 2896{ \ 2897 atf_tc_set_md_var(tc, "descr", \ 2898 "Assert that tracee sees its original parent when being traced " \ 2899 "(check " descr ")"); \ 2900} \ 2901 \ 2902ATF_TC_BODY(test, tc) \ 2903{ \ 2904 \ 2905 tracee_sees_its_original_parent(type); \ 2906} 2907 2908TRACEE_SEES_ITS_ORIGINAL_PARENT( 2909 tracee_sees_its_original_parent_getppid, 2910 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2911 "getppid(2)"); 2912TRACEE_SEES_ITS_ORIGINAL_PARENT( 2913 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 2914 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2915 "sysctl(3) and kinfo_proc2"); 2916TRACEE_SEES_ITS_ORIGINAL_PARENT( 2917 tracee_sees_its_original_parent_procfs_status, 2918 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 2919 "the status file in procfs"); 2920#endif 2921 2922/// ---------------------------------------------------------------------------- 2923 2924static void 2925eventmask_preserved(int event) 2926{ 2927 const int exitval = 5; 2928 const int sigval = SIGSTOP; 2929 pid_t child, wpid; 2930#if defined(TWAIT_HAVE_STATUS) 2931 int status; 2932#endif 2933 ptrace_event_t set_event, get_event; 2934 const int len = sizeof(ptrace_event_t); 2935 2936 DPRINTF("Before forking process PID=%d\n", getpid()); 2937 SYSCALL_REQUIRE((child = fork()) != -1); 2938 if (child == 0) { 2939 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2940 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2941 2942 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2943 FORKEE_ASSERT(raise(sigval) == 0); 2944 2945 DPRINTF("Before exiting of the child process\n"); 2946 _exit(exitval); 2947 } 2948 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2949 2950 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2951 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2952 2953 validate_status_stopped(status, sigval); 2954 2955 set_event.pe_set_event = event; 2956 SYSCALL_REQUIRE( 2957 ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 2958 SYSCALL_REQUIRE( 2959 ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 2960 DPRINTF("set_event=%#x get_event=%#x\n", set_event.pe_set_event, 2961 get_event.pe_set_event); 2962 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 2963 2964 DPRINTF("Before resuming the child process where it left off and " 2965 "without signal to be sent\n"); 2966 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2967 2968 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2969 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2970 2971 validate_status_exited(status, exitval); 2972 2973 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2974 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2975} 2976 2977#define EVENTMASK_PRESERVED(test, event) \ 2978ATF_TC(test); \ 2979ATF_TC_HEAD(test, tc) \ 2980{ \ 2981 atf_tc_set_md_var(tc, "descr", \ 2982 "Verify that eventmask " #event " is preserved"); \ 2983} \ 2984 \ 2985ATF_TC_BODY(test, tc) \ 2986{ \ 2987 \ 2988 eventmask_preserved(event); \ 2989} 2990 2991EVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 2992EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 2993EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 2994EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 2995EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 2996EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 2997EVENTMASK_PRESERVED(eventmask_preserved_posix_spawn, PTRACE_POSIX_SPAWN) 2998 2999/// ---------------------------------------------------------------------------- 3000 3001static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG}; 3002 3003static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER; 3004static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER; 3005static volatile size_t lwpinfo_thread_done; 3006 3007static void * 3008lwpinfo_thread(void *arg) 3009{ 3010 sigset_t s; 3011 volatile void **tcb; 3012 3013 tcb = (volatile void **)arg; 3014 3015 *tcb = _lwp_getprivate(); 3016 DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self()); 3017 3018 pthread_setname_np(pthread_self(), "thread %d", 3019 (void *)(intptr_t)_lwp_self()); 3020 3021 sigemptyset(&s); 3022 pthread_mutex_lock(&lwpinfo_thread_mtx); 3023 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 3024 lwpinfo_thread_done++; 3025 pthread_sigmask(SIG_BLOCK, &s, NULL); 3026 pthread_cond_signal(&lwpinfo_thread_cnd); 3027 pthread_mutex_unlock(&lwpinfo_thread_mtx); 3028 3029 return infinite_thread(NULL); 3030} 3031 3032static void 3033traceme_lwpinfo(const size_t threads, const char *iter) 3034{ 3035 const int sigval = SIGSTOP; 3036 const int sigval2 = SIGINT; 3037 pid_t child, wpid; 3038#if defined(TWAIT_HAVE_STATUS) 3039 int status; 3040#endif 3041 struct ptrace_lwpinfo lwp = {0, 0}; 3042 struct ptrace_lwpstatus lwpstatus = {0}; 3043 struct ptrace_siginfo info; 3044 void *private; 3045 char *name; 3046 char namebuf[PL_LNAMELEN]; 3047 volatile void *tcb[4]; 3048 bool found; 3049 sigset_t s; 3050 3051 /* Maximum number of supported threads in this test */ 3052 pthread_t t[__arraycount(tcb) - 1]; 3053 size_t n, m; 3054 int rv; 3055 size_t bytes_read; 3056 3057 struct ptrace_io_desc io; 3058 sigset_t sigmask; 3059 3060 ATF_REQUIRE(__arraycount(t) >= threads); 3061 memset(tcb, 0, sizeof(tcb)); 3062 3063 DPRINTF("Before forking process PID=%d\n", getpid()); 3064 SYSCALL_REQUIRE((child = fork()) != -1); 3065 if (child == 0) { 3066 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3067 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3068 3069 tcb[0] = _lwp_getprivate(); 3070 DPRINTF("Storing tcb[0] = %p\n", tcb[0]); 3071 3072 pthread_setname_np(pthread_self(), "thread %d", 3073 (void *)(intptr_t)_lwp_self()); 3074 3075 sigemptyset(&s); 3076 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 3077 pthread_sigmask(SIG_BLOCK, &s, NULL); 3078 3079 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3080 FORKEE_ASSERT(raise(sigval) == 0); 3081 3082 for (n = 0; n < threads; n++) { 3083 rv = pthread_create(&t[n], NULL, lwpinfo_thread, 3084 &tcb[n + 1]); 3085 FORKEE_ASSERT(rv == 0); 3086 } 3087 3088 pthread_mutex_lock(&lwpinfo_thread_mtx); 3089 while (lwpinfo_thread_done < threads) { 3090 pthread_cond_wait(&lwpinfo_thread_cnd, 3091 &lwpinfo_thread_mtx); 3092 } 3093 pthread_mutex_unlock(&lwpinfo_thread_mtx); 3094 3095 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 3096 FORKEE_ASSERT(raise(sigval2) == 0); 3097 3098 /* NOTREACHED */ 3099 FORKEE_ASSERTX(0 && "Not reached"); 3100 } 3101 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3102 3103 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3104 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3105 3106 validate_status_stopped(status, sigval); 3107 3108 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 3109 SYSCALL_REQUIRE( 3110 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3111 3112 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3113 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3114 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3115 info.psi_siginfo.si_errno); 3116 3117 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3118 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3119 3120 if (strstr(iter, "LWPINFO") != NULL) { 3121 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3122 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 3123 != -1); 3124 3125 DPRINTF("Assert that there exists a single thread only\n"); 3126 ATF_REQUIRE(lwp.pl_lwpid > 0); 3127 3128 DPRINTF("Assert that lwp thread %d received event " 3129 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 3130 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 3131 3132 if (strstr(iter, "LWPSTATUS") != NULL) { 3133 DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS " 3134 "for child\n"); 3135 lwpstatus.pl_lwpid = lwp.pl_lwpid; 3136 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus, 3137 sizeof(lwpstatus)) != -1); 3138 } 3139 3140 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3141 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 3142 != -1); 3143 3144 DPRINTF("Assert that there exists a single thread only\n"); 3145 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 3146 } else { 3147 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 3148 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 3149 sizeof(lwpstatus)) != -1); 3150 3151 DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid); 3152 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 3153 3154 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 3155 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 3156 sizeof(lwpstatus)) != -1); 3157 3158 DPRINTF("Assert that there exists a single thread only\n"); 3159 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 3160 } 3161 3162 DPRINTF("Before resuming the child process where it left off and " 3163 "without signal to be sent\n"); 3164 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3165 3166 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3167 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3168 3169 validate_status_stopped(status, sigval2); 3170 3171 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 3172 SYSCALL_REQUIRE( 3173 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3174 3175 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3176 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3177 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3178 info.psi_siginfo.si_errno); 3179 3180 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 3181 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3182 3183 memset(&lwp, 0, sizeof(lwp)); 3184 memset(&lwpstatus, 0, sizeof(lwpstatus)); 3185 3186 memset(&io, 0, sizeof(io)); 3187 3188 bytes_read = 0; 3189 io.piod_op = PIOD_READ_D; 3190 io.piod_len = sizeof(tcb); 3191 3192 do { 3193 io.piod_addr = (char *)&tcb + bytes_read; 3194 io.piod_offs = io.piod_addr; 3195 3196 rv = ptrace(PT_IO, child, &io, sizeof(io)); 3197 ATF_REQUIRE(rv != -1 && io.piod_len != 0); 3198 3199 bytes_read += io.piod_len; 3200 io.piod_len = sizeof(tcb) - bytes_read; 3201 } while (bytes_read < sizeof(tcb)); 3202 3203 for (n = 0; n <= threads; n++) { 3204 if (strstr(iter, "LWPINFO") != NULL) { 3205 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3206 "child\n"); 3207 SYSCALL_REQUIRE( 3208 ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3209 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3210 3211 DPRINTF("Assert that the thread exists\n"); 3212 ATF_REQUIRE(lwp.pl_lwpid > 0); 3213 3214 DPRINTF("Assert that lwp thread %d received expected " 3215 "event\n", lwp.pl_lwpid); 3216 FORKEE_ASSERT_EQ(lwp.pl_event, 3217 info.psi_lwpid == lwp.pl_lwpid ? 3218 PL_EVENT_SIGNAL : PL_EVENT_NONE); 3219 3220 if (strstr(iter, "LWPSTATUS") != NULL) { 3221 DPRINTF("Before calling ptrace(2) with " 3222 "PT_LWPSTATUS for child\n"); 3223 lwpstatus.pl_lwpid = lwp.pl_lwpid; 3224 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, 3225 &lwpstatus, sizeof(lwpstatus)) != -1); 3226 3227 goto check_lwpstatus; 3228 } 3229 } else { 3230 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for " 3231 "child\n"); 3232 SYSCALL_REQUIRE( 3233 ptrace(PT_LWPNEXT, child, &lwpstatus, 3234 sizeof(lwpstatus)) != -1); 3235 DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid); 3236 3237 DPRINTF("Assert that the thread exists\n"); 3238 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 3239 3240 check_lwpstatus: 3241 3242 if (strstr(iter, "pl_sigmask") != NULL) { 3243 sigmask = lwpstatus.pl_sigmask; 3244 3245 DPRINTF("Retrieved sigmask: " 3246 "%02x%02x%02x%02x\n", 3247 sigmask.__bits[0], sigmask.__bits[1], 3248 sigmask.__bits[2], sigmask.__bits[3]); 3249 3250 found = false; 3251 for (m = 0; 3252 m < __arraycount(lwpinfo_thread_sigmask); 3253 m++) { 3254 if (sigismember(&sigmask, 3255 lwpinfo_thread_sigmask[m])) { 3256 found = true; 3257 lwpinfo_thread_sigmask[m] = 0; 3258 break; 3259 } 3260 } 3261 ATF_REQUIRE(found == true); 3262 } else if (strstr(iter, "pl_name") != NULL) { 3263 name = lwpstatus.pl_name; 3264 3265 DPRINTF("Retrieved thread name: " 3266 "%s\n", name); 3267 3268 snprintf(namebuf, sizeof namebuf, "thread %d", 3269 lwpstatus.pl_lwpid); 3270 3271 ATF_REQUIRE(strcmp(name, namebuf) == 0); 3272 } else if (strstr(iter, "pl_private") != NULL) { 3273 private = lwpstatus.pl_private; 3274 3275 DPRINTF("Retrieved thread private pointer: " 3276 "%p\n", private); 3277 3278 found = false; 3279 for (m = 0; m < __arraycount(tcb); m++) { 3280 DPRINTF("Comparing %p and %p\n", 3281 private, tcb[m]); 3282 if (private == tcb[m]) { 3283 found = true; 3284 break; 3285 } 3286 } 3287 ATF_REQUIRE(found == true); 3288 } 3289 } 3290 } 3291 3292 if (strstr(iter, "LWPINFO") != NULL) { 3293 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3294 "child\n"); 3295 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 3296 != -1); 3297 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3298 3299 DPRINTF("Assert that there are no more threads\n"); 3300 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 3301 } else { 3302 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 3303 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 3304 sizeof(lwpstatus)) != -1); 3305 3306 DPRINTF("Assert that there exists a single thread only\n"); 3307 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 3308 } 3309 3310 DPRINTF("Before resuming the child process where it left off and " 3311 "without signal to be sent\n"); 3312 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 3313 3314 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3315 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3316 3317 validate_status_signaled(status, SIGKILL, 0); 3318 3319 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3320 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3321} 3322 3323#define TRACEME_LWPINFO(test, threads, iter) \ 3324ATF_TC(test); \ 3325ATF_TC_HEAD(test, tc) \ 3326{ \ 3327 atf_tc_set_md_var(tc, "descr", \ 3328 "Verify " iter " with the child with " #threads \ 3329 " spawned extra threads"); \ 3330} \ 3331 \ 3332ATF_TC_BODY(test, tc) \ 3333{ \ 3334 \ 3335 traceme_lwpinfo(threads, iter); \ 3336} 3337 3338TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO") 3339TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO") 3340TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO") 3341TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO") 3342 3343TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS") 3344TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS") 3345TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS") 3346TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS") 3347 3348TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0, 3349 "LWPINFO+LWPSTATUS+pl_sigmask") 3350TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1, 3351 "LWPINFO+LWPSTATUS+pl_sigmask") 3352TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2, 3353 "LWPINFO+LWPSTATUS+pl_sigmask") 3354TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3, 3355 "LWPINFO+LWPSTATUS+pl_sigmask") 3356 3357TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0, 3358 "LWPINFO+LWPSTATUS+pl_name") 3359TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1, 3360 "LWPINFO+LWPSTATUS+pl_name") 3361TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2, 3362 "LWPINFO+LWPSTATUS+pl_name") 3363TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3, 3364 "LWPINFO+LWPSTATUS+pl_name") 3365 3366TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0, 3367 "LWPINFO+LWPSTATUS+pl_private") 3368TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1, 3369 "LWPINFO+LWPSTATUS+pl_private") 3370TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2, 3371 "LWPINFO+LWPSTATUS+pl_private") 3372TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3, 3373 "LWPINFO+LWPSTATUS+pl_private") 3374 3375TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT") 3376TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT") 3377TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT") 3378TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT") 3379 3380TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask") 3381TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask") 3382TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask") 3383TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask") 3384 3385TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name") 3386TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name") 3387TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name") 3388TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name") 3389 3390TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private") 3391TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private") 3392TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private") 3393TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private") 3394 3395/// ---------------------------------------------------------------------------- 3396 3397#if defined(TWAIT_HAVE_PID) 3398static void 3399attach_lwpinfo(const int threads) 3400{ 3401 const int sigval = SIGINT; 3402 struct msg_fds parent_tracee, parent_tracer; 3403 const int exitval_tracer = 10; 3404 pid_t tracee, tracer, wpid; 3405 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 3406#if defined(TWAIT_HAVE_STATUS) 3407 int status; 3408#endif 3409 struct ptrace_lwpinfo lwp = {0, 0}; 3410 struct ptrace_siginfo info; 3411 3412 /* Maximum number of supported threads in this test */ 3413 pthread_t t[3]; 3414 int n, rv; 3415 3416 DPRINTF("Spawn tracee\n"); 3417 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 3418 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 3419 tracee = atf_utils_fork(); 3420 if (tracee == 0) { 3421 /* Wait for message from the parent */ 3422 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 3423 3424 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 3425 3426 for (n = 0; n < threads; n++) { 3427 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 3428 FORKEE_ASSERT(rv == 0); 3429 } 3430 3431 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 3432 3433 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3434 FORKEE_ASSERT(raise(sigval) == 0); 3435 3436 /* NOTREACHED */ 3437 FORKEE_ASSERTX(0 && "Not reached"); 3438 } 3439 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 3440 3441 DPRINTF("Spawn debugger\n"); 3442 tracer = atf_utils_fork(); 3443 if (tracer == 0) { 3444 /* No IPC to communicate with the child */ 3445 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 3446 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 3447 3448 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 3449 FORKEE_REQUIRE_SUCCESS( 3450 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3451 3452 forkee_status_stopped(status, SIGSTOP); 3453 3454 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3455 "tracee"); 3456 FORKEE_ASSERT( 3457 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3458 3459 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3460 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3461 "si_errno=%#x\n", 3462 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3463 info.psi_siginfo.si_errno); 3464 3465 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 3466 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 3467 3468 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3469 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3470 != -1); 3471 3472 DPRINTF("Assert that there exists a thread\n"); 3473 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 3474 3475 DPRINTF("Assert that lwp thread %d received event " 3476 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 3477 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 3478 3479 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3480 "tracee\n"); 3481 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3482 != -1); 3483 3484 DPRINTF("Assert that there are no more lwp threads in " 3485 "tracee\n"); 3486 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 3487 3488 /* Resume tracee with PT_CONTINUE */ 3489 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3490 3491 /* Inform parent that tracer has attached to tracee */ 3492 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 3493 3494 /* Wait for parent */ 3495 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 3496 3497 /* Wait for tracee and assert that it raised a signal */ 3498 FORKEE_REQUIRE_SUCCESS( 3499 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3500 3501 forkee_status_stopped(status, SIGINT); 3502 3503 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3504 "child"); 3505 FORKEE_ASSERT( 3506 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3507 3508 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3509 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3510 "si_errno=%#x\n", 3511 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3512 info.psi_siginfo.si_errno); 3513 3514 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 3515 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 3516 3517 memset(&lwp, 0, sizeof(lwp)); 3518 3519 for (n = 0; n <= threads; n++) { 3520 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3521 "child\n"); 3522 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 3523 sizeof(lwp)) != -1); 3524 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3525 3526 DPRINTF("Assert that the thread exists\n"); 3527 FORKEE_ASSERT(lwp.pl_lwpid > 0); 3528 3529 DPRINTF("Assert that lwp thread %d received expected " 3530 "event\n", lwp.pl_lwpid); 3531 FORKEE_ASSERT_EQ(lwp.pl_event, 3532 info.psi_lwpid == lwp.pl_lwpid ? 3533 PL_EVENT_SIGNAL : PL_EVENT_NONE); 3534 } 3535 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3536 "tracee\n"); 3537 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3538 != -1); 3539 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3540 3541 DPRINTF("Assert that there are no more threads\n"); 3542 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 3543 3544 DPRINTF("Before resuming the child process where it left off " 3545 "and without signal to be sent\n"); 3546 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 3547 != -1); 3548 3549 /* Wait for tracee and assert that it exited */ 3550 FORKEE_REQUIRE_SUCCESS( 3551 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3552 3553 forkee_status_signaled(status, SIGKILL, 0); 3554 3555 DPRINTF("Before exiting of the tracer process\n"); 3556 _exit(exitval_tracer); 3557 } 3558 3559 DPRINTF("Wait for the tracer to attach to the tracee\n"); 3560 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 3561 3562 DPRINTF("Resume the tracee and spawn threads\n"); 3563 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 3564 3565 DPRINTF("Resume the tracee and let it exit\n"); 3566 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 3567 3568 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 3569 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 3570 3571 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 3572 TWAIT_FNAME); 3573 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 3574 tracer); 3575 3576 validate_status_exited(status, exitval_tracer); 3577 3578 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 3579 TWAIT_FNAME); 3580 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 3581 tracee); 3582 3583 validate_status_signaled(status, SIGKILL, 0); 3584 3585 msg_close(&parent_tracer); 3586 msg_close(&parent_tracee); 3587} 3588 3589#define ATTACH_LWPINFO(test, threads) \ 3590ATF_TC(test); \ 3591ATF_TC_HEAD(test, tc) \ 3592{ \ 3593 atf_tc_set_md_var(tc, "descr", \ 3594 "Verify LWPINFO with the child with " #threads \ 3595 " spawned extra threads (tracer is not the original " \ 3596 "parent)"); \ 3597} \ 3598 \ 3599ATF_TC_BODY(test, tc) \ 3600{ \ 3601 \ 3602 attach_lwpinfo(threads); \ 3603} 3604 3605ATTACH_LWPINFO(attach_lwpinfo0, 0) 3606ATTACH_LWPINFO(attach_lwpinfo1, 1) 3607ATTACH_LWPINFO(attach_lwpinfo2, 2) 3608ATTACH_LWPINFO(attach_lwpinfo3, 3) 3609#endif 3610 3611/// ---------------------------------------------------------------------------- 3612 3613static void 3614ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 3615{ 3616 const int exitval = 5; 3617 const int sigval = SIGINT; 3618 const int sigfaked = SIGTRAP; 3619 const int sicodefaked = TRAP_BRKPT; 3620 pid_t child, wpid; 3621 struct sigaction sa; 3622#if defined(TWAIT_HAVE_STATUS) 3623 int status; 3624#endif 3625 struct ptrace_siginfo info; 3626 memset(&info, 0, sizeof(info)); 3627 3628 DPRINTF("Before forking process PID=%d\n", getpid()); 3629 SYSCALL_REQUIRE((child = fork()) != -1); 3630 if (child == 0) { 3631 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3632 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3633 3634 sa.sa_sigaction = sah; 3635 sa.sa_flags = SA_SIGINFO; 3636 sigemptyset(&sa.sa_mask); 3637 3638 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 3639 != -1); 3640 3641 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3642 FORKEE_ASSERT(raise(sigval) == 0); 3643 3644 FORKEE_ASSERT_EQ(*signal_caught, 1); 3645 3646 DPRINTF("Before exiting of the child process\n"); 3647 _exit(exitval); 3648 } 3649 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3650 3651 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3652 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3653 3654 validate_status_stopped(status, sigval); 3655 3656 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3657 SYSCALL_REQUIRE( 3658 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3659 3660 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3661 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3662 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3663 info.psi_siginfo.si_errno); 3664 3665 if (faked) { 3666 DPRINTF("Before setting new faked signal to signo=%d " 3667 "si_code=%d\n", sigfaked, sicodefaked); 3668 info.psi_siginfo.si_signo = sigfaked; 3669 info.psi_siginfo.si_code = sicodefaked; 3670 } 3671 3672 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 3673 SYSCALL_REQUIRE( 3674 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 3675 3676 if (faked) { 3677 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3678 "child\n"); 3679 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 3680 sizeof(info)) != -1); 3681 3682 DPRINTF("Before checking siginfo_t\n"); 3683 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 3684 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 3685 } 3686 3687 DPRINTF("Before resuming the child process where it left off and " 3688 "without signal to be sent\n"); 3689 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 3690 faked ? sigfaked : sigval) != -1); 3691 3692 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3693 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3694 3695 validate_status_exited(status, exitval); 3696 3697 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3698 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3699} 3700 3701#define PTRACE_SIGINFO(test, faked) \ 3702ATF_TC(test); \ 3703ATF_TC_HEAD(test, tc) \ 3704{ \ 3705 atf_tc_set_md_var(tc, "descr", \ 3706 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 3707 "with%s setting signal to new value", faked ? "" : "out"); \ 3708} \ 3709 \ 3710static int test##_caught = 0; \ 3711 \ 3712static void \ 3713test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 3714{ \ 3715 if (faked) { \ 3716 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 3717 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 3718 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 3719 } else { \ 3720 FORKEE_ASSERT_EQ(sig, SIGINT); \ 3721 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 3722 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 3723 } \ 3724 \ 3725 ++ test##_caught; \ 3726} \ 3727 \ 3728ATF_TC_BODY(test, tc) \ 3729{ \ 3730 \ 3731 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 3732} 3733 3734PTRACE_SIGINFO(siginfo_set_unmodified, false) 3735PTRACE_SIGINFO(siginfo_set_faked, true) 3736 3737/// ---------------------------------------------------------------------------- 3738 3739static void 3740traceme_exec(bool masked, bool ignored) 3741{ 3742 const int sigval = SIGTRAP; 3743 pid_t child, wpid; 3744#if defined(TWAIT_HAVE_STATUS) 3745 int status; 3746#endif 3747 struct sigaction sa; 3748 struct ptrace_siginfo info; 3749 sigset_t intmask; 3750 struct kinfo_proc2 kp; 3751 size_t len = sizeof(kp); 3752 3753 int name[6]; 3754 const size_t namelen = __arraycount(name); 3755 ki_sigset_t kp_sigmask; 3756 ki_sigset_t kp_sigignore; 3757 3758 memset(&info, 0, sizeof(info)); 3759 3760 DPRINTF("Before forking process PID=%d\n", getpid()); 3761 SYSCALL_REQUIRE((child = fork()) != -1); 3762 if (child == 0) { 3763 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3764 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3765 3766 if (masked) { 3767 sigemptyset(&intmask); 3768 sigaddset(&intmask, sigval); 3769 sigprocmask(SIG_BLOCK, &intmask, NULL); 3770 } 3771 3772 if (ignored) { 3773 memset(&sa, 0, sizeof(sa)); 3774 sa.sa_handler = SIG_IGN; 3775 sigemptyset(&sa.sa_mask); 3776 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 3777 } 3778 3779 DPRINTF("Before calling execve(2) from child\n"); 3780 execlp("/bin/echo", "/bin/echo", NULL); 3781 3782 FORKEE_ASSERT(0 && "Not reached"); 3783 } 3784 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3785 3786 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3787 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3788 3789 validate_status_stopped(status, sigval); 3790 3791 name[0] = CTL_KERN, 3792 name[1] = KERN_PROC2, 3793 name[2] = KERN_PROC_PID; 3794 name[3] = getpid(); 3795 name[4] = sizeof(kp); 3796 name[5] = 1; 3797 3798 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 3799 3800 if (masked) 3801 kp_sigmask = kp.p_sigmask; 3802 3803 if (ignored) 3804 kp_sigignore = kp.p_sigignore; 3805 3806 name[3] = getpid(); 3807 3808 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 3809 3810 if (masked) { 3811 DPRINTF("kp_sigmask=" 3812 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 3813 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 3814 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 3815 3816 DPRINTF("kp.p_sigmask=" 3817 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 3818 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 3819 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 3820 3821 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 3822 sizeof(kp_sigmask))); 3823 } 3824 3825 if (ignored) { 3826 DPRINTF("kp_sigignore=" 3827 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 3828 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 3829 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 3830 3831 DPRINTF("kp.p_sigignore=" 3832 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 3833 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 3834 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 3835 3836 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 3837 sizeof(kp_sigignore))); 3838 } 3839 3840 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3841 SYSCALL_REQUIRE( 3842 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3843 3844 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3845 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3846 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3847 info.psi_siginfo.si_errno); 3848 3849 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3850 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 3851 3852 DPRINTF("Before resuming the child process where it left off and " 3853 "without signal to be sent\n"); 3854 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3855 3856 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3857 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3858 3859 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3860 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3861} 3862 3863#define TRACEME_EXEC(test, masked, ignored) \ 3864ATF_TC(test); \ 3865ATF_TC_HEAD(test, tc) \ 3866{ \ 3867 atf_tc_set_md_var(tc, "descr", \ 3868 "Detect SIGTRAP TRAP_EXEC from " \ 3869 "child%s%s", masked ? " with masked signal" : "", \ 3870 masked ? " with ignored signal" : ""); \ 3871} \ 3872 \ 3873ATF_TC_BODY(test, tc) \ 3874{ \ 3875 \ 3876 traceme_exec(masked, ignored); \ 3877} 3878 3879TRACEME_EXEC(traceme_exec, false, false) 3880TRACEME_EXEC(traceme_signalmasked_exec, true, false) 3881TRACEME_EXEC(traceme_signalignored_exec, false, true) 3882 3883/// ---------------------------------------------------------------------------- 3884 3885#define TRACE_THREADS_NUM 100 3886 3887static volatile int done; 3888pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 3889 3890static void * 3891trace_threads_cb(void *arg __unused) 3892{ 3893 3894 pthread_mutex_lock(&trace_threads_mtx); 3895 done++; 3896 pthread_mutex_unlock(&trace_threads_mtx); 3897 3898 while (done < TRACE_THREADS_NUM) 3899 sched_yield(); 3900 3901 return NULL; 3902} 3903 3904static void 3905trace_threads(bool trace_create, bool trace_exit, bool masked) 3906{ 3907 const int sigval = SIGSTOP; 3908 pid_t child, wpid; 3909#if defined(TWAIT_HAVE_STATUS) 3910 int status; 3911#endif 3912 ptrace_state_t state; 3913 const int slen = sizeof(state); 3914 ptrace_event_t event; 3915 const int elen = sizeof(event); 3916 struct ptrace_siginfo info; 3917 3918 sigset_t intmask; 3919 3920 pthread_t t[TRACE_THREADS_NUM]; 3921 int rv; 3922 size_t n; 3923 lwpid_t lid; 3924 3925 /* Track created and exited threads */ 3926 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 3927 3928 DPRINTF("Before forking process PID=%d\n", getpid()); 3929 SYSCALL_REQUIRE((child = fork()) != -1); 3930 if (child == 0) { 3931 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3932 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3933 3934 if (masked) { 3935 sigemptyset(&intmask); 3936 sigaddset(&intmask, SIGTRAP); 3937 sigprocmask(SIG_BLOCK, &intmask, NULL); 3938 } 3939 3940 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3941 FORKEE_ASSERT(raise(sigval) == 0); 3942 3943 for (n = 0; n < __arraycount(t); n++) { 3944 rv = pthread_create(&t[n], NULL, trace_threads_cb, 3945 NULL); 3946 FORKEE_ASSERT(rv == 0); 3947 } 3948 3949 for (n = 0; n < __arraycount(t); n++) { 3950 rv = pthread_join(t[n], NULL); 3951 FORKEE_ASSERT(rv == 0); 3952 } 3953 3954 /* 3955 * There is race between _exit() and pthread_join() detaching 3956 * a thread. For simplicity kill the process after detecting 3957 * LWP events. 3958 */ 3959 while (true) 3960 continue; 3961 3962 FORKEE_ASSERT(0 && "Not reached"); 3963 } 3964 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3965 3966 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3967 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3968 3969 validate_status_stopped(status, sigval); 3970 3971 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3972 SYSCALL_REQUIRE( 3973 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3974 3975 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3976 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3977 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3978 info.psi_siginfo.si_errno); 3979 3980 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3981 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3982 3983 DPRINTF("Set LWP event mask for the child %d\n", child); 3984 memset(&event, 0, sizeof(event)); 3985 if (trace_create) 3986 event.pe_set_event |= PTRACE_LWP_CREATE; 3987 if (trace_exit) 3988 event.pe_set_event |= PTRACE_LWP_EXIT; 3989 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3990 3991 DPRINTF("Before resuming the child process where it left off and " 3992 "without signal to be sent\n"); 3993 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3994 3995 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 3996 DPRINTF("Before calling %s() for the child - expected stopped " 3997 "SIGTRAP\n", TWAIT_FNAME); 3998 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3999 child); 4000 4001 validate_status_stopped(status, SIGTRAP); 4002 4003 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4004 "child\n"); 4005 SYSCALL_REQUIRE( 4006 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4007 4008 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4009 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4010 "si_errno=%#x\n", 4011 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4012 info.psi_siginfo.si_errno); 4013 4014 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4015 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 4016 4017 SYSCALL_REQUIRE( 4018 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4019 4020 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 4021 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 4022 4023 lid = state.pe_lwp; 4024 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 4025 4026 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 4027 4028 DPRINTF("Before resuming the child process where it left off " 4029 "and without signal to be sent\n"); 4030 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4031 } 4032 4033 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 4034 DPRINTF("Before calling %s() for the child - expected stopped " 4035 "SIGTRAP\n", TWAIT_FNAME); 4036 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4037 child); 4038 4039 validate_status_stopped(status, SIGTRAP); 4040 4041 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4042 "child\n"); 4043 SYSCALL_REQUIRE( 4044 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4045 4046 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4047 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4048 "si_errno=%#x\n", 4049 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4050 info.psi_siginfo.si_errno); 4051 4052 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4053 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 4054 4055 SYSCALL_REQUIRE( 4056 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4057 4058 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 4059 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 4060 4061 lid = state.pe_lwp; 4062 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 4063 4064 if (trace_create) { 4065 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 4066 ATF_REQUIRE_EQ(*count, 1); 4067 *count = 0; 4068 } 4069 4070 DPRINTF("Before resuming the child process where it left off " 4071 "and without signal to be sent\n"); 4072 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4073 } 4074 4075 kill(child, SIGKILL); 4076 4077 DPRINTF("Before calling %s() for the child - expected exited\n", 4078 TWAIT_FNAME); 4079 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4080 4081 validate_status_signaled(status, SIGKILL, 0); 4082 4083 DPRINTF("Before calling %s() for the child - expected no process\n", 4084 TWAIT_FNAME); 4085 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4086} 4087 4088#define TRACE_THREADS(test, trace_create, trace_exit, mask) \ 4089ATF_TC(test); \ 4090ATF_TC_HEAD(test, tc) \ 4091{ \ 4092 atf_tc_set_md_var(tc, "descr", \ 4093 "Verify spawning threads with%s tracing LWP create and" \ 4094 "with%s tracing LWP exit", trace_create ? "" : "out", \ 4095 trace_exit ? "" : "out"); \ 4096} \ 4097 \ 4098ATF_TC_BODY(test, tc) \ 4099{ \ 4100 \ 4101 trace_threads(trace_create, trace_exit, mask); \ 4102} 4103 4104TRACE_THREADS(trace_thread_nolwpevents, false, false, false) 4105TRACE_THREADS(trace_thread_lwpexit, false, true, false) 4106TRACE_THREADS(trace_thread_lwpcreate, true, false, false) 4107TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false) 4108 4109TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true) 4110TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true) 4111TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true) 4112 4113/// ---------------------------------------------------------------------------- 4114 4115ATF_TC(signal_mask_unrelated); 4116ATF_TC_HEAD(signal_mask_unrelated, tc) 4117{ 4118 atf_tc_set_md_var(tc, "descr", 4119 "Verify that masking single unrelated signal does not stop tracer " 4120 "from catching other signals"); 4121} 4122 4123ATF_TC_BODY(signal_mask_unrelated, tc) 4124{ 4125 const int exitval = 5; 4126 const int sigval = SIGSTOP; 4127 const int sigmasked = SIGTRAP; 4128 const int signotmasked = SIGINT; 4129 pid_t child, wpid; 4130#if defined(TWAIT_HAVE_STATUS) 4131 int status; 4132#endif 4133 sigset_t intmask; 4134 4135 DPRINTF("Before forking process PID=%d\n", getpid()); 4136 SYSCALL_REQUIRE((child = fork()) != -1); 4137 if (child == 0) { 4138 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4139 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4140 4141 sigemptyset(&intmask); 4142 sigaddset(&intmask, sigmasked); 4143 sigprocmask(SIG_BLOCK, &intmask, NULL); 4144 4145 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4146 FORKEE_ASSERT(raise(sigval) == 0); 4147 4148 DPRINTF("Before raising %s from child\n", 4149 strsignal(signotmasked)); 4150 FORKEE_ASSERT(raise(signotmasked) == 0); 4151 4152 DPRINTF("Before exiting of the child process\n"); 4153 _exit(exitval); 4154 } 4155 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4156 4157 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4158 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4159 4160 validate_status_stopped(status, sigval); 4161 4162 DPRINTF("Before resuming the child process where it left off and " 4163 "without signal to be sent\n"); 4164 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4165 4166 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4167 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4168 4169 validate_status_stopped(status, signotmasked); 4170 4171 DPRINTF("Before resuming the child process where it left off and " 4172 "without signal to be sent\n"); 4173 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4174 4175 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4176 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4177 4178 validate_status_exited(status, exitval); 4179 4180 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4181 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4182} 4183 4184/// ---------------------------------------------------------------------------- 4185 4186static void * 4187thread_and_exec_thread_cb(void *arg __unused) 4188{ 4189 4190 execlp("/bin/echo", "/bin/echo", NULL); 4191 4192 abort(); 4193} 4194 4195static void 4196threads_and_exec(void) 4197{ 4198 const int sigval = SIGSTOP; 4199 pid_t child, wpid; 4200#if defined(TWAIT_HAVE_STATUS) 4201 int status; 4202#endif 4203 ptrace_state_t state; 4204 const int slen = sizeof(state); 4205 ptrace_event_t event; 4206 const int elen = sizeof(event); 4207 struct ptrace_siginfo info; 4208 4209 pthread_t t; 4210 lwpid_t lid; 4211 4212 DPRINTF("Before forking process PID=%d\n", getpid()); 4213 SYSCALL_REQUIRE((child = fork()) != -1); 4214 if (child == 0) { 4215 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4216 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4217 4218 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4219 FORKEE_ASSERT(raise(sigval) == 0); 4220 4221 FORKEE_ASSERT(pthread_create(&t, NULL, 4222 thread_and_exec_thread_cb, NULL) == 0); 4223 4224 for (;;) 4225 continue; 4226 4227 FORKEE_ASSERT(0 && "Not reached"); 4228 } 4229 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4230 4231 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4232 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4233 4234 validate_status_stopped(status, sigval); 4235 4236 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4237 SYSCALL_REQUIRE( 4238 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4239 4240 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4241 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4242 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4243 info.psi_siginfo.si_errno); 4244 4245 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4246 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4247 4248 DPRINTF("Set LWP event mask for the child %d\n", child); 4249 memset(&event, 0, sizeof(event)); 4250 event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; 4251 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4252 4253 DPRINTF("Before resuming the child process where it left off and " 4254 "without signal to be sent\n"); 4255 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4256 4257 DPRINTF("Before calling %s() for the child - expected stopped " 4258 "SIGTRAP\n", TWAIT_FNAME); 4259 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4260 child); 4261 4262 validate_status_stopped(status, SIGTRAP); 4263 4264 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4265 "child\n"); 4266 SYSCALL_REQUIRE( 4267 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4268 4269 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4270 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4271 "si_errno=%#x\n", 4272 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4273 info.psi_siginfo.si_errno); 4274 4275 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4276 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 4277 4278 SYSCALL_REQUIRE( 4279 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4280 4281 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 4282 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 4283 4284 lid = state.pe_lwp; 4285 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 4286 4287 DPRINTF("Before resuming the child process where it left off " 4288 "and without signal to be sent\n"); 4289 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4290 4291 DPRINTF("Before calling %s() for the child - expected stopped " 4292 "SIGTRAP\n", TWAIT_FNAME); 4293 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4294 child); 4295 4296 validate_status_stopped(status, SIGTRAP); 4297 4298 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4299 "child\n"); 4300 SYSCALL_REQUIRE( 4301 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4302 4303 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4304 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4305 "si_errno=%#x\n", 4306 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4307 info.psi_siginfo.si_errno); 4308 4309 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4310 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 4311 4312 SYSCALL_REQUIRE( 4313 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4314 4315 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 4316 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 4317 4318 lid = state.pe_lwp; 4319 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 4320 4321 DPRINTF("Before resuming the child process where it left off " 4322 "and without signal to be sent\n"); 4323 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4324 4325 DPRINTF("Before calling %s() for the child - expected stopped " 4326 "SIGTRAP\n", TWAIT_FNAME); 4327 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4328 child); 4329 4330 validate_status_stopped(status, SIGTRAP); 4331 4332 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4333 "child\n"); 4334 SYSCALL_REQUIRE( 4335 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4336 4337 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4338 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4339 "si_errno=%#x\n", 4340 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4341 info.psi_siginfo.si_errno); 4342 4343 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4344 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4345 4346 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 4347 4348 DPRINTF("Before calling %s() for the child - expected exited\n", 4349 TWAIT_FNAME); 4350 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4351 4352 validate_status_signaled(status, SIGKILL, 0); 4353 4354 DPRINTF("Before calling %s() for the child - expected no process\n", 4355 TWAIT_FNAME); 4356 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4357} 4358 4359ATF_TC(threads_and_exec); 4360ATF_TC_HEAD(threads_and_exec, tc) 4361{ 4362 atf_tc_set_md_var(tc, "descr", 4363 "Verify that multithreaded application on exec() will report " 4364 "LWP_EXIT events"); 4365} 4366 4367ATF_TC_BODY(threads_and_exec, tc) 4368{ 4369 4370 threads_and_exec(); 4371} 4372 4373/// ---------------------------------------------------------------------------- 4374 4375ATF_TC(suspend_no_deadlock); 4376ATF_TC_HEAD(suspend_no_deadlock, tc) 4377{ 4378 atf_tc_set_md_var(tc, "descr", 4379 "Verify that the while the only thread within a process is " 4380 "suspended, the whole process cannot be unstopped"); 4381} 4382 4383ATF_TC_BODY(suspend_no_deadlock, tc) 4384{ 4385 const int exitval = 5; 4386 const int sigval = SIGSTOP; 4387 pid_t child, wpid; 4388#if defined(TWAIT_HAVE_STATUS) 4389 int status; 4390#endif 4391 struct ptrace_siginfo psi; 4392 4393 DPRINTF("Before forking process PID=%d\n", getpid()); 4394 SYSCALL_REQUIRE((child = fork()) != -1); 4395 if (child == 0) { 4396 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4397 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4398 4399 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4400 FORKEE_ASSERT(raise(sigval) == 0); 4401 4402 DPRINTF("Before exiting of the child process\n"); 4403 _exit(exitval); 4404 } 4405 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4406 4407 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4408 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4409 4410 validate_status_stopped(status, sigval); 4411 4412 DPRINTF("Before reading siginfo and lwpid_t\n"); 4413 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 4414 4415 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 4416 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 4417 4418 DPRINTF("Before resuming the child process where it left off and " 4419 "without signal to be sent\n"); 4420 ATF_REQUIRE_ERRNO(EDEADLK, 4421 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 4422 4423 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 4424 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 4425 4426 DPRINTF("Before resuming the child process where it left off and " 4427 "without signal to be sent\n"); 4428 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4429 4430 DPRINTF("Before calling %s() for the child - expected exited\n", 4431 TWAIT_FNAME); 4432 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4433 4434 validate_status_exited(status, exitval); 4435 4436 DPRINTF("Before calling %s() for the child - expected no process\n", 4437 TWAIT_FNAME); 4438 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4439} 4440 4441/// ---------------------------------------------------------------------------- 4442 4443static pthread_barrier_t barrier1_resume; 4444static pthread_barrier_t barrier2_resume; 4445 4446static void * 4447resume_thread(void *arg) 4448{ 4449 4450 raise(SIGUSR1); 4451 4452 pthread_barrier_wait(&barrier1_resume); 4453 4454 /* Debugger will suspend the process here */ 4455 4456 pthread_barrier_wait(&barrier2_resume); 4457 4458 raise(SIGUSR2); 4459 4460 return infinite_thread(arg); 4461} 4462 4463ATF_TC(resume); 4464ATF_TC_HEAD(resume, tc) 4465{ 4466 atf_tc_set_md_var(tc, "descr", 4467 "Verify that a thread can be suspended by a debugger and later " 4468 "resumed by the debugger"); 4469} 4470 4471ATF_TC_BODY(resume, tc) 4472{ 4473 const int sigval = SIGSTOP; 4474 pid_t child, wpid; 4475#if defined(TWAIT_HAVE_STATUS) 4476 int status; 4477#endif 4478 lwpid_t lid; 4479 struct ptrace_siginfo psi; 4480 pthread_t t; 4481 4482 DPRINTF("Before forking process PID=%d\n", getpid()); 4483 SYSCALL_REQUIRE((child = fork()) != -1); 4484 if (child == 0) { 4485 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4486 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4487 4488 pthread_barrier_init(&barrier1_resume, NULL, 2); 4489 pthread_barrier_init(&barrier2_resume, NULL, 2); 4490 4491 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4492 FORKEE_ASSERT(raise(sigval) == 0); 4493 4494 DPRINTF("Before creating new thread in child\n"); 4495 FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0); 4496 4497 pthread_barrier_wait(&barrier1_resume); 4498 4499 pthread_barrier_wait(&barrier2_resume); 4500 4501 infinite_thread(NULL); 4502 } 4503 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4504 4505 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4506 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4507 4508 validate_status_stopped(status, sigval); 4509 4510 DPRINTF("Before resuming the child process where it left off and " 4511 "without signal to be sent\n"); 4512 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4513 4514 DPRINTF("Before calling %s() for the child - expected stopped " 4515 "SIGUSR1\n", TWAIT_FNAME); 4516 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4517 4518 validate_status_stopped(status, SIGUSR1); 4519 4520 DPRINTF("Before reading siginfo and lwpid_t\n"); 4521 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 4522 4523 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 4524 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 4525 4526 lid = psi.psi_lwpid; 4527 4528 DPRINTF("Before resuming the child process where it left off and " 4529 "without signal to be sent\n"); 4530 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4531 4532 DPRINTF("Before suspending the parent for 1 second, we expect no signals\n"); 4533 SYSCALL_REQUIRE(sleep(1) == 0); 4534 4535#if defined(TWAIT_HAVE_OPTIONS) 4536 DPRINTF("Before calling %s() for the child - expected no status\n", 4537 TWAIT_FNAME); 4538 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0); 4539#endif 4540 4541 DPRINTF("Before resuming the child process where it left off and " 4542 "without signal to be sent\n"); 4543 SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1); 4544 4545 DPRINTF("Before calling %s() for the child - expected stopped " 4546 "SIGSTOP\n", TWAIT_FNAME); 4547 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4548 4549 validate_status_stopped(status, SIGSTOP); 4550 4551 DPRINTF("Before resuming LWP %d\n", lid); 4552 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1); 4553 4554 DPRINTF("Before resuming the child process where it left off and " 4555 "without signal to be sent\n"); 4556 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4557 4558 DPRINTF("Before calling %s() for the child - expected stopped " 4559 "SIGUSR2\n", TWAIT_FNAME); 4560 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4561 4562 validate_status_stopped(status, SIGUSR2); 4563 4564 DPRINTF("Before resuming the child process where it left off and " 4565 "without signal to be sent\n"); 4566 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 4567 4568 DPRINTF("Before calling %s() for the child - expected exited\n", 4569 TWAIT_FNAME); 4570 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4571 4572 validate_status_signaled(status, SIGKILL, 0); 4573 4574 DPRINTF("Before calling %s() for the child - expected no process\n", 4575 TWAIT_FNAME); 4576 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4577} 4578 4579/// ---------------------------------------------------------------------------- 4580 4581static void 4582user_va0_disable(int operation) 4583{ 4584 pid_t child, wpid; 4585#if defined(TWAIT_HAVE_STATUS) 4586 int status; 4587#endif 4588 const int sigval = SIGSTOP; 4589 int rv; 4590 4591 struct ptrace_siginfo info; 4592 4593 if (get_user_va0_disable() == 0) 4594 atf_tc_skip("vm.user_va0_disable is set to 0"); 4595 4596 memset(&info, 0, sizeof(info)); 4597 4598 DPRINTF("Before forking process PID=%d\n", getpid()); 4599 SYSCALL_REQUIRE((child = fork()) != -1); 4600 if (child == 0) { 4601 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4602 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4603 4604 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4605 FORKEE_ASSERT(raise(sigval) == 0); 4606 4607 /* NOTREACHED */ 4608 FORKEE_ASSERTX(0 && "This shall not be reached"); 4609 __unreachable(); 4610 } 4611 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4612 4613 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4614 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4615 4616 validate_status_stopped(status, sigval); 4617 4618 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4619 "child\n"); 4620 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 4621 sizeof(info)) != -1); 4622 4623 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4624 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4625 "si_errno=%#x\n", 4626 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4627 info.psi_siginfo.si_errno); 4628 4629 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4630 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4631 4632 DPRINTF("Before resuming the child process in PC=0x0 " 4633 "and without signal to be sent\n"); 4634 errno = 0; 4635 rv = ptrace(operation, child, (void *)0, 0); 4636 ATF_REQUIRE_EQ(errno, EINVAL); 4637 ATF_REQUIRE_EQ(rv, -1); 4638 4639 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 4640 4641 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4642 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4643 validate_status_signaled(status, SIGKILL, 0); 4644 4645 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4646 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4647} 4648 4649#define USER_VA0_DISABLE(test, operation) \ 4650ATF_TC(test); \ 4651ATF_TC_HEAD(test, tc) \ 4652{ \ 4653 atf_tc_set_md_var(tc, "descr", \ 4654 "Verify behavior of " #operation " with PC set to 0x0"); \ 4655} \ 4656 \ 4657ATF_TC_BODY(test, tc) \ 4658{ \ 4659 \ 4660 user_va0_disable(operation); \ 4661} 4662 4663USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 4664USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 4665USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 4666 4667/// ---------------------------------------------------------------------------- 4668 4669/* 4670 * Parse the core file and find the requested note. If the reading or parsing 4671 * fails, the test is failed. If the note is found, it is read onto buf, up to 4672 * buf_len. The actual length of the note is returned (which can be greater 4673 * than buf_len, indicating that it has been truncated). If the note is not 4674 * found, -1 is returned. 4675 * 4676 * If the note_name ends in '*', then we find the first note that matches 4677 * the note_name prefix up to the '*' character, e.g.: 4678 * 4679 * NetBSD-CORE@* 4680 * 4681 * finds the first note whose name prefix matches "NetBSD-CORE@". 4682 */ 4683static ssize_t core_find_note(const char *core_path, 4684 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 4685{ 4686 int core_fd; 4687 Elf *core_elf; 4688 size_t core_numhdr, i; 4689 ssize_t ret = -1; 4690 size_t name_len = strlen(note_name); 4691 bool prefix_match = false; 4692 4693 if (note_name[name_len - 1] == '*') { 4694 prefix_match = true; 4695 name_len--; 4696 } else { 4697 /* note: we assume note name will be null-terminated */ 4698 name_len++; 4699 } 4700 4701 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 4702 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 4703 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 4704 4705 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 4706 for (i = 0; i < core_numhdr && ret == -1; i++) { 4707 GElf_Phdr core_hdr; 4708 size_t offset; 4709 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 4710 if (core_hdr.p_type != PT_NOTE) 4711 continue; 4712 4713 for (offset = core_hdr.p_offset; 4714 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 4715 Elf64_Nhdr note_hdr; 4716 char name_buf[64]; 4717 4718 switch (gelf_getclass(core_elf)) { 4719 case ELFCLASS64: 4720 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 4721 sizeof(note_hdr), offset) 4722 == sizeof(note_hdr)); 4723 offset += sizeof(note_hdr); 4724 break; 4725 case ELFCLASS32: 4726 { 4727 Elf32_Nhdr tmp_hdr; 4728 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 4729 sizeof(tmp_hdr), offset) 4730 == sizeof(tmp_hdr)); 4731 offset += sizeof(tmp_hdr); 4732 note_hdr.n_namesz = tmp_hdr.n_namesz; 4733 note_hdr.n_descsz = tmp_hdr.n_descsz; 4734 note_hdr.n_type = tmp_hdr.n_type; 4735 } 4736 break; 4737 } 4738 4739 /* indicates end of notes */ 4740 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 4741 break; 4742 if (((prefix_match && 4743 note_hdr.n_namesz > name_len) || 4744 (!prefix_match && 4745 note_hdr.n_namesz == name_len)) && 4746 note_hdr.n_namesz <= sizeof(name_buf)) { 4747 SYSCALL_REQUIRE(pread(core_fd, name_buf, 4748 note_hdr.n_namesz, offset) 4749 == (ssize_t)(size_t)note_hdr.n_namesz); 4750 4751 if (!strncmp(note_name, name_buf, name_len) && 4752 note_hdr.n_type == note_type) 4753 ret = note_hdr.n_descsz; 4754 } 4755 4756 offset += note_hdr.n_namesz; 4757 /* fix to alignment */ 4758 offset = roundup(offset, core_hdr.p_align); 4759 4760 /* if name & type matched above */ 4761 if (ret != -1) { 4762 ssize_t read_len = MIN(buf_len, 4763 note_hdr.n_descsz); 4764 SYSCALL_REQUIRE(pread(core_fd, buf, 4765 read_len, offset) == read_len); 4766 break; 4767 } 4768 4769 offset += note_hdr.n_descsz; 4770 /* fix to alignment */ 4771 offset = roundup(offset, core_hdr.p_align); 4772 } 4773 } 4774 4775 elf_end(core_elf); 4776 close(core_fd); 4777 4778 return ret; 4779} 4780 4781ATF_TC(core_dump_procinfo); 4782ATF_TC_HEAD(core_dump_procinfo, tc) 4783{ 4784 atf_tc_set_md_var(tc, "descr", 4785 "Trigger a core dump and verify its contents."); 4786} 4787 4788ATF_TC_BODY(core_dump_procinfo, tc) 4789{ 4790 const int exitval = 5; 4791 pid_t child, wpid; 4792#if defined(TWAIT_HAVE_STATUS) 4793 const int sigval = SIGTRAP; 4794 int status; 4795#endif 4796 char core_path[] = "/tmp/core.XXXXXX"; 4797 int core_fd; 4798 struct netbsd_elfcore_procinfo procinfo; 4799 4800 DPRINTF("Before forking process PID=%d\n", getpid()); 4801 SYSCALL_REQUIRE((child = fork()) != -1); 4802 if (child == 0) { 4803 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4804 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4805 4806 DPRINTF("Before triggering SIGTRAP\n"); 4807 trigger_trap(); 4808 4809 DPRINTF("Before exiting of the child process\n"); 4810 _exit(exitval); 4811 } 4812 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4813 4814 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4815 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4816 4817 validate_status_stopped(status, sigval); 4818 4819 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 4820 close(core_fd); 4821 4822 DPRINTF("Call DUMPCORE for the child process\n"); 4823 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 4824 != -1); 4825 4826 DPRINTF("Read core file\n"); 4827 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 4828 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 4829 sizeof(procinfo)); 4830 4831 ATF_CHECK_EQ(procinfo.cpi_version, 1); 4832 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 4833 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 4834 ATF_CHECK_EQ(procinfo.cpi_pid, child); 4835 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 4836 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 4837 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 4838 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 4839 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 4840 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 4841 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 4842 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 4843 ATF_CHECK(procinfo.cpi_siglwp > 0); 4844 4845 unlink(core_path); 4846 4847 DPRINTF("Before resuming the child process where it left off and " 4848 "without signal to be sent\n"); 4849 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4850 4851 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4852 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4853 4854 validate_status_exited(status, exitval); 4855 4856 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4857 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4858} 4859 4860/// ---------------------------------------------------------------------------- 4861 4862#if defined(TWAIT_HAVE_STATUS) 4863 4864#define THREAD_CONCURRENT_BREAKPOINT_NUM 50 4865#define THREAD_CONCURRENT_SIGNALS_NUM 50 4866#define THREAD_CONCURRENT_WATCHPOINT_NUM 50 4867 4868/* List of signals to use for the test */ 4869const int thread_concurrent_signals_list[] = { 4870 SIGIO, 4871 SIGXCPU, 4872 SIGXFSZ, 4873 SIGVTALRM, 4874 SIGPROF, 4875 SIGWINCH, 4876 SIGINFO, 4877 SIGUSR1, 4878 SIGUSR2 4879}; 4880 4881enum thread_concurrent_signal_handling { 4882 /* the signal is discarded by debugger */ 4883 TCSH_DISCARD, 4884 /* the handler is set to SIG_IGN */ 4885 TCSH_SIG_IGN, 4886 /* an actual handler is used */ 4887 TCSH_HANDLER 4888}; 4889 4890static pthread_barrier_t thread_concurrent_barrier; 4891static pthread_key_t thread_concurrent_key; 4892static uint32_t thread_concurrent_watchpoint_var = 0; 4893 4894static void * 4895thread_concurrent_breakpoint_thread(void *arg) 4896{ 4897 static volatile int watchme = 1; 4898 pthread_barrier_wait(&thread_concurrent_barrier); 4899 DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self()); 4900 check_happy(watchme); 4901 return NULL; 4902} 4903 4904static void 4905thread_concurrent_sig_handler(int sig) 4906{ 4907 void *tls_val = pthread_getspecific(thread_concurrent_key); 4908 DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 4909 FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key, 4910 (void*)((uintptr_t)tls_val + 1)) == 0); 4911} 4912 4913static void * 4914thread_concurrent_signals_thread(void *arg) 4915{ 4916 int sigval = thread_concurrent_signals_list[ 4917 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 4918 enum thread_concurrent_signal_handling *signal_handle = arg; 4919 void *tls_val; 4920 4921 pthread_barrier_wait(&thread_concurrent_barrier); 4922 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 4923 _lwp_self()); 4924 pthread_kill(pthread_self(), sigval); 4925 if (*signal_handle == TCSH_HANDLER) { 4926 tls_val = pthread_getspecific(thread_concurrent_key); 4927 DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 4928 FORKEE_ASSERT(tls_val == (void*)1); 4929 } 4930 return NULL; 4931} 4932 4933static void * 4934thread_concurrent_watchpoint_thread(void *arg) 4935{ 4936 pthread_barrier_wait(&thread_concurrent_barrier); 4937 DPRINTF("Before modifying var from LWP %d\n", _lwp_self()); 4938 thread_concurrent_watchpoint_var = 1; 4939 return NULL; 4940} 4941 4942#if defined(__i386__) || defined(__x86_64__) 4943enum thread_concurrent_sigtrap_event { 4944 TCSE_UNKNOWN, 4945 TCSE_BREAKPOINT, 4946 TCSE_WATCHPOINT 4947}; 4948 4949static void 4950thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid); 4951static enum thread_concurrent_sigtrap_event 4952thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info); 4953#endif 4954 4955static void 4956thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle, 4957 int breakpoint_threads, int signal_threads, int watchpoint_threads) 4958{ 4959 const int exitval = 5; 4960 const int sigval = SIGSTOP; 4961 pid_t child, wpid; 4962 int status; 4963 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 4964 = {{0, 0}}; 4965 struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 4966 = {{0, 0}}; 4967 struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 4968 = {{0, 0}}; 4969 ptrace_event_t event; 4970 int i; 4971 4972#if defined(HAVE_DBREGS) 4973 if (!can_we_set_dbregs()) { 4974 atf_tc_skip("Either run this test as root or set sysctl(3) " 4975 "security.models.extensions.user_set_dbregs to 1"); 4976 } 4977#endif 4978 4979 atf_tc_skip("PR kern/54960"); 4980 4981 /* Protect against out-of-bounds array access. */ 4982 ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM); 4983 ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM); 4984 ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM); 4985 4986 DPRINTF("Before forking process PID=%d\n", getpid()); 4987 SYSCALL_REQUIRE((child = fork()) != -1); 4988 if (child == 0) { 4989 pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM]; 4990 pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM]; 4991 pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM]; 4992 4993 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4994 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4995 4996 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4997 FORKEE_ASSERT(raise(sigval) == 0); 4998 4999 if (signal_handle != TCSH_DISCARD) { 5000 struct sigaction sa; 5001 unsigned int j; 5002 5003 memset(&sa, 0, sizeof(sa)); 5004 if (signal_handle == TCSH_SIG_IGN) 5005 sa.sa_handler = SIG_IGN; 5006 else 5007 sa.sa_handler = thread_concurrent_sig_handler; 5008 sigemptyset(&sa.sa_mask); 5009 5010 for (j = 0; 5011 j < __arraycount(thread_concurrent_signals_list); 5012 j++) 5013 FORKEE_ASSERT(sigaction( 5014 thread_concurrent_signals_list[j], &sa, NULL) 5015 != -1); 5016 } 5017 5018 DPRINTF("Before starting threads from the child\n"); 5019 FORKEE_ASSERT(pthread_barrier_init( 5020 &thread_concurrent_barrier, NULL, 5021 breakpoint_threads + signal_threads + watchpoint_threads) 5022 == 0); 5023 FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL) 5024 == 0); 5025 5026 for (i = 0; i < signal_threads; i++) { 5027 FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL, 5028 thread_concurrent_signals_thread, 5029 &signal_handle) == 0); 5030 } 5031 for (i = 0; i < breakpoint_threads; i++) { 5032 FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL, 5033 thread_concurrent_breakpoint_thread, NULL) == 0); 5034 } 5035 for (i = 0; i < watchpoint_threads; i++) { 5036 FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL, 5037 thread_concurrent_watchpoint_thread, NULL) == 0); 5038 } 5039 5040 DPRINTF("Before joining threads from the child\n"); 5041 for (i = 0; i < watchpoint_threads; i++) { 5042 FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0); 5043 } 5044 for (i = 0; i < breakpoint_threads; i++) { 5045 FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0); 5046 } 5047 for (i = 0; i < signal_threads; i++) { 5048 FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0); 5049 } 5050 5051 FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0); 5052 FORKEE_ASSERT(pthread_barrier_destroy( 5053 &thread_concurrent_barrier) == 0); 5054 5055 DPRINTF("Before exiting of the child process\n"); 5056 _exit(exitval); 5057 } 5058 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5059 5060 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5061 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5062 5063 validate_status_stopped(status, sigval); 5064 5065 DPRINTF("Set LWP event mask for the child process\n"); 5066 memset(&event, 0, sizeof(event)); 5067 event.pe_set_event |= PTRACE_LWP_CREATE; 5068 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event)) 5069 != -1); 5070 5071 DPRINTF("Before resuming the child process where it left off\n"); 5072 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5073 5074 DPRINTF("Before entering signal collection loop\n"); 5075 while (1) { 5076 ptrace_siginfo_t info; 5077 5078 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5079 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5080 child); 5081 if (WIFEXITED(status)) 5082 break; 5083 /* Note: we use validate_status_stopped() to get nice error 5084 * message. Signal is irrelevant since it won't be reached. 5085 */ 5086 else if (!WIFSTOPPED(status)) 5087 validate_status_stopped(status, 0); 5088 5089 DPRINTF("Before calling PT_GET_SIGINFO\n"); 5090 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 5091 sizeof(info)) != -1); 5092 5093 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 5094 info.psi_siginfo.si_signo, info.psi_lwpid, 5095 WSTOPSIG(status)); 5096 5097 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status), 5098 "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid, 5099 WSTOPSIG(status), info.psi_siginfo.si_signo); 5100 5101 if (WSTOPSIG(status) != SIGTRAP) { 5102 int expected_sig = 5103 thread_concurrent_signals_list[info.psi_lwpid % 5104 __arraycount(thread_concurrent_signals_list)]; 5105 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 5106 "lwp=%d, expected %d, got %d", info.psi_lwpid, 5107 expected_sig, WSTOPSIG(status)); 5108 5109 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 5110 } else if (info.psi_siginfo.si_code == TRAP_LWP) { 5111#if defined(__i386__) || defined(__x86_64__) 5112 thread_concurrent_lwp_setup(child, info.psi_lwpid); 5113#endif 5114 } else { 5115#if defined(__i386__) || defined(__x86_64__) 5116 switch (thread_concurrent_handle_sigtrap(child, &info)) { 5117 case TCSE_UNKNOWN: 5118 /* already reported inside the function */ 5119 break; 5120 case TCSE_BREAKPOINT: 5121 *FIND_EVENT_COUNT(bp_counts, 5122 info.psi_lwpid) += 1; 5123 break; 5124 case TCSE_WATCHPOINT: 5125 *FIND_EVENT_COUNT(wp_counts, 5126 info.psi_lwpid) += 1; 5127 break; 5128 } 5129#else 5130 ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n", 5131 info.psi_siginfo.si_code); 5132#endif 5133 } 5134 5135 DPRINTF("Before resuming the child process\n"); 5136 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 5137 signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP 5138 ? WSTOPSIG(status) : 0) != -1); 5139 } 5140 5141 for (i = 0; i < signal_threads; i++) 5142 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 5143 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 5144 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 5145 for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++) 5146 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0, 5147 "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d", 5148 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 5149 5150 for (i = 0; i < breakpoint_threads; i++) 5151 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1, 5152 "bp_counts[%d].lec_count=%d; lec_lwp=%d", 5153 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 5154 for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++) 5155 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0, 5156 "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d", 5157 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 5158 5159 for (i = 0; i < watchpoint_threads; i++) 5160 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1, 5161 "wp_counts[%d].lec_count=%d; lec_lwp=%d", 5162 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 5163 for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++) 5164 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0, 5165 "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d", 5166 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 5167 5168 validate_status_exited(status, exitval); 5169} 5170 5171#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr) \ 5172ATF_TC(test); \ 5173ATF_TC_HEAD(test, tc) \ 5174{ \ 5175 atf_tc_set_md_var(tc, "descr", descr); \ 5176} \ 5177 \ 5178ATF_TC_BODY(test, tc) \ 5179{ \ 5180 thread_concurrent_test(sig_hdl, bps, sigs, wps); \ 5181} 5182 5183THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD, 5184 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 5185 "Verify that concurrent signals issued to a single thread are reported " 5186 "correctly"); 5187THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN, 5188 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 5189 "Verify that concurrent signals issued to a single thread are reported " 5190 "correctly and passed back to SIG_IGN handler"); 5191THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER, 5192 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 5193 "Verify that concurrent signals issued to a single thread are reported " 5194 "correctly and passed back to a handler function"); 5195 5196#if defined(__i386__) || defined(__x86_64__) 5197THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD, 5198 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0, 5199 "Verify that concurrent breakpoints are reported correctly"); 5200THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD, 5201 0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 5202 "Verify that concurrent breakpoints are reported correctly"); 5203THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD, 5204 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 5205 "Verify that concurrent breakpoints and watchpoints are reported " 5206 "correctly"); 5207 5208THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD, 5209 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 5210 "Verify that concurrent breakpoints and signals are reported correctly"); 5211THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN, 5212 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 5213 "Verify that concurrent breakpoints and signals are reported correctly " 5214 "and passed back to SIG_IGN handler"); 5215THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER, 5216 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 5217 "Verify that concurrent breakpoints and signals are reported correctly " 5218 "and passed back to a handler function"); 5219 5220THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD, 5221 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 5222 "Verify that concurrent watchpoints and signals are reported correctly"); 5223THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN, 5224 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 5225 "Verify that concurrent watchpoints and signals are reported correctly " 5226 "and passed back to SIG_IGN handler"); 5227THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER, 5228 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 5229 "Verify that concurrent watchpoints and signals are reported correctly " 5230 "and passed back to a handler function"); 5231 5232THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD, 5233 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 5234 THREAD_CONCURRENT_WATCHPOINT_NUM, 5235 "Verify that concurrent breakpoints, watchpoints and signals are reported " 5236 "correctly"); 5237THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN, 5238 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 5239 THREAD_CONCURRENT_WATCHPOINT_NUM, 5240 "Verify that concurrent breakpoints, watchpoints and signals are reported " 5241 "correctly and passed back to SIG_IGN handler"); 5242THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER, 5243 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 5244 THREAD_CONCURRENT_WATCHPOINT_NUM, 5245 "Verify that concurrent breakpoints, watchpoints and signals are reported " 5246 "correctly and passed back to a handler function"); 5247#endif 5248 5249#endif /*defined(TWAIT_HAVE_STATUS)*/ 5250 5251/// ---------------------------------------------------------------------------- 5252 5253#include "t_ptrace_register_wait.h" 5254#include "t_ptrace_syscall_wait.h" 5255#include "t_ptrace_step_wait.h" 5256#include "t_ptrace_kill_wait.h" 5257#include "t_ptrace_bytetransfer_wait.h" 5258#include "t_ptrace_clone_wait.h" 5259#include "t_ptrace_fork_wait.h" 5260 5261/// ---------------------------------------------------------------------------- 5262 5263#include "t_ptrace_amd64_wait.h" 5264#include "t_ptrace_i386_wait.h" 5265#include "t_ptrace_x86_wait.h" 5266 5267/// ---------------------------------------------------------------------------- 5268 5269#else 5270ATF_TC(dummy); 5271ATF_TC_HEAD(dummy, tc) 5272{ 5273 atf_tc_set_md_var(tc, "descr", "A dummy test"); 5274} 5275 5276ATF_TC_BODY(dummy, tc) 5277{ 5278 5279 // Dummy, skipped 5280 // The ATF framework requires at least a single defined test. 5281} 5282#endif 5283 5284ATF_TP_ADD_TCS(tp) 5285{ 5286 setvbuf(stdout, NULL, _IONBF, 0); 5287 setvbuf(stderr, NULL, _IONBF, 0); 5288 5289#ifdef ENABLE_TESTS 5290 ATF_TP_ADD_TC(tp, traceme_raise1); 5291 ATF_TP_ADD_TC(tp, traceme_raise2); 5292 ATF_TP_ADD_TC(tp, traceme_raise3); 5293 ATF_TP_ADD_TC(tp, traceme_raise4); 5294 ATF_TP_ADD_TC(tp, traceme_raise5); 5295 ATF_TP_ADD_TC(tp, traceme_raise6); 5296 ATF_TP_ADD_TC(tp, traceme_raise7); 5297 ATF_TP_ADD_TC(tp, traceme_raise8); 5298 ATF_TP_ADD_TC(tp, traceme_raise9); 5299 ATF_TP_ADD_TC(tp, traceme_raise10); 5300 5301 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 5302 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 5303 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 5304 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 5305 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 5306 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 5307 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 5308 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 5309 5310 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 5311 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 5312 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 5313 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 5314 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 5315 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 5316 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 5317 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 5318 5319 ATF_TP_ADD_TC(tp, traceme_crash_trap); 5320 ATF_TP_ADD_TC(tp, traceme_crash_segv); 5321 ATF_TP_ADD_TC(tp, traceme_crash_ill); 5322 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 5323 ATF_TP_ADD_TC(tp, traceme_crash_bus); 5324 5325 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 5326 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 5327 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 5328 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 5329 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 5330 5331 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 5332 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 5333 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 5334 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 5335 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 5336 5337 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 5338 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 5339 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 5340 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 5341 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 5342 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 5343 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 5344 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 5345 5346 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 5347 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 5348 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 5349 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 5350 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 5351 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 5352 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 5353 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 5354 5355 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 5356 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 5357 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 5358 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 5359 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 5360 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 5361 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 5362 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 5363 5364 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 5365 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 5366 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 5367 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 5368 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 5369 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 5370 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 5371 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 5372 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 5373 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 5374 5375 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 5376 5377 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 5378 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 5379 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 5380 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 5381 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 5382 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 5383 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 5384 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 5385 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 5386 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 5387 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 5388 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 5389 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 5390 5391 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 5392 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 5393 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 5394 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 5395 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 5396 5397 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 5398 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 5399 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 5400 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 5401 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 5402 5403 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 5404 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 5405 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 5406 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 5407 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 5408 5409 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 5410 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 5411 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 5412 5413 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 5414 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 5415 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 5416 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 5417 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 5418 5419 ATF_TP_ADD_TC_HAVE_PID(tp, 5420 unrelated_tracer_sees_signalmasked_crash_trap); 5421 ATF_TP_ADD_TC_HAVE_PID(tp, 5422 unrelated_tracer_sees_signalmasked_crash_segv); 5423 ATF_TP_ADD_TC_HAVE_PID(tp, 5424 unrelated_tracer_sees_signalmasked_crash_ill); 5425 ATF_TP_ADD_TC_HAVE_PID(tp, 5426 unrelated_tracer_sees_signalmasked_crash_fpe); 5427 ATF_TP_ADD_TC_HAVE_PID(tp, 5428 unrelated_tracer_sees_signalmasked_crash_bus); 5429 5430 ATF_TP_ADD_TC_HAVE_PID(tp, 5431 unrelated_tracer_sees_signalignored_crash_trap); 5432 ATF_TP_ADD_TC_HAVE_PID(tp, 5433 unrelated_tracer_sees_signalignored_crash_segv); 5434 ATF_TP_ADD_TC_HAVE_PID(tp, 5435 unrelated_tracer_sees_signalignored_crash_ill); 5436 ATF_TP_ADD_TC_HAVE_PID(tp, 5437 unrelated_tracer_sees_signalignored_crash_fpe); 5438 ATF_TP_ADD_TC_HAVE_PID(tp, 5439 unrelated_tracer_sees_signalignored_crash_bus); 5440 5441 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 5442 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 5443 ATF_TP_ADD_TC_HAVE_PID(tp, 5444 unrelated_tracer_sees_terminaton_before_the_parent); 5445 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 5446 5447 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 5448 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 5449 5450 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 5451 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 5452 5453 ATF_TP_ADD_TC_HAVE_PID(tp, 5454 tracee_sees_its_original_parent_getppid); 5455 ATF_TP_ADD_TC_HAVE_PID(tp, 5456 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 5457 ATF_TP_ADD_TC_HAVE_PID(tp, 5458 tracee_sees_its_original_parent_procfs_status); 5459 5460 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 5461 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 5462 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 5463 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 5464 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 5465 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 5466 ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn); 5467 5468 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 5469 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 5470 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 5471 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 5472 5473 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 5474 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 5475 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 5476 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 5477 5478 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 5479 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 5480 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 5481 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 5482 5483 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 5484 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 5485 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 5486 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 5487 5488 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 5489 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 5490 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 5491 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 5492 5493 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 5494 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 5495 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 5496 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 5497 5498 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 5499 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 5500 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 5501 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 5502 5503 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 5504 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 5505 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 5506 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 5507 5508 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 5509 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 5510 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 5511 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 5512 5513 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 5514 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 5515 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 5516 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 5517 5518 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 5519 5520 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); 5521 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); 5522 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); 5523 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); 5524 5525 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); 5526 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); 5527 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); 5528 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); 5529 5530 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); 5531 5532 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); 5533 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); 5534 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); 5535 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); 5536 5537 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); 5538 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); 5539 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); 5540 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d); 5541 5542 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 5543 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 5544 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 5545 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 5546 5547 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus); 5548 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus); 5549 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus); 5550 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus); 5551 5552 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask); 5553 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask); 5554 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask); 5555 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask); 5556 5557 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name); 5558 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name); 5559 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name); 5560 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name); 5561 5562 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private); 5563 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private); 5564 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private); 5565 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private); 5566 5567 ATF_TP_ADD_TC(tp, traceme_lwpnext0); 5568 ATF_TP_ADD_TC(tp, traceme_lwpnext1); 5569 ATF_TP_ADD_TC(tp, traceme_lwpnext2); 5570 ATF_TP_ADD_TC(tp, traceme_lwpnext3); 5571 5572 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask); 5573 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask); 5574 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask); 5575 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask); 5576 5577 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name); 5578 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name); 5579 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name); 5580 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name); 5581 5582 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private); 5583 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private); 5584 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private); 5585 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private); 5586 5587 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 5588 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 5589 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 5590 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 5591 5592 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 5593 ATF_TP_ADD_TC(tp, siginfo_set_faked); 5594 5595 ATF_TP_ADD_TC(tp, traceme_exec); 5596 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 5597 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 5598 5599 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 5600 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 5601 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 5602 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 5603 5604 ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap); 5605 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap); 5606 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap); 5607 5608 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 5609 5610 ATF_TP_ADD_TC(tp, threads_and_exec); 5611 5612 ATF_TP_ADD_TC(tp, suspend_no_deadlock); 5613 5614 ATF_TP_ADD_TC(tp, resume); 5615 5616 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 5617 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 5618 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 5619 5620 ATF_TP_ADD_TC(tp, core_dump_procinfo); 5621 5622#if defined(TWAIT_HAVE_STATUS) 5623 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 5624 ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign); 5625 ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler); 5626#if defined(__i386__) || defined(__x86_64__) 5627 ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints); 5628 ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints); 5629 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp); 5630 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig); 5631 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign); 5632 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler); 5633 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig); 5634 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign); 5635 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler); 5636 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig); 5637 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign); 5638 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler); 5639#endif 5640#endif 5641 5642 ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER(); 5643 ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL(); 5644 ATF_TP_ADD_TCS_PTRACE_WAIT_STEP(); 5645 ATF_TP_ADD_TCS_PTRACE_WAIT_KILL(); 5646 ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER(); 5647 ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE(); 5648 ATF_TP_ADD_TCS_PTRACE_WAIT_FORK(); 5649 5650 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 5651 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 5652 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 5653 5654#else 5655 ATF_TP_ADD_TC(tp, dummy); 5656#endif 5657 5658 return atf_no_error(); 5659} 5660