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