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