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