t_ptrace_wait.c revision 1.95
1/* $NetBSD: t_ptrace_wait.c,v 1.95 2019/02/20 09:25:11 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.95 2019/02/20 09:25:11 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, bool masked, bool ignored) 1826{ 1827 const int sigval = SIGSTOP; 1828 struct msg_fds parent_tracee, parent_tracer; 1829 const int exitval = 10; 1830 pid_t tracee, tracer, wpid; 1831 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1832#if defined(TWAIT_HAVE_STATUS) 1833 int status; 1834#endif 1835 struct sigaction sa; 1836 struct ptrace_siginfo info; 1837 sigset_t intmask; 1838 struct kinfo_proc2 kp; 1839 size_t len = sizeof(kp); 1840 1841 int name[6]; 1842 const size_t namelen = __arraycount(name); 1843 ki_sigset_t kp_sigmask; 1844 ki_sigset_t kp_sigignore; 1845 1846#ifndef PTRACE_ILLEGAL_ASM 1847 if (sig == SIGILL) 1848 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1849#endif 1850 1851 memset(&info, 0, sizeof(info)); 1852 1853 if (masked || ignored) 1854 atf_tc_expect_fail("Unexpected sigmask reset on crash under " 1855 "debugger"); 1856 1857 DPRINTF("Spawn tracee\n"); 1858 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1859 tracee = atf_utils_fork(); 1860 if (tracee == 0) { 1861 // Wait for parent to let us crash 1862 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 1863 1864 if (masked) { 1865 sigemptyset(&intmask); 1866 sigaddset(&intmask, sig); 1867 sigprocmask(SIG_BLOCK, &intmask, NULL); 1868 } 1869 1870 if (ignored) { 1871 memset(&sa, 0, sizeof(sa)); 1872 sa.sa_handler = SIG_IGN; 1873 sigemptyset(&sa.sa_mask); 1874 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 1875 } 1876 1877 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1878 FORKEE_ASSERT(raise(sigval) == 0); 1879 1880 DPRINTF("Before executing a trap\n"); 1881 switch (sig) { 1882 case SIGTRAP: 1883 trigger_trap(); 1884 break; 1885 case SIGSEGV: 1886 trigger_segv(); 1887 break; 1888 case SIGILL: 1889 trigger_ill(); 1890 break; 1891 case SIGFPE: 1892 trigger_fpe(); 1893 break; 1894 case SIGBUS: 1895 trigger_bus(); 1896 break; 1897 default: 1898 /* NOTREACHED */ 1899 FORKEE_ASSERTX(0 && "This shall not be reached"); 1900 } 1901 1902 /* NOTREACHED */ 1903 FORKEE_ASSERTX(0 && "This shall not be reached"); 1904 } 1905 1906 DPRINTF("Spawn debugger\n"); 1907 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 1908 tracer = atf_utils_fork(); 1909 if (tracer == 0) { 1910 /* Fork again and drop parent to reattach to PID 1 */ 1911 tracer = atf_utils_fork(); 1912 if (tracer != 0) 1913 _exit(exitval); 1914 1915 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 1916 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 1917 1918 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 1919 FORKEE_REQUIRE_SUCCESS( 1920 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1921 1922 forkee_status_stopped(status, SIGSTOP); 1923 1924 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 1925 "traced process\n"); 1926 SYSCALL_REQUIRE( 1927 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1928 1929 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1930 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1931 "si_errno=%#x\n", info.psi_siginfo.si_signo, 1932 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 1933 1934 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 1935 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 1936 1937 /* Resume tracee with PT_CONTINUE */ 1938 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1939 1940 /* Inform parent that tracer has attached to tracee */ 1941 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 1942 1943 /* Wait for parent to tell use that tracee should have exited */ 1944 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 1945 1946 /* Wait for tracee and assert that it exited */ 1947 FORKEE_REQUIRE_SUCCESS( 1948 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1949 1950 forkee_status_stopped(status, sigval); 1951 1952 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 1953 "traced process\n"); 1954 SYSCALL_REQUIRE( 1955 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1956 1957 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1958 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1959 "si_errno=%#x\n", info.psi_siginfo.si_signo, 1960 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 1961 1962 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 1963 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 1964 1965 name[0] = CTL_KERN, 1966 name[1] = KERN_PROC2, 1967 name[2] = KERN_PROC_PID; 1968 name[3] = tracee; 1969 name[4] = sizeof(kp); 1970 name[5] = 1; 1971 1972 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1973 1974 if (masked) 1975 kp_sigmask = kp.p_sigmask; 1976 1977 if (ignored) 1978 kp_sigignore = kp.p_sigignore; 1979 1980 /* Resume tracee with PT_CONTINUE */ 1981 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1982 1983 /* Wait for tracee and assert that it exited */ 1984 FORKEE_REQUIRE_SUCCESS( 1985 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1986 1987 forkee_status_stopped(status, sig); 1988 1989 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 1990 "traced process\n"); 1991 SYSCALL_REQUIRE( 1992 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1993 1994 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1995 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1996 "si_errno=%#x\n", info.psi_siginfo.si_signo, 1997 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 1998 1999 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig); 2000 2001 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2002 2003 if (masked) { 2004 DPRINTF("kp_sigmask=" 2005 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2006 PRIx32 "\n", 2007 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 2008 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 2009 2010 DPRINTF("kp.p_sigmask=" 2011 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2012 PRIx32 "\n", 2013 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 2014 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 2015 2016 FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask, 2017 sizeof(kp_sigmask))); 2018 } 2019 2020 if (ignored) { 2021 DPRINTF("kp_sigignore=" 2022 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2023 PRIx32 "\n", 2024 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 2025 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 2026 2027 DPRINTF("kp.p_sigignore=" 2028 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2029 PRIx32 "\n", 2030 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 2031 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 2032 2033 FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore, 2034 sizeof(kp_sigignore))); 2035 } 2036 2037 switch (sig) { 2038 case SIGTRAP: 2039 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 2040 break; 2041 case SIGSEGV: 2042 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 2043 break; 2044 case SIGILL: 2045 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 2046 break; 2047 case SIGFPE: 2048 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 2049 break; 2050 case SIGBUS: 2051 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 2052 break; 2053 } 2054 2055 FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 2056 DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 2057 FORKEE_REQUIRE_SUCCESS( 2058 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2059 2060 forkee_status_signaled(status, SIGKILL, 0); 2061 2062 /* Inform parent that tracer is exiting normally */ 2063 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 2064 2065 DPRINTF("Before exiting of the tracer process\n"); 2066 _exit(0 /* collect by initproc */); 2067 } 2068 2069 DPRINTF("Wait for the tracer process (direct child) to exit " 2070 "calling %s()\n", TWAIT_FNAME); 2071 TWAIT_REQUIRE_SUCCESS( 2072 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2073 2074 validate_status_exited(status, exitval); 2075 2076 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2077 TWAIT_FNAME); 2078 TWAIT_REQUIRE_SUCCESS( 2079 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2080 2081 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2082 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2083 2084 DPRINTF("Resume the tracee and let it crash\n"); 2085 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2086 2087 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 2088 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2089 2090 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2091 TWAIT_FNAME); 2092 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2093 2094 validate_status_signaled(status, SIGKILL, 0); 2095 2096 DPRINTF("Await normal exit of tracer\n"); 2097 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 2098 2099 msg_close(&parent_tracer); 2100 msg_close(&parent_tracee); 2101} 2102 2103#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 2104ATF_TC(test); \ 2105ATF_TC_HEAD(test, tc) \ 2106{ \ 2107 atf_tc_set_md_var(tc, "descr", \ 2108 "Assert that an unrelated tracer sees crash signal from " \ 2109 "the debuggee"); \ 2110} \ 2111 \ 2112ATF_TC_BODY(test, tc) \ 2113{ \ 2114 \ 2115 unrelated_tracer_sees_crash(sig, false, false); \ 2116} 2117 2118UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 2119UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 2120UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 2121UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 2122UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 2123 2124#define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig) \ 2125ATF_TC(test); \ 2126ATF_TC_HEAD(test, tc) \ 2127{ \ 2128 atf_tc_set_md_var(tc, "descr", \ 2129 "Assert that an unrelated tracer sees crash signal from " \ 2130 "the debuggee with masked signal"); \ 2131} \ 2132 \ 2133ATF_TC_BODY(test, tc) \ 2134{ \ 2135 \ 2136 unrelated_tracer_sees_crash(sig, true, false); \ 2137} 2138 2139UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2140 unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP) 2141UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2142 unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV) 2143UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2144 unrelated_tracer_sees_signalmasked_crash_ill, SIGILL) 2145UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2146 unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE) 2147UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2148 unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS) 2149 2150#define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig) \ 2151ATF_TC(test); \ 2152ATF_TC_HEAD(test, tc) \ 2153{ \ 2154 atf_tc_set_md_var(tc, "descr", \ 2155 "Assert that an unrelated tracer sees crash signal from " \ 2156 "the debuggee with signal ignored"); \ 2157} \ 2158 \ 2159ATF_TC_BODY(test, tc) \ 2160{ \ 2161 \ 2162 unrelated_tracer_sees_crash(sig, false, true); \ 2163} 2164 2165UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2166 unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP) 2167UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2168 unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV) 2169UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2170 unrelated_tracer_sees_signalignored_crash_ill, SIGILL) 2171UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2172 unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE) 2173UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2174 unrelated_tracer_sees_signalignored_crash_bus, SIGBUS) 2175#endif 2176 2177/// ---------------------------------------------------------------------------- 2178 2179#if defined(TWAIT_HAVE_PID) 2180static void 2181tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 2182 bool stopped) 2183{ 2184 /* 2185 * notimeout - disable timeout in await zombie function 2186 * unrelated - attach from unrelated tracer reparented to initproc 2187 * stopped - attach to a stopped process 2188 */ 2189 2190 struct msg_fds parent_tracee, parent_tracer; 2191 const int exitval_tracee = 5; 2192 const int exitval_tracer = 10; 2193 pid_t tracee, tracer, wpid; 2194 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2195#if defined(TWAIT_HAVE_STATUS) 2196 int status; 2197#endif 2198 2199 /* 2200 * Only a subset of options are supported. 2201 */ 2202 ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 2203 (!notimeout && unrelated && !stopped) || 2204 (notimeout && !unrelated && !stopped) || 2205 (!notimeout && unrelated && stopped)); 2206 2207 DPRINTF("Spawn tracee\n"); 2208 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2209 tracee = atf_utils_fork(); 2210 if (tracee == 0) { 2211 if (stopped) { 2212 DPRINTF("Stop self PID %d\n", getpid()); 2213 raise(SIGSTOP); 2214 } 2215 2216 // Wait for parent to let us exit 2217 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2218 _exit(exitval_tracee); 2219 } 2220 2221 DPRINTF("Spawn debugger\n"); 2222 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2223 tracer = atf_utils_fork(); 2224 if (tracer == 0) { 2225 if(unrelated) { 2226 /* Fork again and drop parent to reattach to PID 1 */ 2227 tracer = atf_utils_fork(); 2228 if (tracer != 0) 2229 _exit(exitval_tracer); 2230 } 2231 2232 if (stopped) { 2233 DPRINTF("Await for a stopped parent PID %d\n", tracee); 2234 await_stopped(tracee); 2235 } 2236 2237 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2238 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2239 2240 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2241 FORKEE_REQUIRE_SUCCESS( 2242 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2243 2244 forkee_status_stopped(status, SIGSTOP); 2245 2246 /* Resume tracee with PT_CONTINUE */ 2247 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2248 2249 /* Inform parent that tracer has attached to tracee */ 2250 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2251 2252 /* Wait for parent to tell use that tracee should have exited */ 2253 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2254 2255 /* Wait for tracee and assert that it exited */ 2256 FORKEE_REQUIRE_SUCCESS( 2257 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2258 2259 forkee_status_exited(status, exitval_tracee); 2260 DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 2261 2262 DPRINTF("Before exiting of the tracer process\n"); 2263 _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 2264 } 2265 2266 if (unrelated) { 2267 DPRINTF("Wait for the tracer process (direct child) to exit " 2268 "calling %s()\n", TWAIT_FNAME); 2269 TWAIT_REQUIRE_SUCCESS( 2270 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2271 2272 validate_status_exited(status, exitval_tracer); 2273 2274 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2275 TWAIT_FNAME); 2276 TWAIT_REQUIRE_SUCCESS( 2277 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2278 } 2279 2280 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2281 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2282 2283 DPRINTF("Resume the tracee and let it exit\n"); 2284 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2285 2286 DPRINTF("Detect that tracee is zombie\n"); 2287 if (notimeout) 2288 await_zombie_raw(tracee, 0); 2289 else 2290 await_zombie(tracee); 2291 2292 DPRINTF("Assert that there is no status about tracee %d - " 2293 "Tracer must detect zombie first - calling %s()\n", tracee, 2294 TWAIT_FNAME); 2295 TWAIT_REQUIRE_SUCCESS( 2296 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2297 2298 if (unrelated) { 2299 DPRINTF("Resume the tracer and let it detect exited tracee\n"); 2300 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2301 } else { 2302 DPRINTF("Tell the tracer child should have exited\n"); 2303 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2304 DPRINTF("Wait for tracer to finish its job and exit - calling " 2305 "%s()\n", TWAIT_FNAME); 2306 2307 DPRINTF("Wait from tracer child to complete waiting for " 2308 "tracee\n"); 2309 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2310 tracer); 2311 2312 validate_status_exited(status, exitval_tracer); 2313 } 2314 2315 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2316 TWAIT_FNAME); 2317 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2318 2319 validate_status_exited(status, exitval_tracee); 2320 2321 msg_close(&parent_tracer); 2322 msg_close(&parent_tracee); 2323} 2324 2325ATF_TC(tracer_sees_terminaton_before_the_parent); 2326ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 2327{ 2328 atf_tc_set_md_var(tc, "descr", 2329 "Assert that tracer sees process termination before the parent"); 2330} 2331 2332ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 2333{ 2334 2335 tracer_sees_terminaton_before_the_parent_raw(false, false, false); 2336} 2337 2338ATF_TC(tracer_sysctl_lookup_without_duplicates); 2339ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 2340{ 2341 atf_tc_set_md_var(tc, "descr", 2342 "Assert that await_zombie() in attach1 always finds a single " 2343 "process and no other error is reported"); 2344} 2345 2346ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 2347{ 2348 time_t start, end; 2349 double diff; 2350 unsigned long N = 0; 2351 2352 /* 2353 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 2354 * This test body isn't specific to this race, however it's just good 2355 * enough for this purposes, no need to invent a dedicated code flow. 2356 */ 2357 2358 start = time(NULL); 2359 while (true) { 2360 DPRINTF("Step: %lu\n", N); 2361 tracer_sees_terminaton_before_the_parent_raw(true, false, 2362 false); 2363 end = time(NULL); 2364 diff = difftime(end, start); 2365 if (diff >= 5.0) 2366 break; 2367 ++N; 2368 } 2369 DPRINTF("Iterations: %lu\n", N); 2370} 2371 2372ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 2373ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2374{ 2375 atf_tc_set_md_var(tc, "descr", 2376 "Assert that tracer sees process termination before the parent"); 2377} 2378 2379ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2380{ 2381 2382 tracer_sees_terminaton_before_the_parent_raw(false, true, false); 2383} 2384 2385ATF_TC(tracer_attach_to_unrelated_stopped_process); 2386ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 2387{ 2388 atf_tc_set_md_var(tc, "descr", 2389 "Assert that tracer can attach to an unrelated stopped process"); 2390} 2391 2392ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 2393{ 2394 2395 tracer_sees_terminaton_before_the_parent_raw(false, true, true); 2396} 2397#endif 2398 2399/// ---------------------------------------------------------------------------- 2400 2401static void 2402parent_attach_to_its_child(bool stopped) 2403{ 2404 struct msg_fds parent_tracee; 2405 const int exitval_tracee = 5; 2406 pid_t tracee, wpid; 2407 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2408#if defined(TWAIT_HAVE_STATUS) 2409 int status; 2410#endif 2411 2412 DPRINTF("Spawn tracee\n"); 2413 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2414 tracee = atf_utils_fork(); 2415 if (tracee == 0) { 2416 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2417 DPRINTF("Parent should now attach to tracee\n"); 2418 2419 if (stopped) { 2420 DPRINTF("Stop self PID %d\n", getpid()); 2421 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2422 } 2423 2424 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 2425 /* Wait for message from the parent */ 2426 _exit(exitval_tracee); 2427 } 2428 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2429 2430 if (stopped) { 2431 DPRINTF("Await for a stopped tracee PID %d\n", tracee); 2432 await_stopped(tracee); 2433 } 2434 2435 DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 2436 SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2437 2438 DPRINTF("Wait for the stopped tracee process with %s()\n", 2439 TWAIT_FNAME); 2440 TWAIT_REQUIRE_SUCCESS( 2441 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2442 2443 validate_status_stopped(status, SIGSTOP); 2444 2445 DPRINTF("Resume tracee with PT_CONTINUE\n"); 2446 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2447 2448 DPRINTF("Let the tracee exit now\n"); 2449 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 2450 2451 DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 2452 TWAIT_REQUIRE_SUCCESS( 2453 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2454 2455 validate_status_exited(status, exitval_tracee); 2456 2457 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 2458 TWAIT_REQUIRE_FAILURE(ECHILD, 2459 wpid = TWAIT_GENERIC(tracee, &status, 0)); 2460 2461 msg_close(&parent_tracee); 2462} 2463 2464ATF_TC(parent_attach_to_its_child); 2465ATF_TC_HEAD(parent_attach_to_its_child, tc) 2466{ 2467 atf_tc_set_md_var(tc, "descr", 2468 "Assert that tracer parent can PT_ATTACH to its child"); 2469} 2470 2471ATF_TC_BODY(parent_attach_to_its_child, tc) 2472{ 2473 2474 parent_attach_to_its_child(false); 2475} 2476 2477ATF_TC(parent_attach_to_its_stopped_child); 2478ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 2479{ 2480 atf_tc_set_md_var(tc, "descr", 2481 "Assert that tracer parent can PT_ATTACH to its stopped child"); 2482} 2483 2484ATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 2485{ 2486 2487 parent_attach_to_its_child(true); 2488} 2489 2490/// ---------------------------------------------------------------------------- 2491 2492static void 2493child_attach_to_its_parent(bool stopped) 2494{ 2495 struct msg_fds parent_tracee; 2496 const int exitval_tracer = 5; 2497 pid_t tracer, wpid; 2498 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2499#if defined(TWAIT_HAVE_STATUS) 2500 int status; 2501#endif 2502 2503 DPRINTF("Spawn tracer\n"); 2504 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2505 tracer = atf_utils_fork(); 2506 if (tracer == 0) { 2507 /* Wait for message from the parent */ 2508 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2509 2510 if (stopped) { 2511 DPRINTF("Await for a stopped parent PID %d\n", 2512 getppid()); 2513 await_stopped(getppid()); 2514 } 2515 2516 DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 2517 getppid()); 2518 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 2519 2520 DPRINTF("Wait for the stopped parent process with %s()\n", 2521 TWAIT_FNAME); 2522 FORKEE_REQUIRE_SUCCESS( 2523 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 2524 2525 forkee_status_stopped(status, SIGSTOP); 2526 2527 DPRINTF("Resume parent with PT_DETACH\n"); 2528 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 2529 != -1); 2530 2531 /* Tell parent we are ready */ 2532 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 2533 2534 _exit(exitval_tracer); 2535 } 2536 2537 DPRINTF("Wait for the tracer to become ready\n"); 2538 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2539 2540 if (stopped) { 2541 DPRINTF("Stop self PID %d\n", getpid()); 2542 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2543 } 2544 2545 DPRINTF("Allow the tracer to exit now\n"); 2546 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 2547 2548 DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 2549 TWAIT_REQUIRE_SUCCESS( 2550 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2551 2552 validate_status_exited(status, exitval_tracer); 2553 2554 DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 2555 TWAIT_REQUIRE_FAILURE(ECHILD, 2556 wpid = TWAIT_GENERIC(tracer, &status, 0)); 2557 2558 msg_close(&parent_tracee); 2559} 2560 2561ATF_TC(child_attach_to_its_parent); 2562ATF_TC_HEAD(child_attach_to_its_parent, tc) 2563{ 2564 atf_tc_set_md_var(tc, "descr", 2565 "Assert that tracer child can PT_ATTACH to its parent"); 2566} 2567 2568ATF_TC_BODY(child_attach_to_its_parent, tc) 2569{ 2570 2571 child_attach_to_its_parent(false); 2572} 2573 2574ATF_TC(child_attach_to_its_stopped_parent); 2575ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 2576{ 2577 atf_tc_set_md_var(tc, "descr", 2578 "Assert that tracer child can PT_ATTACH to its stopped parent"); 2579} 2580 2581ATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 2582{ 2583 /* 2584 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 2585 * this causes a pipe (established from atf-run) to be broken. 2586 * atf-run uses this mechanism to monitor whether a test is alive. 2587 * 2588 * As a workaround spawn this test as a subprocess. 2589 */ 2590 2591 const int exitval = 15; 2592 pid_t child, wpid; 2593#if defined(TWAIT_HAVE_STATUS) 2594 int status; 2595#endif 2596 2597 SYSCALL_REQUIRE((child = fork()) != -1); 2598 if (child == 0) { 2599 child_attach_to_its_parent(true); 2600 _exit(exitval); 2601 } else { 2602 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2603 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2604 2605 validate_status_exited(status, exitval); 2606 2607 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 2608 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2609 } 2610} 2611 2612/// ---------------------------------------------------------------------------- 2613 2614#if defined(TWAIT_HAVE_PID) 2615 2616enum tracee_sees_its_original_parent_type { 2617 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2618 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2619 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 2620}; 2621 2622static void 2623tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 2624{ 2625 struct msg_fds parent_tracer, parent_tracee; 2626 const int exitval_tracee = 5; 2627 const int exitval_tracer = 10; 2628 pid_t parent, tracee, tracer, wpid; 2629 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2630#if defined(TWAIT_HAVE_STATUS) 2631 int status; 2632#endif 2633 /* sysctl(3) - kinfo_proc2 */ 2634 int name[CTL_MAXNAME]; 2635 struct kinfo_proc2 kp; 2636 size_t len = sizeof(kp); 2637 unsigned int namelen; 2638 2639 /* procfs - status */ 2640 FILE *fp; 2641 struct stat st; 2642 const char *fname = "/proc/curproc/status"; 2643 char s_executable[MAXPATHLEN]; 2644 int s_pid, s_ppid; 2645 int rv; 2646 2647 if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 2648 SYSCALL_REQUIRE( 2649 (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 2650 if (rv != 0) 2651 atf_tc_skip("/proc/curproc/status not found"); 2652 } 2653 2654 DPRINTF("Spawn tracee\n"); 2655 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2656 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2657 tracee = atf_utils_fork(); 2658 if (tracee == 0) { 2659 parent = getppid(); 2660 2661 /* Emit message to the parent */ 2662 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 2663 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2664 2665 switch (type) { 2666 case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 2667 FORKEE_ASSERT_EQ(parent, getppid()); 2668 break; 2669 case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 2670 namelen = 0; 2671 name[namelen++] = CTL_KERN; 2672 name[namelen++] = KERN_PROC2; 2673 name[namelen++] = KERN_PROC_PID; 2674 name[namelen++] = getpid(); 2675 name[namelen++] = len; 2676 name[namelen++] = 1; 2677 2678 FORKEE_ASSERT_EQ( 2679 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2680 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 2681 break; 2682 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 2683 /* 2684 * Format: 2685 * EXECUTABLE PID PPID ... 2686 */ 2687 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 2688 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 2689 FORKEE_ASSERT_EQ(fclose(fp), 0); 2690 FORKEE_ASSERT_EQ(parent, s_ppid); 2691 break; 2692 } 2693 2694 _exit(exitval_tracee); 2695 } 2696 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 2697 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 2698 2699 DPRINTF("Spawn debugger\n"); 2700 tracer = atf_utils_fork(); 2701 if (tracer == 0) { 2702 /* No IPC to communicate with the child */ 2703 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2704 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2705 2706 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2707 FORKEE_REQUIRE_SUCCESS( 2708 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2709 2710 forkee_status_stopped(status, SIGSTOP); 2711 2712 /* Resume tracee with PT_CONTINUE */ 2713 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2714 2715 /* Inform parent that tracer has attached to tracee */ 2716 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2717 2718 /* Wait for parent to tell use that tracee should have exited */ 2719 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2720 2721 /* Wait for tracee and assert that it exited */ 2722 FORKEE_REQUIRE_SUCCESS( 2723 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2724 2725 forkee_status_exited(status, exitval_tracee); 2726 2727 DPRINTF("Before exiting of the tracer process\n"); 2728 _exit(exitval_tracer); 2729 } 2730 2731 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2732 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2733 2734 DPRINTF("Resume the tracee and let it exit\n"); 2735 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2736 2737 DPRINTF("Detect that tracee is zombie\n"); 2738 await_zombie(tracee); 2739 2740 DPRINTF("Assert that there is no status about tracee - " 2741 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 2742 TWAIT_REQUIRE_SUCCESS( 2743 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2744 2745 DPRINTF("Tell the tracer child should have exited\n"); 2746 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2747 2748 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 2749 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2750 tracer); 2751 2752 validate_status_exited(status, exitval_tracer); 2753 2754 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2755 TWAIT_FNAME); 2756 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 2757 tracee); 2758 2759 validate_status_exited(status, exitval_tracee); 2760 2761 msg_close(&parent_tracer); 2762 msg_close(&parent_tracee); 2763} 2764 2765#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 2766ATF_TC(test); \ 2767ATF_TC_HEAD(test, tc) \ 2768{ \ 2769 atf_tc_set_md_var(tc, "descr", \ 2770 "Assert that tracee sees its original parent when being traced " \ 2771 "(check " descr ")"); \ 2772} \ 2773 \ 2774ATF_TC_BODY(test, tc) \ 2775{ \ 2776 \ 2777 tracee_sees_its_original_parent(type); \ 2778} 2779 2780TRACEE_SEES_ITS_ORIGINAL_PARENT( 2781 tracee_sees_its_original_parent_getppid, 2782 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2783 "getppid(2)"); 2784TRACEE_SEES_ITS_ORIGINAL_PARENT( 2785 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 2786 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2787 "sysctl(3) and kinfo_proc2"); 2788TRACEE_SEES_ITS_ORIGINAL_PARENT( 2789 tracee_sees_its_original_parent_procfs_status, 2790 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 2791 "the status file in procfs"); 2792#endif 2793 2794/// ---------------------------------------------------------------------------- 2795 2796static void 2797eventmask_preserved(int event) 2798{ 2799 const int exitval = 5; 2800 const int sigval = SIGSTOP; 2801 pid_t child, wpid; 2802#if defined(TWAIT_HAVE_STATUS) 2803 int status; 2804#endif 2805 ptrace_event_t set_event, get_event; 2806 const int len = sizeof(ptrace_event_t); 2807 2808 DPRINTF("Before forking process PID=%d\n", getpid()); 2809 SYSCALL_REQUIRE((child = fork()) != -1); 2810 if (child == 0) { 2811 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2812 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2813 2814 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2815 FORKEE_ASSERT(raise(sigval) == 0); 2816 2817 DPRINTF("Before exiting of the child process\n"); 2818 _exit(exitval); 2819 } 2820 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2821 2822 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2823 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2824 2825 validate_status_stopped(status, sigval); 2826 2827 set_event.pe_set_event = event; 2828 SYSCALL_REQUIRE( 2829 ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 2830 SYSCALL_REQUIRE( 2831 ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 2832 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 2833 2834 DPRINTF("Before resuming the child process where it left off and " 2835 "without signal to be sent\n"); 2836 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2837 2838 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2839 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2840 2841 validate_status_exited(status, exitval); 2842 2843 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2844 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2845} 2846 2847#define EVENTMASK_PRESERVED(test, event) \ 2848ATF_TC(test); \ 2849ATF_TC_HEAD(test, tc) \ 2850{ \ 2851 atf_tc_set_md_var(tc, "descr", \ 2852 "Verify that eventmask " #event " is preserved"); \ 2853} \ 2854 \ 2855ATF_TC_BODY(test, tc) \ 2856{ \ 2857 \ 2858 eventmask_preserved(event); \ 2859} 2860 2861EVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 2862EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 2863EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 2864EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 2865EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 2866EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 2867 2868/// ---------------------------------------------------------------------------- 2869 2870static void 2871fork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork, 2872 bool trackvforkdone, bool detachchild, bool detachparent) 2873{ 2874 const int exitval = 5; 2875 const int exitval2 = 15; 2876 const int sigval = SIGSTOP; 2877 pid_t child, child2 = 0, wpid; 2878#if defined(TWAIT_HAVE_STATUS) 2879 int status; 2880#endif 2881 ptrace_state_t state; 2882 const int slen = sizeof(state); 2883 ptrace_event_t event; 2884 const int elen = sizeof(event); 2885 2886 DPRINTF("Before forking process PID=%d\n", getpid()); 2887 SYSCALL_REQUIRE((child = fork()) != -1); 2888 if (child == 0) { 2889 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2890 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2891 2892 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2893 FORKEE_ASSERT(raise(sigval) == 0); 2894 2895 FORKEE_ASSERT((child2 = (fn)()) != -1); 2896 2897 if (child2 == 0) 2898 _exit(exitval2); 2899 2900 FORKEE_REQUIRE_SUCCESS 2901 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 2902 2903 forkee_status_exited(status, exitval2); 2904 2905 DPRINTF("Before exiting of the child process\n"); 2906 _exit(exitval); 2907 } 2908 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2909 2910 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2911 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2912 2913 validate_status_stopped(status, sigval); 2914 2915 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 2916 trackfork ? "|PTRACE_FORK" : "", 2917 trackvfork ? "|PTRACE_VFORK" : "", 2918 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 2919 event.pe_set_event = 0; 2920 if (trackfork) 2921 event.pe_set_event |= PTRACE_FORK; 2922 if (trackvfork) 2923 event.pe_set_event |= PTRACE_VFORK; 2924 if (trackvforkdone) 2925 event.pe_set_event |= PTRACE_VFORK_DONE; 2926 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 2927 2928 DPRINTF("Before resuming the child process where it left off and " 2929 "without signal to be sent\n"); 2930 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2931 2932#if defined(TWAIT_HAVE_PID) 2933 if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 2934 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 2935 child); 2936 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2937 child); 2938 2939 validate_status_stopped(status, SIGTRAP); 2940 2941 SYSCALL_REQUIRE( 2942 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2943 if (trackfork && fn == fork) { 2944 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 2945 PTRACE_FORK); 2946 } 2947 if (trackvfork && fn == vfork) { 2948 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 2949 PTRACE_VFORK); 2950 } 2951 2952 child2 = state.pe_other_pid; 2953 DPRINTF("Reported ptrace event with forkee %d\n", child2); 2954 2955 DPRINTF("Before calling %s() for the forkee %d of the child " 2956 "%d\n", TWAIT_FNAME, child2, child); 2957 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 2958 child2); 2959 2960 validate_status_stopped(status, SIGTRAP); 2961 2962 SYSCALL_REQUIRE( 2963 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 2964 if (trackfork && fn == fork) { 2965 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 2966 PTRACE_FORK); 2967 } 2968 if (trackvfork && fn == vfork) { 2969 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 2970 PTRACE_VFORK); 2971 } 2972 2973 ATF_REQUIRE_EQ(state.pe_other_pid, child); 2974 2975 DPRINTF("Before resuming the forkee process where it left off " 2976 "and without signal to be sent\n"); 2977 SYSCALL_REQUIRE( 2978 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 2979 2980 DPRINTF("Before resuming the child process where it left off " 2981 "and without signal to be sent\n"); 2982 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2983 } 2984#endif 2985 2986 if (trackvforkdone && fn == vfork) { 2987 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 2988 child); 2989 TWAIT_REQUIRE_SUCCESS( 2990 wpid = TWAIT_GENERIC(child, &status, 0), child); 2991 2992 validate_status_stopped(status, SIGTRAP); 2993 2994 SYSCALL_REQUIRE( 2995 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2996 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 2997 2998 child2 = state.pe_other_pid; 2999 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 3000 child2); 3001 3002 DPRINTF("Before resuming the child process where it left off " 3003 "and without signal to be sent\n"); 3004 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3005 } 3006 3007#if defined(TWAIT_HAVE_PID) 3008 if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 3009 DPRINTF("Before calling %s() for the forkee - expected exited" 3010 "\n", TWAIT_FNAME); 3011 TWAIT_REQUIRE_SUCCESS( 3012 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3013 3014 validate_status_exited(status, exitval2); 3015 3016 DPRINTF("Before calling %s() for the forkee - expected no " 3017 "process\n", TWAIT_FNAME); 3018 TWAIT_REQUIRE_FAILURE(ECHILD, 3019 wpid = TWAIT_GENERIC(child2, &status, 0)); 3020 } 3021#endif 3022 3023 DPRINTF("Before calling %s() for the child - expected stopped " 3024 "SIGCHLD\n", TWAIT_FNAME); 3025 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3026 3027 validate_status_stopped(status, SIGCHLD); 3028 3029 DPRINTF("Before resuming the child process where it left off and " 3030 "without signal to be sent\n"); 3031 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3032 3033 DPRINTF("Before calling %s() for the child - expected exited\n", 3034 TWAIT_FNAME); 3035 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3036 3037 validate_status_exited(status, exitval); 3038 3039 DPRINTF("Before calling %s() for the child - expected no process\n", 3040 TWAIT_FNAME); 3041 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3042} 3043 3044#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \ 3045ATF_TC(name); \ 3046ATF_TC_HEAD(name, tc) \ 3047{ \ 3048 atf_tc_set_md_var(tc, "descr", descr); \ 3049} \ 3050 \ 3051ATF_TC_BODY(name, tc) \ 3052{ \ 3053 \ 3054 fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent); \ 3055} 3056 3057#define F false 3058#define T true 3059 3060#define F_IF__0(x) 3061#define F_IF__1(x) x 3062#define F_IF__(x,y) F_IF__ ## x (y) 3063#define F_IF_(x,y) F_IF__(x,y) 3064#define F_IF(x,y) F_IF_(x,y) 3065 3066#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \ 3067 "Verify " #function "(2) called with 0" \ 3068 F_IF(forkbit,"|PTRACE_FORK") \ 3069 F_IF(vforkbit,"|PTRACE_VFORK") \ 3070 F_IF(vforkdonebit,"|PTRACE_VFORK_DONE") \ 3071 " in EVENT_MASK." \ 3072 F_IF(dchildbit," Detach child in this test.") \ 3073 F_IF(dparentbit," Detach parent in this test.") 3074 3075FORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F) 3076#if defined(TWAIT_HAVE_PID) 3077FORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F) 3078FORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F) 3079FORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F) 3080#endif 3081FORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F) 3082#if defined(TWAIT_HAVE_PID) 3083FORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F) 3084FORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F) 3085FORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F) 3086#endif 3087 3088FORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F) 3089#if defined(TWAIT_HAVE_PID) 3090FORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F) 3091FORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F) 3092FORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F) 3093#endif 3094FORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F) 3095#if defined(TWAIT_HAVE_PID) 3096FORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F) 3097FORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F) 3098FORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F) 3099#endif 3100 3101/// ---------------------------------------------------------------------------- 3102 3103enum bytes_transfer_type { 3104 BYTES_TRANSFER_DATA, 3105 BYTES_TRANSFER_DATAIO, 3106 BYTES_TRANSFER_TEXT, 3107 BYTES_TRANSFER_TEXTIO, 3108 BYTES_TRANSFER_AUXV 3109}; 3110 3111static int __used 3112bytes_transfer_dummy(int a, int b, int c, int d) 3113{ 3114 int e, f, g, h; 3115 3116 a *= 4; 3117 b += 3; 3118 c -= 2; 3119 d /= 1; 3120 3121 e = strtol("10", NULL, 10); 3122 f = strtol("20", NULL, 10); 3123 g = strtol("30", NULL, 10); 3124 h = strtol("40", NULL, 10); 3125 3126 return (a + b * c - d) + (e * f - g / h); 3127} 3128 3129static void 3130bytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 3131{ 3132 const int exitval = 5; 3133 const int sigval = SIGSTOP; 3134 pid_t child, wpid; 3135 bool skip = false; 3136 3137 int lookup_me = 0; 3138 uint8_t lookup_me8 = 0; 3139 uint16_t lookup_me16 = 0; 3140 uint32_t lookup_me32 = 0; 3141 uint64_t lookup_me64 = 0; 3142 3143 int magic = 0x13579246; 3144 uint8_t magic8 = 0xab; 3145 uint16_t magic16 = 0x1234; 3146 uint32_t magic32 = 0x98765432; 3147 uint64_t magic64 = 0xabcdef0123456789; 3148 3149 struct ptrace_io_desc io; 3150#if defined(TWAIT_HAVE_STATUS) 3151 int status; 3152#endif 3153 /* 513 is just enough, for the purposes of ATF it's good enough */ 3154 AuxInfo ai[513], *aip; 3155 3156 ATF_REQUIRE(size < sizeof(ai)); 3157 3158 /* Prepare variables for .TEXT transfers */ 3159 switch (type) { 3160 case BYTES_TRANSFER_TEXT: 3161 memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 3162 break; 3163 case BYTES_TRANSFER_TEXTIO: 3164 switch (size) { 3165 case 8: 3166 memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 3167 break; 3168 case 16: 3169 memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 3170 break; 3171 case 32: 3172 memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 3173 break; 3174 case 64: 3175 memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 3176 break; 3177 } 3178 break; 3179 default: 3180 break; 3181 } 3182 3183 /* Prepare variables for PIOD and AUXV transfers */ 3184 switch (type) { 3185 case BYTES_TRANSFER_TEXTIO: 3186 case BYTES_TRANSFER_DATAIO: 3187 io.piod_op = operation; 3188 switch (size) { 3189 case 8: 3190 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3191 (void *)bytes_transfer_dummy : 3192 &lookup_me8; 3193 io.piod_addr = &lookup_me8; 3194 io.piod_len = sizeof(lookup_me8); 3195 break; 3196 case 16: 3197 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3198 (void *)bytes_transfer_dummy : 3199 &lookup_me16; 3200 io.piod_addr = &lookup_me16; 3201 io.piod_len = sizeof(lookup_me16); 3202 break; 3203 case 32: 3204 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3205 (void *)bytes_transfer_dummy : 3206 &lookup_me32; 3207 io.piod_addr = &lookup_me32; 3208 io.piod_len = sizeof(lookup_me32); 3209 break; 3210 case 64: 3211 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3212 (void *)bytes_transfer_dummy : 3213 &lookup_me64; 3214 io.piod_addr = &lookup_me64; 3215 io.piod_len = sizeof(lookup_me64); 3216 break; 3217 default: 3218 break; 3219 } 3220 break; 3221 case BYTES_TRANSFER_AUXV: 3222 io.piod_op = operation; 3223 io.piod_offs = 0; 3224 io.piod_addr = ai; 3225 io.piod_len = size; 3226 break; 3227 default: 3228 break; 3229 } 3230 3231 DPRINTF("Before forking process PID=%d\n", getpid()); 3232 SYSCALL_REQUIRE((child = fork()) != -1); 3233 if (child == 0) { 3234 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3235 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3236 3237 switch (type) { 3238 case BYTES_TRANSFER_DATA: 3239 switch (operation) { 3240 case PT_READ_D: 3241 case PT_READ_I: 3242 lookup_me = magic; 3243 break; 3244 default: 3245 break; 3246 } 3247 break; 3248 case BYTES_TRANSFER_DATAIO: 3249 switch (operation) { 3250 case PIOD_READ_D: 3251 case PIOD_READ_I: 3252 switch (size) { 3253 case 8: 3254 lookup_me8 = magic8; 3255 break; 3256 case 16: 3257 lookup_me16 = magic16; 3258 break; 3259 case 32: 3260 lookup_me32 = magic32; 3261 break; 3262 case 64: 3263 lookup_me64 = magic64; 3264 break; 3265 default: 3266 break; 3267 } 3268 break; 3269 default: 3270 break; 3271 } 3272 default: 3273 break; 3274 } 3275 3276 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3277 FORKEE_ASSERT(raise(sigval) == 0); 3278 3279 /* Handle PIOD and PT separately as operation values overlap */ 3280 switch (type) { 3281 case BYTES_TRANSFER_DATA: 3282 switch (operation) { 3283 case PT_WRITE_D: 3284 case PT_WRITE_I: 3285 FORKEE_ASSERT_EQ(lookup_me, magic); 3286 break; 3287 default: 3288 break; 3289 } 3290 break; 3291 case BYTES_TRANSFER_DATAIO: 3292 switch (operation) { 3293 case PIOD_WRITE_D: 3294 case PIOD_WRITE_I: 3295 switch (size) { 3296 case 8: 3297 FORKEE_ASSERT_EQ(lookup_me8, magic8); 3298 break; 3299 case 16: 3300 FORKEE_ASSERT_EQ(lookup_me16, magic16); 3301 break; 3302 case 32: 3303 FORKEE_ASSERT_EQ(lookup_me32, magic32); 3304 break; 3305 case 64: 3306 FORKEE_ASSERT_EQ(lookup_me64, magic64); 3307 break; 3308 default: 3309 break; 3310 } 3311 break; 3312 default: 3313 break; 3314 } 3315 break; 3316 case BYTES_TRANSFER_TEXT: 3317 FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 3318 sizeof(magic)) == 0); 3319 break; 3320 case BYTES_TRANSFER_TEXTIO: 3321 switch (size) { 3322 case 8: 3323 FORKEE_ASSERT(memcmp(&magic8, 3324 bytes_transfer_dummy, 3325 sizeof(magic8)) == 0); 3326 break; 3327 case 16: 3328 FORKEE_ASSERT(memcmp(&magic16, 3329 bytes_transfer_dummy, 3330 sizeof(magic16)) == 0); 3331 break; 3332 case 32: 3333 FORKEE_ASSERT(memcmp(&magic32, 3334 bytes_transfer_dummy, 3335 sizeof(magic32)) == 0); 3336 break; 3337 case 64: 3338 FORKEE_ASSERT(memcmp(&magic64, 3339 bytes_transfer_dummy, 3340 sizeof(magic64)) == 0); 3341 break; 3342 } 3343 break; 3344 default: 3345 break; 3346 } 3347 3348 DPRINTF("Before exiting of the child process\n"); 3349 _exit(exitval); 3350 } 3351 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3352 3353 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3354 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3355 3356 validate_status_stopped(status, sigval); 3357 3358 /* Check PaX MPROTECT */ 3359 if (!can_we_write_to_text(child)) { 3360 switch (type) { 3361 case BYTES_TRANSFER_TEXTIO: 3362 switch (operation) { 3363 case PIOD_WRITE_D: 3364 case PIOD_WRITE_I: 3365 skip = true; 3366 break; 3367 default: 3368 break; 3369 } 3370 break; 3371 case BYTES_TRANSFER_TEXT: 3372 switch (operation) { 3373 case PT_WRITE_D: 3374 case PT_WRITE_I: 3375 skip = true; 3376 break; 3377 default: 3378 break; 3379 } 3380 break; 3381 default: 3382 break; 3383 } 3384 } 3385 3386 /* Bailout cleanly killing the child process */ 3387 if (skip) { 3388 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 3389 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3390 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3391 child); 3392 3393 validate_status_signaled(status, SIGKILL, 0); 3394 3395 atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 3396 } 3397 3398 DPRINTF("Calling operation to transfer bytes between child=%d and " 3399 "parent=%d\n", child, getpid()); 3400 3401 switch (type) { 3402 case BYTES_TRANSFER_TEXTIO: 3403 case BYTES_TRANSFER_DATAIO: 3404 case BYTES_TRANSFER_AUXV: 3405 switch (operation) { 3406 case PIOD_WRITE_D: 3407 case PIOD_WRITE_I: 3408 switch (size) { 3409 case 8: 3410 lookup_me8 = magic8; 3411 break; 3412 case 16: 3413 lookup_me16 = magic16; 3414 break; 3415 case 32: 3416 lookup_me32 = magic32; 3417 break; 3418 case 64: 3419 lookup_me64 = magic64; 3420 break; 3421 default: 3422 break; 3423 } 3424 break; 3425 default: 3426 break; 3427 } 3428 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 3429 switch (operation) { 3430 case PIOD_READ_D: 3431 case PIOD_READ_I: 3432 switch (size) { 3433 case 8: 3434 ATF_REQUIRE_EQ(lookup_me8, magic8); 3435 break; 3436 case 16: 3437 ATF_REQUIRE_EQ(lookup_me16, magic16); 3438 break; 3439 case 32: 3440 ATF_REQUIRE_EQ(lookup_me32, magic32); 3441 break; 3442 case 64: 3443 ATF_REQUIRE_EQ(lookup_me64, magic64); 3444 break; 3445 default: 3446 break; 3447 } 3448 break; 3449 case PIOD_READ_AUXV: 3450 DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 3451 io.piod_len); 3452 ATF_REQUIRE(io.piod_len > 0); 3453 for (aip = ai; aip->a_type != AT_NULL; aip++) 3454 DPRINTF("a_type=%#llx a_v=%#llx\n", 3455 (long long int)aip->a_type, 3456 (long long int)aip->a_v); 3457 break; 3458 default: 3459 break; 3460 } 3461 break; 3462 case BYTES_TRANSFER_TEXT: 3463 switch (operation) { 3464 case PT_READ_D: 3465 case PT_READ_I: 3466 errno = 0; 3467 lookup_me = ptrace(operation, child, 3468 bytes_transfer_dummy, 0); 3469 ATF_REQUIRE_EQ(lookup_me, magic); 3470 SYSCALL_REQUIRE_ERRNO(errno, 0); 3471 break; 3472 case PT_WRITE_D: 3473 case PT_WRITE_I: 3474 SYSCALL_REQUIRE(ptrace(operation, child, 3475 bytes_transfer_dummy, magic) 3476 != -1); 3477 break; 3478 default: 3479 break; 3480 } 3481 break; 3482 case BYTES_TRANSFER_DATA: 3483 switch (operation) { 3484 case PT_READ_D: 3485 case PT_READ_I: 3486 errno = 0; 3487 lookup_me = ptrace(operation, child, &lookup_me, 0); 3488 ATF_REQUIRE_EQ(lookup_me, magic); 3489 SYSCALL_REQUIRE_ERRNO(errno, 0); 3490 break; 3491 case PT_WRITE_D: 3492 case PT_WRITE_I: 3493 lookup_me = magic; 3494 SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 3495 magic) != -1); 3496 break; 3497 default: 3498 break; 3499 } 3500 break; 3501 default: 3502 break; 3503 } 3504 3505 DPRINTF("Before resuming the child process where it left off and " 3506 "without signal to be sent\n"); 3507 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3508 3509 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3510 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3511 3512 validate_status_exited(status, exitval); 3513 3514 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3515 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3516} 3517 3518#define BYTES_TRANSFER(test, operation, size, type) \ 3519ATF_TC(test); \ 3520ATF_TC_HEAD(test, tc) \ 3521{ \ 3522 atf_tc_set_md_var(tc, "descr", \ 3523 "Verify bytes transfer operation" #operation " and size " #size \ 3524 " of type " #type); \ 3525} \ 3526 \ 3527ATF_TC_BODY(test, tc) \ 3528{ \ 3529 \ 3530 bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 3531} 3532 3533// DATA 3534 3535BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 3536BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 3537BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 3538BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 3539 3540BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 3541BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 3542BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 3543BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 3544 3545BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 3546BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 3547BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 3548BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 3549 3550BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 3551BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 3552BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 3553BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 3554 3555BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 3556BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 3557BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 3558BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 3559 3560// TEXT 3561 3562BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 3563BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 3564BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 3565BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 3566 3567BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 3568BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 3569BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 3570BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 3571 3572BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 3573BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 3574BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 3575BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 3576 3577BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 3578BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 3579BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 3580BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 3581 3582BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 3583BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 3584BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 3585BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 3586 3587// AUXV 3588 3589BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 3590 3591/// ---------------------------------------------------------------------------- 3592 3593#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 3594static void 3595access_regs(const char *regset, const char *aux) 3596{ 3597 const int exitval = 5; 3598 const int sigval = SIGSTOP; 3599 pid_t child, wpid; 3600#if defined(TWAIT_HAVE_STATUS) 3601 int status; 3602#endif 3603#if defined(HAVE_GPREGS) 3604 struct reg gpr; 3605 register_t rgstr; 3606#endif 3607#if defined(HAVE_FPREGS) 3608 struct fpreg fpr; 3609#endif 3610 3611#if !defined(HAVE_GPREGS) 3612 if (strcmp(regset, "regs") == 0) 3613 atf_tc_fail("Impossible test scenario!"); 3614#endif 3615 3616#if !defined(HAVE_FPREGS) 3617 if (strcmp(regset, "fpregs") == 0) 3618 atf_tc_fail("Impossible test scenario!"); 3619#endif 3620 3621 DPRINTF("Before forking process PID=%d\n", getpid()); 3622 SYSCALL_REQUIRE((child = fork()) != -1); 3623 if (child == 0) { 3624 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3625 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3626 3627 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3628 FORKEE_ASSERT(raise(sigval) == 0); 3629 3630 DPRINTF("Before exiting of the child process\n"); 3631 _exit(exitval); 3632 } 3633 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3634 3635 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3636 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3637 3638 validate_status_stopped(status, sigval); 3639 3640#if defined(HAVE_GPREGS) 3641 if (strcmp(regset, "regs") == 0) { 3642 DPRINTF("Call GETREGS for the child process\n"); 3643 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 3644 3645 if (strcmp(aux, "none") == 0) { 3646 DPRINTF("Retrieved registers\n"); 3647 } else if (strcmp(aux, "pc") == 0) { 3648 rgstr = PTRACE_REG_PC(&gpr); 3649 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 3650 } else if (strcmp(aux, "set_pc") == 0) { 3651 rgstr = PTRACE_REG_PC(&gpr); 3652 PTRACE_REG_SET_PC(&gpr, rgstr); 3653 } else if (strcmp(aux, "sp") == 0) { 3654 rgstr = PTRACE_REG_SP(&gpr); 3655 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 3656 } else if (strcmp(aux, "intrv") == 0) { 3657 rgstr = PTRACE_REG_INTRV(&gpr); 3658 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 3659 } else if (strcmp(aux, "setregs") == 0) { 3660 DPRINTF("Call SETREGS for the child process\n"); 3661 SYSCALL_REQUIRE( 3662 ptrace(PT_GETREGS, child, &gpr, 0) != -1); 3663 } 3664 } 3665#endif 3666 3667#if defined(HAVE_FPREGS) 3668 if (strcmp(regset, "fpregs") == 0) { 3669 DPRINTF("Call GETFPREGS for the child process\n"); 3670 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 3671 3672 if (strcmp(aux, "getfpregs") == 0) { 3673 DPRINTF("Retrieved FP registers\n"); 3674 } else if (strcmp(aux, "setfpregs") == 0) { 3675 DPRINTF("Call SETFPREGS for the child\n"); 3676 SYSCALL_REQUIRE( 3677 ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 3678 } 3679 } 3680#endif 3681 3682 DPRINTF("Before resuming the child process where it left off and " 3683 "without signal to be sent\n"); 3684 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3685 3686 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3687 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3688 3689 validate_status_exited(status, exitval); 3690 3691 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3692 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3693} 3694 3695#define ACCESS_REGS(test, regset, aux) \ 3696ATF_TC(test); \ 3697ATF_TC_HEAD(test, tc) \ 3698{ \ 3699 atf_tc_set_md_var(tc, "descr", \ 3700 "Verify " regset " with auxiliary operation: " aux); \ 3701} \ 3702 \ 3703ATF_TC_BODY(test, tc) \ 3704{ \ 3705 \ 3706 access_regs(regset, aux); \ 3707} 3708#endif 3709 3710#if defined(HAVE_GPREGS) 3711ACCESS_REGS(access_regs1, "regs", "none") 3712ACCESS_REGS(access_regs2, "regs", "pc") 3713ACCESS_REGS(access_regs3, "regs", "set_pc") 3714ACCESS_REGS(access_regs4, "regs", "sp") 3715ACCESS_REGS(access_regs5, "regs", "intrv") 3716ACCESS_REGS(access_regs6, "regs", "setregs") 3717#endif 3718#if defined(HAVE_FPREGS) 3719ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 3720ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 3721#endif 3722 3723/// ---------------------------------------------------------------------------- 3724 3725#if defined(PT_STEP) 3726static void 3727ptrace_step(int N, int setstep, bool masked, bool ignored) 3728{ 3729 const int exitval = 5; 3730 const int sigval = SIGSTOP; 3731 pid_t child, wpid; 3732#if defined(TWAIT_HAVE_STATUS) 3733 int status; 3734#endif 3735 int happy; 3736 struct sigaction sa; 3737 struct ptrace_siginfo info; 3738 sigset_t intmask; 3739 struct kinfo_proc2 kp; 3740 size_t len = sizeof(kp); 3741 3742 int name[6]; 3743 const size_t namelen = __arraycount(name); 3744 ki_sigset_t kp_sigmask; 3745 ki_sigset_t kp_sigignore; 3746 3747#if defined(__arm__) 3748 /* PT_STEP not supported on arm 32-bit */ 3749 atf_tc_expect_fail("PR kern/52119"); 3750#endif 3751 3752 if (masked || ignored) 3753 atf_tc_expect_fail("Unexpected sigmask reset on crash under " 3754 "debugger"); 3755 3756 DPRINTF("Before forking process PID=%d\n", getpid()); 3757 SYSCALL_REQUIRE((child = fork()) != -1); 3758 if (child == 0) { 3759 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3760 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3761 3762 if (masked) { 3763 sigemptyset(&intmask); 3764 sigaddset(&intmask, SIGTRAP); 3765 sigprocmask(SIG_BLOCK, &intmask, NULL); 3766 } 3767 3768 if (ignored) { 3769 memset(&sa, 0, sizeof(sa)); 3770 sa.sa_handler = SIG_IGN; 3771 sigemptyset(&sa.sa_mask); 3772 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 3773 } 3774 3775 happy = check_happy(999); 3776 3777 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3778 FORKEE_ASSERT(raise(sigval) == 0); 3779 3780 FORKEE_ASSERT_EQ(happy, check_happy(999)); 3781 3782 DPRINTF("Before exiting of the child process\n"); 3783 _exit(exitval); 3784 } 3785 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3786 3787 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3788 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3789 3790 validate_status_stopped(status, sigval); 3791 3792 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3793 SYSCALL_REQUIRE( 3794 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3795 3796 DPRINTF("Before checking siginfo_t\n"); 3797 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3798 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3799 3800 name[0] = CTL_KERN, 3801 name[1] = KERN_PROC2, 3802 name[2] = KERN_PROC_PID; 3803 name[3] = child; 3804 name[4] = sizeof(kp); 3805 name[5] = 1; 3806 3807 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 3808 3809 if (masked) 3810 kp_sigmask = kp.p_sigmask; 3811 3812 if (ignored) 3813 kp_sigignore = kp.p_sigignore; 3814 3815 while (N --> 0) { 3816 if (setstep) { 3817 DPRINTF("Before resuming the child process where it " 3818 "left off and without signal to be sent (use " 3819 "PT_SETSTEP and PT_CONTINUE)\n"); 3820 SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 3821 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 3822 != -1); 3823 } else { 3824 DPRINTF("Before resuming the child process where it " 3825 "left off and without signal to be sent (use " 3826 "PT_STEP)\n"); 3827 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 3828 != -1); 3829 } 3830 3831 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3832 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3833 child); 3834 3835 validate_status_stopped(status, SIGTRAP); 3836 3837 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3838 SYSCALL_REQUIRE( 3839 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3840 3841 DPRINTF("Before checking siginfo_t\n"); 3842 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 3843 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 3844 3845 if (setstep) { 3846 SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 3847 } 3848 3849 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 3850 3851 if (masked) { 3852 DPRINTF("kp_sigmask=" 3853 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 3854 PRIx32 "\n", 3855 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 3856 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 3857 3858 DPRINTF("kp.p_sigmask=" 3859 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 3860 PRIx32 "\n", 3861 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 3862 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 3863 3864 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 3865 sizeof(kp_sigmask))); 3866 } 3867 3868 if (ignored) { 3869 DPRINTF("kp_sigignore=" 3870 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 3871 PRIx32 "\n", 3872 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 3873 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 3874 3875 DPRINTF("kp.p_sigignore=" 3876 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 3877 PRIx32 "\n", 3878 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 3879 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 3880 3881 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 3882 sizeof(kp_sigignore))); 3883 } 3884 } 3885 3886 DPRINTF("Before resuming the child process where it left off and " 3887 "without signal to be sent\n"); 3888 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3889 3890 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3891 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3892 3893 validate_status_exited(status, exitval); 3894 3895 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3896 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3897} 3898 3899#define PTRACE_STEP(test, N, setstep) \ 3900ATF_TC(test); \ 3901ATF_TC_HEAD(test, tc) \ 3902{ \ 3903 atf_tc_set_md_var(tc, "descr", \ 3904 "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 3905} \ 3906 \ 3907ATF_TC_BODY(test, tc) \ 3908{ \ 3909 \ 3910 ptrace_step(N, setstep, false, false); \ 3911} 3912 3913PTRACE_STEP(step1, 1, 0) 3914PTRACE_STEP(step2, 2, 0) 3915PTRACE_STEP(step3, 3, 0) 3916PTRACE_STEP(step4, 4, 0) 3917PTRACE_STEP(setstep1, 1, 1) 3918PTRACE_STEP(setstep2, 2, 1) 3919PTRACE_STEP(setstep3, 3, 1) 3920PTRACE_STEP(setstep4, 4, 1) 3921 3922ATF_TC(step_signalmasked); 3923ATF_TC_HEAD(step_signalmasked, tc) 3924{ 3925 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with masked SIGTRAP"); 3926} 3927 3928ATF_TC_BODY(step_signalmasked, tc) 3929{ 3930 3931 ptrace_step(1, 0, true, false); 3932} 3933 3934ATF_TC(step_signalignored); 3935ATF_TC_HEAD(step_signalignored, tc) 3936{ 3937 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with ignored SIGTRAP"); 3938} 3939 3940ATF_TC_BODY(step_signalignored, tc) 3941{ 3942 3943 ptrace_step(1, 0, false, true); 3944} 3945#endif 3946 3947/// ---------------------------------------------------------------------------- 3948 3949static void 3950ptrace_kill(const char *type) 3951{ 3952 const int sigval = SIGSTOP; 3953 pid_t child, wpid; 3954#if defined(TWAIT_HAVE_STATUS) 3955 int status; 3956#endif 3957 3958 DPRINTF("Before forking process PID=%d\n", getpid()); 3959 SYSCALL_REQUIRE((child = fork()) != -1); 3960 if (child == 0) { 3961 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3962 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3963 3964 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3965 FORKEE_ASSERT(raise(sigval) == 0); 3966 3967 /* NOTREACHED */ 3968 FORKEE_ASSERTX(0 && 3969 "Child should be terminated by a signal from its parent"); 3970 } 3971 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3972 3973 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3974 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3975 3976 validate_status_stopped(status, sigval); 3977 3978 DPRINTF("Before killing the child process with %s\n", type); 3979 if (strcmp(type, "ptrace(PT_KILL)") == 0) { 3980 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 3981 } else if (strcmp(type, "kill(SIGKILL)") == 0) { 3982 kill(child, SIGKILL); 3983 } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 3984 setpgid(child, 0); 3985 killpg(getpgid(child), SIGKILL); 3986 } 3987 3988 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3989 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3990 3991 validate_status_signaled(status, SIGKILL, 0); 3992 3993 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3994 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3995} 3996 3997#define PTRACE_KILL(test, type) \ 3998ATF_TC(test); \ 3999ATF_TC_HEAD(test, tc) \ 4000{ \ 4001 atf_tc_set_md_var(tc, "descr", \ 4002 "Verify killing the child with " type); \ 4003} \ 4004 \ 4005ATF_TC_BODY(test, tc) \ 4006{ \ 4007 \ 4008 ptrace_kill(type); \ 4009} 4010 4011// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 4012PTRACE_KILL(kill1, "ptrace(PT_KILL)") 4013PTRACE_KILL(kill2, "kill(SIGKILL)") 4014PTRACE_KILL(kill3, "killpg(SIGKILL)") 4015 4016/// ---------------------------------------------------------------------------- 4017 4018static void 4019traceme_lwpinfo(const int threads) 4020{ 4021 const int sigval = SIGSTOP; 4022 const int sigval2 = SIGINT; 4023 pid_t child, wpid; 4024#if defined(TWAIT_HAVE_STATUS) 4025 int status; 4026#endif 4027 struct ptrace_lwpinfo lwp = {0, 0}; 4028 struct ptrace_siginfo info; 4029 4030 /* Maximum number of supported threads in this test */ 4031 pthread_t t[3]; 4032 int n, rv; 4033 4034 ATF_REQUIRE((int)__arraycount(t) >= threads); 4035 4036 DPRINTF("Before forking process PID=%d\n", getpid()); 4037 SYSCALL_REQUIRE((child = fork()) != -1); 4038 if (child == 0) { 4039 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4040 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4041 4042 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4043 FORKEE_ASSERT(raise(sigval) == 0); 4044 4045 for (n = 0; n < threads; n++) { 4046 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 4047 FORKEE_ASSERT(rv == 0); 4048 } 4049 4050 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 4051 FORKEE_ASSERT(raise(sigval2) == 0); 4052 4053 /* NOTREACHED */ 4054 FORKEE_ASSERTX(0 && "Not reached"); 4055 } 4056 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4057 4058 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4059 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4060 4061 validate_status_stopped(status, sigval); 4062 4063 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4064 SYSCALL_REQUIRE( 4065 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4066 4067 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4068 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4069 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4070 info.psi_siginfo.si_errno); 4071 4072 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4073 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4074 4075 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4076 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4077 4078 DPRINTF("Assert that there exists a single thread only\n"); 4079 ATF_REQUIRE(lwp.pl_lwpid > 0); 4080 4081 DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 4082 lwp.pl_lwpid); 4083 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 4084 4085 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4086 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4087 4088 DPRINTF("Assert that there exists a single thread only\n"); 4089 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 4090 4091 DPRINTF("Before resuming the child process where it left off and " 4092 "without signal to be sent\n"); 4093 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4094 4095 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4096 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4097 4098 validate_status_stopped(status, sigval2); 4099 4100 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4101 SYSCALL_REQUIRE( 4102 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4103 4104 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4105 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4106 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4107 info.psi_siginfo.si_errno); 4108 4109 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 4110 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4111 4112 memset(&lwp, 0, sizeof(lwp)); 4113 4114 for (n = 0; n <= threads; n++) { 4115 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4116 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4117 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4118 4119 DPRINTF("Assert that the thread exists\n"); 4120 ATF_REQUIRE(lwp.pl_lwpid > 0); 4121 4122 DPRINTF("Assert that lwp thread %d received expected event\n", 4123 lwp.pl_lwpid); 4124 FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ? 4125 PL_EVENT_SIGNAL : PL_EVENT_NONE); 4126 } 4127 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4128 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4129 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4130 4131 DPRINTF("Assert that there are no more threads\n"); 4132 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 4133 4134 DPRINTF("Before resuming the child process where it left off and " 4135 "without signal to be sent\n"); 4136 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 4137 4138 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4139 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4140 4141 validate_status_signaled(status, SIGKILL, 0); 4142 4143 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4144 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4145} 4146 4147#define TRACEME_LWPINFO(test, threads) \ 4148ATF_TC(test); \ 4149ATF_TC_HEAD(test, tc) \ 4150{ \ 4151 atf_tc_set_md_var(tc, "descr", \ 4152 "Verify LWPINFO with the child with " #threads \ 4153 " spawned extra threads"); \ 4154} \ 4155 \ 4156ATF_TC_BODY(test, tc) \ 4157{ \ 4158 \ 4159 traceme_lwpinfo(threads); \ 4160} 4161 4162TRACEME_LWPINFO(traceme_lwpinfo0, 0) 4163TRACEME_LWPINFO(traceme_lwpinfo1, 1) 4164TRACEME_LWPINFO(traceme_lwpinfo2, 2) 4165TRACEME_LWPINFO(traceme_lwpinfo3, 3) 4166 4167/// ---------------------------------------------------------------------------- 4168 4169#if defined(TWAIT_HAVE_PID) 4170static void 4171attach_lwpinfo(const int threads) 4172{ 4173 const int sigval = SIGINT; 4174 struct msg_fds parent_tracee, parent_tracer; 4175 const int exitval_tracer = 10; 4176 pid_t tracee, tracer, wpid; 4177 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 4178#if defined(TWAIT_HAVE_STATUS) 4179 int status; 4180#endif 4181 struct ptrace_lwpinfo lwp = {0, 0}; 4182 struct ptrace_siginfo info; 4183 4184 /* Maximum number of supported threads in this test */ 4185 pthread_t t[3]; 4186 int n, rv; 4187 4188 DPRINTF("Spawn tracee\n"); 4189 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 4190 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 4191 tracee = atf_utils_fork(); 4192 if (tracee == 0) { 4193 /* Wait for message from the parent */ 4194 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 4195 4196 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 4197 4198 for (n = 0; n < threads; n++) { 4199 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 4200 FORKEE_ASSERT(rv == 0); 4201 } 4202 4203 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 4204 4205 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4206 FORKEE_ASSERT(raise(sigval) == 0); 4207 4208 /* NOTREACHED */ 4209 FORKEE_ASSERTX(0 && "Not reached"); 4210 } 4211 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 4212 4213 DPRINTF("Spawn debugger\n"); 4214 tracer = atf_utils_fork(); 4215 if (tracer == 0) { 4216 /* No IPC to communicate with the child */ 4217 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 4218 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 4219 4220 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 4221 FORKEE_REQUIRE_SUCCESS( 4222 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4223 4224 forkee_status_stopped(status, SIGSTOP); 4225 4226 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4227 "tracee"); 4228 FORKEE_ASSERT( 4229 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 4230 4231 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4232 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4233 "si_errno=%#x\n", 4234 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4235 info.psi_siginfo.si_errno); 4236 4237 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 4238 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 4239 4240 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4241 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 4242 != -1); 4243 4244 DPRINTF("Assert that there exists a thread\n"); 4245 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 4246 4247 DPRINTF("Assert that lwp thread %d received event " 4248 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 4249 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 4250 4251 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 4252 "tracee\n"); 4253 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 4254 != -1); 4255 4256 DPRINTF("Assert that there are no more lwp threads in " 4257 "tracee\n"); 4258 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 4259 4260 /* Resume tracee with PT_CONTINUE */ 4261 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 4262 4263 /* Inform parent that tracer has attached to tracee */ 4264 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 4265 4266 /* Wait for parent */ 4267 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 4268 4269 /* Wait for tracee and assert that it raised a signal */ 4270 FORKEE_REQUIRE_SUCCESS( 4271 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4272 4273 forkee_status_stopped(status, SIGINT); 4274 4275 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4276 "child"); 4277 FORKEE_ASSERT( 4278 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 4279 4280 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4281 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4282 "si_errno=%#x\n", 4283 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4284 info.psi_siginfo.si_errno); 4285 4286 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 4287 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 4288 4289 memset(&lwp, 0, sizeof(lwp)); 4290 4291 for (n = 0; n <= threads; n++) { 4292 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 4293 "child\n"); 4294 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 4295 sizeof(lwp)) != -1); 4296 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4297 4298 DPRINTF("Assert that the thread exists\n"); 4299 FORKEE_ASSERT(lwp.pl_lwpid > 0); 4300 4301 DPRINTF("Assert that lwp thread %d received expected " 4302 "event\n", lwp.pl_lwpid); 4303 FORKEE_ASSERT_EQ(lwp.pl_event, 4304 info.psi_lwpid == lwp.pl_lwpid ? 4305 PL_EVENT_SIGNAL : PL_EVENT_NONE); 4306 } 4307 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 4308 "tracee\n"); 4309 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 4310 != -1); 4311 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4312 4313 DPRINTF("Assert that there are no more threads\n"); 4314 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 4315 4316 DPRINTF("Before resuming the child process where it left off " 4317 "and without signal to be sent\n"); 4318 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 4319 != -1); 4320 4321 /* Wait for tracee and assert that it exited */ 4322 FORKEE_REQUIRE_SUCCESS( 4323 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4324 4325 forkee_status_signaled(status, SIGKILL, 0); 4326 4327 DPRINTF("Before exiting of the tracer process\n"); 4328 _exit(exitval_tracer); 4329 } 4330 4331 DPRINTF("Wait for the tracer to attach to the tracee\n"); 4332 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 4333 4334 DPRINTF("Resume the tracee and spawn threads\n"); 4335 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 4336 4337 DPRINTF("Resume the tracee and let it exit\n"); 4338 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 4339 4340 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 4341 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 4342 4343 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 4344 TWAIT_FNAME); 4345 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 4346 tracer); 4347 4348 validate_status_exited(status, exitval_tracer); 4349 4350 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 4351 TWAIT_FNAME); 4352 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 4353 tracee); 4354 4355 validate_status_signaled(status, SIGKILL, 0); 4356 4357 msg_close(&parent_tracer); 4358 msg_close(&parent_tracee); 4359} 4360 4361#define ATTACH_LWPINFO(test, threads) \ 4362ATF_TC(test); \ 4363ATF_TC_HEAD(test, tc) \ 4364{ \ 4365 atf_tc_set_md_var(tc, "descr", \ 4366 "Verify LWPINFO with the child with " #threads \ 4367 " spawned extra threads (tracer is not the original " \ 4368 "parent)"); \ 4369} \ 4370 \ 4371ATF_TC_BODY(test, tc) \ 4372{ \ 4373 \ 4374 attach_lwpinfo(threads); \ 4375} 4376 4377ATTACH_LWPINFO(attach_lwpinfo0, 0) 4378ATTACH_LWPINFO(attach_lwpinfo1, 1) 4379ATTACH_LWPINFO(attach_lwpinfo2, 2) 4380ATTACH_LWPINFO(attach_lwpinfo3, 3) 4381#endif 4382 4383/// ---------------------------------------------------------------------------- 4384 4385static void 4386ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 4387{ 4388 const int exitval = 5; 4389 const int sigval = SIGINT; 4390 const int sigfaked = SIGTRAP; 4391 const int sicodefaked = TRAP_BRKPT; 4392 pid_t child, wpid; 4393 struct sigaction sa; 4394#if defined(TWAIT_HAVE_STATUS) 4395 int status; 4396#endif 4397 struct ptrace_siginfo info; 4398 memset(&info, 0, sizeof(info)); 4399 4400 DPRINTF("Before forking process PID=%d\n", getpid()); 4401 SYSCALL_REQUIRE((child = fork()) != -1); 4402 if (child == 0) { 4403 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4404 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4405 4406 sa.sa_sigaction = sah; 4407 sa.sa_flags = SA_SIGINFO; 4408 sigemptyset(&sa.sa_mask); 4409 4410 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 4411 != -1); 4412 4413 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4414 FORKEE_ASSERT(raise(sigval) == 0); 4415 4416 FORKEE_ASSERT_EQ(*signal_caught, 1); 4417 4418 DPRINTF("Before exiting of the child process\n"); 4419 _exit(exitval); 4420 } 4421 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4422 4423 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4424 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4425 4426 validate_status_stopped(status, sigval); 4427 4428 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4429 SYSCALL_REQUIRE( 4430 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4431 4432 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4433 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4434 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4435 info.psi_siginfo.si_errno); 4436 4437 if (faked) { 4438 DPRINTF("Before setting new faked signal to signo=%d " 4439 "si_code=%d\n", sigfaked, sicodefaked); 4440 info.psi_siginfo.si_signo = sigfaked; 4441 info.psi_siginfo.si_code = sicodefaked; 4442 } 4443 4444 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 4445 SYSCALL_REQUIRE( 4446 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 4447 4448 if (faked) { 4449 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4450 "child\n"); 4451 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 4452 sizeof(info)) != -1); 4453 4454 DPRINTF("Before checking siginfo_t\n"); 4455 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 4456 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 4457 } 4458 4459 DPRINTF("Before resuming the child process where it left off and " 4460 "without signal to be sent\n"); 4461 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 4462 faked ? sigfaked : sigval) != -1); 4463 4464 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4465 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4466 4467 validate_status_exited(status, exitval); 4468 4469 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4470 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4471} 4472 4473#define PTRACE_SIGINFO(test, faked) \ 4474ATF_TC(test); \ 4475ATF_TC_HEAD(test, tc) \ 4476{ \ 4477 atf_tc_set_md_var(tc, "descr", \ 4478 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 4479 "with%s setting signal to new value", faked ? "" : "out"); \ 4480} \ 4481 \ 4482static int test##_caught = 0; \ 4483 \ 4484static void \ 4485test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 4486{ \ 4487 if (faked) { \ 4488 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 4489 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 4490 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 4491 } else { \ 4492 FORKEE_ASSERT_EQ(sig, SIGINT); \ 4493 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 4494 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 4495 } \ 4496 \ 4497 ++ test##_caught; \ 4498} \ 4499 \ 4500ATF_TC_BODY(test, tc) \ 4501{ \ 4502 \ 4503 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 4504} 4505 4506PTRACE_SIGINFO(siginfo_set_unmodified, false) 4507PTRACE_SIGINFO(siginfo_set_faked, true) 4508 4509/// ---------------------------------------------------------------------------- 4510 4511ATF_TC(traceme_exec); 4512ATF_TC_HEAD(traceme_exec, tc) 4513{ 4514 atf_tc_set_md_var(tc, "descr", 4515 "Detect SIGTRAP TRAP_EXEC from tracee"); 4516} 4517 4518ATF_TC_BODY(traceme_exec, tc) 4519{ 4520 const int sigval = SIGTRAP; 4521 pid_t child, wpid; 4522#if defined(TWAIT_HAVE_STATUS) 4523 int status; 4524#endif 4525 4526 struct ptrace_siginfo info; 4527 memset(&info, 0, sizeof(info)); 4528 4529 DPRINTF("Before forking process PID=%d\n", getpid()); 4530 SYSCALL_REQUIRE((child = fork()) != -1); 4531 if (child == 0) { 4532 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4533 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4534 4535 DPRINTF("Before calling execve(2) from child\n"); 4536 execlp("/bin/echo", "/bin/echo", NULL); 4537 4538 FORKEE_ASSERT(0 && "Not reached"); 4539 } 4540 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4541 4542 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4543 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4544 4545 validate_status_stopped(status, sigval); 4546 4547 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4548 SYSCALL_REQUIRE( 4549 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4550 4551 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4552 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4553 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4554 info.psi_siginfo.si_errno); 4555 4556 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4557 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4558 4559 DPRINTF("Before resuming the child process where it left off and " 4560 "without signal to be sent\n"); 4561 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4562 4563 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4564 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4565 4566 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4567 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4568} 4569 4570/// ---------------------------------------------------------------------------- 4571 4572static volatile int done; 4573 4574static void * 4575trace_threads_cb(void *arg __unused) 4576{ 4577 4578 done++; 4579 4580 while (done < 3) 4581 continue; 4582 4583 return NULL; 4584} 4585 4586static void 4587trace_threads(bool trace_create, bool trace_exit) 4588{ 4589 const int sigval = SIGSTOP; 4590 pid_t child, wpid; 4591#if defined(TWAIT_HAVE_STATUS) 4592 int status; 4593#endif 4594 ptrace_state_t state; 4595 const int slen = sizeof(state); 4596 ptrace_event_t event; 4597 const int elen = sizeof(event); 4598 struct ptrace_siginfo info; 4599 4600 pthread_t t[3]; 4601 int rv; 4602 size_t n; 4603 lwpid_t lid; 4604 4605 /* Track created and exited threads */ 4606 bool traced_lwps[__arraycount(t)]; 4607 4608 atf_tc_skip("PR kern/51995"); 4609 4610 DPRINTF("Before forking process PID=%d\n", getpid()); 4611 SYSCALL_REQUIRE((child = fork()) != -1); 4612 if (child == 0) { 4613 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4614 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4615 4616 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4617 FORKEE_ASSERT(raise(sigval) == 0); 4618 4619 for (n = 0; n < __arraycount(t); n++) { 4620 rv = pthread_create(&t[n], NULL, trace_threads_cb, 4621 NULL); 4622 FORKEE_ASSERT(rv == 0); 4623 } 4624 4625 for (n = 0; n < __arraycount(t); n++) { 4626 rv = pthread_join(t[n], NULL); 4627 FORKEE_ASSERT(rv == 0); 4628 } 4629 4630 /* 4631 * There is race between _exit() and pthread_join() detaching 4632 * a thread. For simplicity kill the process after detecting 4633 * LWP events. 4634 */ 4635 while (true) 4636 continue; 4637 4638 FORKEE_ASSERT(0 && "Not reached"); 4639 } 4640 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4641 4642 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4643 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4644 4645 validate_status_stopped(status, sigval); 4646 4647 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4648 SYSCALL_REQUIRE( 4649 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4650 4651 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4652 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4653 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4654 info.psi_siginfo.si_errno); 4655 4656 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4657 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4658 4659 DPRINTF("Set LWP event mask for the child %d\n", child); 4660 memset(&event, 0, sizeof(event)); 4661 if (trace_create) 4662 event.pe_set_event |= PTRACE_LWP_CREATE; 4663 if (trace_exit) 4664 event.pe_set_event |= PTRACE_LWP_EXIT; 4665 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4666 4667 DPRINTF("Before resuming the child process where it left off and " 4668 "without signal to be sent\n"); 4669 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4670 4671 memset(traced_lwps, 0, sizeof(traced_lwps)); 4672 4673 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 4674 DPRINTF("Before calling %s() for the child - expected stopped " 4675 "SIGTRAP\n", TWAIT_FNAME); 4676 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4677 child); 4678 4679 validate_status_stopped(status, SIGTRAP); 4680 4681 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4682 "child\n"); 4683 SYSCALL_REQUIRE( 4684 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4685 4686 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4687 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4688 "si_errno=%#x\n", 4689 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4690 info.psi_siginfo.si_errno); 4691 4692 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4693 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 4694 4695 SYSCALL_REQUIRE( 4696 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4697 4698 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 4699 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 4700 4701 lid = state.pe_lwp; 4702 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 4703 4704 traced_lwps[lid - 1] = true; 4705 4706 DPRINTF("Before resuming the child process where it left off " 4707 "and without signal to be sent\n"); 4708 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4709 } 4710 4711 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 4712 DPRINTF("Before calling %s() for the child - expected stopped " 4713 "SIGTRAP\n", TWAIT_FNAME); 4714 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4715 child); 4716 4717 validate_status_stopped(status, SIGTRAP); 4718 4719 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4720 "child\n"); 4721 SYSCALL_REQUIRE( 4722 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4723 4724 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4725 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4726 "si_errno=%#x\n", 4727 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4728 info.psi_siginfo.si_errno); 4729 4730 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4731 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 4732 4733 SYSCALL_REQUIRE( 4734 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4735 4736 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 4737 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 4738 4739 lid = state.pe_lwp; 4740 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 4741 4742 if (trace_create) { 4743 ATF_REQUIRE(traced_lwps[lid - 1] == true); 4744 traced_lwps[lid - 1] = false; 4745 } 4746 4747 DPRINTF("Before resuming the child process where it left off " 4748 "and without signal to be sent\n"); 4749 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4750 } 4751 4752 kill(child, SIGKILL); 4753 4754 DPRINTF("Before calling %s() for the child - expected exited\n", 4755 TWAIT_FNAME); 4756 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4757 4758 validate_status_signaled(status, SIGKILL, 0); 4759 4760 DPRINTF("Before calling %s() for the child - expected no process\n", 4761 TWAIT_FNAME); 4762 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4763} 4764 4765#define TRACE_THREADS(test, trace_create, trace_exit) \ 4766ATF_TC(test); \ 4767ATF_TC_HEAD(test, tc) \ 4768{ \ 4769 atf_tc_set_md_var(tc, "descr", \ 4770 "Verify spawning threads with%s tracing LWP create and" \ 4771 "with%s tracing LWP exit", trace_create ? "" : "out", \ 4772 trace_exit ? "" : "out"); \ 4773} \ 4774 \ 4775ATF_TC_BODY(test, tc) \ 4776{ \ 4777 \ 4778 trace_threads(trace_create, trace_exit); \ 4779} 4780 4781TRACE_THREADS(trace_thread1, false, false) 4782TRACE_THREADS(trace_thread2, false, true) 4783TRACE_THREADS(trace_thread3, true, false) 4784TRACE_THREADS(trace_thread4, true, true) 4785 4786/// ---------------------------------------------------------------------------- 4787 4788ATF_TC(signal_mask_unrelated); 4789ATF_TC_HEAD(signal_mask_unrelated, tc) 4790{ 4791 atf_tc_set_md_var(tc, "descr", 4792 "Verify that masking single unrelated signal does not stop tracer " 4793 "from catching other signals"); 4794} 4795 4796ATF_TC_BODY(signal_mask_unrelated, tc) 4797{ 4798 const int exitval = 5; 4799 const int sigval = SIGSTOP; 4800 const int sigmasked = SIGTRAP; 4801 const int signotmasked = SIGINT; 4802 pid_t child, wpid; 4803#if defined(TWAIT_HAVE_STATUS) 4804 int status; 4805#endif 4806 sigset_t intmask; 4807 4808 DPRINTF("Before forking process PID=%d\n", getpid()); 4809 SYSCALL_REQUIRE((child = fork()) != -1); 4810 if (child == 0) { 4811 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4812 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4813 4814 sigemptyset(&intmask); 4815 sigaddset(&intmask, sigmasked); 4816 sigprocmask(SIG_BLOCK, &intmask, NULL); 4817 4818 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4819 FORKEE_ASSERT(raise(sigval) == 0); 4820 4821 DPRINTF("Before raising %s from child\n", 4822 strsignal(signotmasked)); 4823 FORKEE_ASSERT(raise(signotmasked) == 0); 4824 4825 DPRINTF("Before exiting of the child process\n"); 4826 _exit(exitval); 4827 } 4828 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4829 4830 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4831 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4832 4833 validate_status_stopped(status, sigval); 4834 4835 DPRINTF("Before resuming the child process where it left off and " 4836 "without signal to be sent\n"); 4837 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4838 4839 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4840 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4841 4842 validate_status_stopped(status, signotmasked); 4843 4844 DPRINTF("Before resuming the child process where it left off and " 4845 "without signal to be sent\n"); 4846 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4847 4848 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4849 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4850 4851 validate_status_exited(status, exitval); 4852 4853 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4854 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4855} 4856 4857/// ---------------------------------------------------------------------------- 4858 4859ATF_TC(signal5); 4860ATF_TC_HEAD(signal5, tc) 4861{ 4862 atf_tc_set_md_var(tc, "descr", 4863 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4864 "catching exec() breakpoint"); 4865} 4866 4867ATF_TC_BODY(signal5, tc) 4868{ 4869 const int sigval = SIGSTOP; 4870 const int sigmasked = SIGTRAP; 4871 pid_t child, wpid; 4872#if defined(TWAIT_HAVE_STATUS) 4873 int status; 4874#endif 4875 struct ptrace_siginfo info; 4876 sigset_t intmask; 4877 4878 memset(&info, 0, sizeof(info)); 4879 4880 DPRINTF("Before forking process PID=%d\n", getpid()); 4881 SYSCALL_REQUIRE((child = fork()) != -1); 4882 if (child == 0) { 4883 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4884 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4885 4886 sigemptyset(&intmask); 4887 sigaddset(&intmask, sigmasked); 4888 sigprocmask(SIG_BLOCK, &intmask, NULL); 4889 4890 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4891 FORKEE_ASSERT(raise(sigval) == 0); 4892 4893 DPRINTF("Before calling execve(2) from child\n"); 4894 execlp("/bin/echo", "/bin/echo", NULL); 4895 4896 /* NOTREACHED */ 4897 FORKEE_ASSERTX(0 && "Not reached"); 4898 } 4899 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4900 4901 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4902 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4903 4904 validate_status_stopped(status, sigval); 4905 4906 DPRINTF("Before resuming the child process where it left off and " 4907 "without signal to be sent\n"); 4908 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4909 4910 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4911 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4912 4913 validate_status_stopped(status, sigmasked); 4914 4915 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4916 SYSCALL_REQUIRE( 4917 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4918 4919 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4920 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4921 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4922 info.psi_siginfo.si_errno); 4923 4924 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked); 4925 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4926 4927 DPRINTF("Before resuming the child process where it left off and " 4928 "without signal to be sent\n"); 4929 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4930 4931 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4932 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4933 4934 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4935 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4936} 4937 4938#if defined(TWAIT_HAVE_PID) 4939ATF_TC(signal6); 4940ATF_TC_HEAD(signal6, tc) 4941{ 4942 atf_tc_set_md_var(tc, "timeout", "5"); 4943 atf_tc_set_md_var(tc, "descr", 4944 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4945 "catching PTRACE_FORK breakpoint"); 4946} 4947 4948ATF_TC_BODY(signal6, tc) 4949{ 4950 const int exitval = 5; 4951 const int exitval2 = 15; 4952 const int sigval = SIGSTOP; 4953 const int sigmasked = SIGTRAP; 4954 pid_t child, child2, wpid; 4955#if defined(TWAIT_HAVE_STATUS) 4956 int status; 4957#endif 4958 sigset_t intmask; 4959 ptrace_state_t state; 4960 const int slen = sizeof(state); 4961 ptrace_event_t event; 4962 const int elen = sizeof(event); 4963 4964 atf_tc_expect_fail("PR kern/51918"); 4965 4966 DPRINTF("Before forking process PID=%d\n", getpid()); 4967 SYSCALL_REQUIRE((child = fork()) != -1); 4968 if (child == 0) { 4969 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4970 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4971 4972 sigemptyset(&intmask); 4973 sigaddset(&intmask, sigmasked); 4974 sigprocmask(SIG_BLOCK, &intmask, NULL); 4975 4976 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4977 FORKEE_ASSERT(raise(sigval) == 0); 4978 4979 FORKEE_ASSERT((child2 = fork()) != -1); 4980 4981 if (child2 == 0) 4982 _exit(exitval2); 4983 4984 FORKEE_REQUIRE_SUCCESS 4985 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4986 4987 forkee_status_exited(status, exitval2); 4988 4989 DPRINTF("Before exiting of the child process\n"); 4990 _exit(exitval); 4991 } 4992 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4993 4994 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4995 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4996 4997 validate_status_stopped(status, sigval); 4998 4999 DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 5000 event.pe_set_event = PTRACE_FORK; 5001 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5002 5003 DPRINTF("Before resuming the child process where it left off and " 5004 "without signal to be sent\n"); 5005 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5006 5007 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5008 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5009 5010 validate_status_stopped(status, sigmasked); 5011 5012 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5013 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 5014 5015 child2 = state.pe_other_pid; 5016 DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2); 5017 5018 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 5019 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 5020 child2); 5021 5022 validate_status_stopped(status, SIGTRAP); 5023 5024 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 5025 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 5026 ATF_REQUIRE_EQ(state.pe_other_pid, child); 5027 5028 DPRINTF("Before resuming the forkee process where it left off and " 5029 "without signal to be sent\n"); 5030 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 5031 5032 DPRINTF("Before resuming the child process where it left off and " 5033 "without signal to be sent\n"); 5034 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5035 5036 DPRINTF("Before calling %s() for the forkee - expected exited\n", 5037 TWAIT_FNAME); 5038 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 5039 child2); 5040 5041 validate_status_exited(status, exitval2); 5042 5043 DPRINTF("Before calling %s() for the forkee - expected no process\n", 5044 TWAIT_FNAME); 5045 TWAIT_REQUIRE_FAILURE(ECHILD, 5046 wpid = TWAIT_GENERIC(child2, &status, 0)); 5047 5048 DPRINTF("Before calling %s() for the child - expected stopped " 5049 "SIGCHLD\n", TWAIT_FNAME); 5050 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5051 5052 validate_status_stopped(status, SIGCHLD); 5053 5054 DPRINTF("Before resuming the child process where it left off and " 5055 "without signal to be sent\n"); 5056 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5057 5058 DPRINTF("Before calling %s() for the child - expected exited\n", 5059 TWAIT_FNAME); 5060 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5061 5062 validate_status_exited(status, exitval); 5063 5064 DPRINTF("Before calling %s() for the child - expected no process\n", 5065 TWAIT_FNAME); 5066 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5067} 5068#endif 5069 5070#if defined(TWAIT_HAVE_PID) 5071ATF_TC(signal7); 5072ATF_TC_HEAD(signal7, tc) 5073{ 5074 atf_tc_set_md_var(tc, "descr", 5075 "Verify that masking SIGTRAP in tracee does not stop tracer from " 5076 "catching PTRACE_VFORK breakpoint"); 5077} 5078 5079ATF_TC_BODY(signal7, tc) 5080{ 5081 const int exitval = 5; 5082 const int exitval2 = 15; 5083 const int sigval = SIGSTOP; 5084 const int sigmasked = SIGTRAP; 5085 pid_t child, child2, wpid; 5086#if defined(TWAIT_HAVE_STATUS) 5087 int status; 5088#endif 5089 sigset_t intmask; 5090 ptrace_state_t state; 5091 const int slen = sizeof(state); 5092 ptrace_event_t event; 5093 const int elen = sizeof(event); 5094 5095 atf_tc_expect_fail("PR kern/51918"); 5096 5097 DPRINTF("Before forking process PID=%d\n", getpid()); 5098 SYSCALL_REQUIRE((child = fork()) != -1); 5099 if (child == 0) { 5100 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5101 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5102 5103 sigemptyset(&intmask); 5104 sigaddset(&intmask, sigmasked); 5105 sigprocmask(SIG_BLOCK, &intmask, NULL); 5106 5107 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5108 FORKEE_ASSERT(raise(sigval) == 0); 5109 5110 FORKEE_ASSERT((child2 = fork()) != -1); 5111 5112 if (child2 == 0) 5113 _exit(exitval2); 5114 5115 FORKEE_REQUIRE_SUCCESS 5116 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 5117 5118 forkee_status_exited(status, exitval2); 5119 5120 DPRINTF("Before exiting of the child process\n"); 5121 _exit(exitval); 5122 } 5123 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5124 5125 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5126 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5127 5128 validate_status_stopped(status, sigval); 5129 5130 DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 5131 event.pe_set_event = PTRACE_VFORK; 5132 SYSCALL_REQUIRE( 5133 ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || 5134 errno == ENOTSUP); 5135 5136 DPRINTF("Before resuming the child process where it left off and " 5137 "without signal to be sent\n"); 5138 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5139 5140 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5141 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5142 5143 validate_status_stopped(status, sigmasked); 5144 5145 SYSCALL_REQUIRE( 5146 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5147 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 5148 5149 child2 = state.pe_other_pid; 5150 DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2); 5151 5152 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 5153 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 5154 child2); 5155 5156 validate_status_stopped(status, SIGTRAP); 5157 5158 SYSCALL_REQUIRE( 5159 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 5160 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 5161 ATF_REQUIRE_EQ(state.pe_other_pid, child); 5162 5163 DPRINTF("Before resuming the forkee process where it left off and " 5164 "without signal to be sent\n"); 5165 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 5166 5167 DPRINTF("Before resuming the child process where it left off and " 5168 "without signal to be sent\n"); 5169 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5170 5171 DPRINTF("Before calling %s() for the forkee - expected exited\n", 5172 TWAIT_FNAME); 5173 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 5174 child2); 5175 5176 validate_status_exited(status, exitval2); 5177 5178 DPRINTF("Before calling %s() for the forkee - expected no process\n", 5179 TWAIT_FNAME); 5180 TWAIT_REQUIRE_FAILURE(ECHILD, 5181 wpid = TWAIT_GENERIC(child2, &status, 0)); 5182 5183 DPRINTF("Before calling %s() for the child - expected stopped " 5184 "SIGCHLD\n", TWAIT_FNAME); 5185 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5186 5187 validate_status_stopped(status, SIGCHLD); 5188 5189 DPRINTF("Before resuming the child process where it left off and " 5190 "without signal to be sent\n"); 5191 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5192 5193 DPRINTF("Before calling %s() for the child - expected exited\n", 5194 TWAIT_FNAME); 5195 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5196 5197 validate_status_exited(status, exitval); 5198 5199 DPRINTF("Before calling %s() for the child - expected no process\n", 5200 TWAIT_FNAME); 5201 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5202} 5203#endif 5204 5205ATF_TC(signal8); 5206ATF_TC_HEAD(signal8, tc) 5207{ 5208 atf_tc_set_md_var(tc, "descr", 5209 "Verify that masking SIGTRAP in tracee does not stop tracer from " 5210 "catching PTRACE_VFORK_DONE breakpoint"); 5211} 5212 5213ATF_TC_BODY(signal8, tc) 5214{ 5215 const int exitval = 5; 5216 const int exitval2 = 15; 5217 const int sigval = SIGSTOP; 5218 const int sigmasked = SIGTRAP; 5219 pid_t child, child2, wpid; 5220#if defined(TWAIT_HAVE_STATUS) 5221 int status; 5222#endif 5223 sigset_t intmask; 5224 ptrace_state_t state; 5225 const int slen = sizeof(state); 5226 ptrace_event_t event; 5227 const int elen = sizeof(event); 5228 5229 atf_tc_expect_fail("PR kern/51918"); 5230 5231 DPRINTF("Before forking process PID=%d\n", getpid()); 5232 SYSCALL_REQUIRE((child = fork()) != -1); 5233 if (child == 0) { 5234 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5235 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5236 5237 sigemptyset(&intmask); 5238 sigaddset(&intmask, sigmasked); 5239 sigprocmask(SIG_BLOCK, &intmask, NULL); 5240 5241 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5242 FORKEE_ASSERT(raise(sigval) == 0); 5243 5244 FORKEE_ASSERT((child2 = vfork()) != -1); 5245 5246 if (child2 == 0) 5247 _exit(exitval2); 5248 5249 FORKEE_REQUIRE_SUCCESS 5250 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 5251 5252 forkee_status_exited(status, exitval2); 5253 5254 DPRINTF("Before exiting of the child process\n"); 5255 _exit(exitval); 5256 } 5257 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5258 5259 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5260 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5261 5262 validate_status_stopped(status, sigval); 5263 5264 DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", 5265 child); 5266 event.pe_set_event = PTRACE_VFORK_DONE; 5267 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5268 5269 DPRINTF("Before resuming the child process where it left off and " 5270 "without signal to be sent\n"); 5271 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5272 5273 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5274 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5275 5276 validate_status_stopped(status, sigmasked); 5277 5278 SYSCALL_REQUIRE( 5279 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5280 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 5281 5282 child2 = state.pe_other_pid; 5283 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); 5284 5285 DPRINTF("Before resuming the child process where it left off and " 5286 "without signal to be sent\n"); 5287 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5288 5289 DPRINTF("Before calling %s() for the child - expected stopped " 5290 "SIGCHLD\n", TWAIT_FNAME); 5291 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5292 5293 validate_status_stopped(status, SIGCHLD); 5294 5295 DPRINTF("Before resuming the child process where it left off and " 5296 "without signal to be sent\n"); 5297 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5298 5299 DPRINTF("Before calling %s() for the child - expected exited\n", 5300 TWAIT_FNAME); 5301 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5302 5303 validate_status_exited(status, exitval); 5304 5305 DPRINTF("Before calling %s() for the child - expected no process\n", 5306 TWAIT_FNAME); 5307 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5308} 5309 5310volatile lwpid_t the_lwp_id = 0; 5311 5312static void 5313lwp_main_func(void *arg) 5314{ 5315 the_lwp_id = _lwp_self(); 5316 _lwp_exit(); 5317} 5318 5319ATF_TC(signal9); 5320ATF_TC_HEAD(signal9, tc) 5321{ 5322 atf_tc_set_md_var(tc, "descr", 5323 "Verify that masking SIGTRAP in tracee does not stop tracer from " 5324 "catching PTRACE_LWP_CREATE breakpoint"); 5325} 5326 5327ATF_TC_BODY(signal9, tc) 5328{ 5329 const int exitval = 5; 5330 const int sigval = SIGSTOP; 5331 const int sigmasked = SIGTRAP; 5332 pid_t child, wpid; 5333#if defined(TWAIT_HAVE_STATUS) 5334 int status; 5335#endif 5336 sigset_t intmask; 5337 ptrace_state_t state; 5338 const int slen = sizeof(state); 5339 ptrace_event_t event; 5340 const int elen = sizeof(event); 5341 ucontext_t uc; 5342 lwpid_t lid; 5343 static const size_t ssize = 16*1024; 5344 void *stack; 5345 5346 atf_tc_expect_fail("PR kern/51918"); 5347 5348 DPRINTF("Before forking process PID=%d\n", getpid()); 5349 SYSCALL_REQUIRE((child = fork()) != -1); 5350 if (child == 0) { 5351 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5352 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5353 5354 sigemptyset(&intmask); 5355 sigaddset(&intmask, sigmasked); 5356 sigprocmask(SIG_BLOCK, &intmask, NULL); 5357 5358 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5359 FORKEE_ASSERT(raise(sigval) == 0); 5360 5361 DPRINTF("Before allocating memory for stack in child\n"); 5362 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5363 5364 DPRINTF("Before making context for new lwp in child\n"); 5365 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 5366 5367 DPRINTF("Before creating new in child\n"); 5368 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5369 5370 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5371 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5372 5373 DPRINTF("Before verifying that reported %d and running lid %d " 5374 "are the same\n", lid, the_lwp_id); 5375 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5376 5377 DPRINTF("Before exiting of the child process\n"); 5378 _exit(exitval); 5379 } 5380 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5381 5382 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5383 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5384 5385 validate_status_stopped(status, sigval); 5386 5387 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 5388 event.pe_set_event = PTRACE_LWP_CREATE; 5389 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5390 5391 DPRINTF("Before resuming the child process where it left off and " 5392 "without signal to be sent\n"); 5393 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5394 5395 DPRINTF("Before calling %s() for the child - expected stopped " 5396 "SIGTRAP\n", TWAIT_FNAME); 5397 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5398 5399 validate_status_stopped(status, sigmasked); 5400 5401 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5402 5403 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 5404 5405 lid = state.pe_lwp; 5406 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 5407 5408 DPRINTF("Before resuming the child process where it left off and " 5409 "without signal to be sent\n"); 5410 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5411 5412 DPRINTF("Before calling %s() for the child - expected exited\n", 5413 TWAIT_FNAME); 5414 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5415 5416 validate_status_exited(status, exitval); 5417 5418 DPRINTF("Before calling %s() for the child - expected no process\n", 5419 TWAIT_FNAME); 5420 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5421} 5422 5423ATF_TC(signal10); 5424ATF_TC_HEAD(signal10, tc) 5425{ 5426 atf_tc_set_md_var(tc, "descr", 5427 "Verify that masking SIGTRAP in tracee does not stop tracer from " 5428 "catching PTRACE_LWP_EXIT breakpoint"); 5429} 5430 5431ATF_TC_BODY(signal10, tc) 5432{ 5433 const int exitval = 5; 5434 const int sigval = SIGSTOP; 5435 const int sigmasked = SIGTRAP; 5436 pid_t child, wpid; 5437#if defined(TWAIT_HAVE_STATUS) 5438 int status; 5439#endif 5440 sigset_t intmask; 5441 ptrace_state_t state; 5442 const int slen = sizeof(state); 5443 ptrace_event_t event; 5444 const int elen = sizeof(event); 5445 ucontext_t uc; 5446 lwpid_t lid; 5447 static const size_t ssize = 16*1024; 5448 void *stack; 5449 5450 atf_tc_expect_fail("PR kern/51918"); 5451 5452 DPRINTF("Before forking process PID=%d\n", getpid()); 5453 SYSCALL_REQUIRE((child = fork()) != -1); 5454 if (child == 0) { 5455 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5456 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5457 5458 sigemptyset(&intmask); 5459 sigaddset(&intmask, sigmasked); 5460 sigprocmask(SIG_BLOCK, &intmask, NULL); 5461 5462 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5463 FORKEE_ASSERT(raise(sigval) == 0); 5464 5465 DPRINTF("Before allocating memory for stack in child\n"); 5466 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5467 5468 DPRINTF("Before making context for new lwp in child\n"); 5469 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 5470 5471 DPRINTF("Before creating new in child\n"); 5472 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5473 5474 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5475 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5476 5477 DPRINTF("Before verifying that reported %d and running lid %d " 5478 "are the same\n", lid, the_lwp_id); 5479 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5480 5481 DPRINTF("Before exiting of the child process\n"); 5482 _exit(exitval); 5483 } 5484 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5485 5486 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5487 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5488 5489 validate_status_stopped(status, sigval); 5490 5491 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 5492 event.pe_set_event = PTRACE_LWP_EXIT; 5493 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5494 5495 DPRINTF("Before resuming the child process where it left off and " 5496 "without signal to be sent\n"); 5497 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5498 5499 DPRINTF("Before calling %s() for the child - expected stopped " 5500 "SIGTRAP\n", TWAIT_FNAME); 5501 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5502 5503 validate_status_stopped(status, sigmasked); 5504 5505 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5506 5507 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 5508 5509 lid = state.pe_lwp; 5510 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 5511 5512 DPRINTF("Before resuming the child process where it left off and " 5513 "without signal to be sent\n"); 5514 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5515 5516 DPRINTF("Before calling %s() for the child - expected exited\n", 5517 TWAIT_FNAME); 5518 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5519 5520 validate_status_exited(status, exitval); 5521 5522 DPRINTF("Before calling %s() for the child - expected no process\n", 5523 TWAIT_FNAME); 5524 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5525} 5526 5527static void 5528lwp_main_stop(void *arg) 5529{ 5530 the_lwp_id = _lwp_self(); 5531 5532 raise(SIGTRAP); 5533 5534 _lwp_exit(); 5535} 5536 5537ATF_TC(suspend1); 5538ATF_TC_HEAD(suspend1, tc) 5539{ 5540 atf_tc_set_md_var(tc, "descr", 5541 "Verify that a thread can be suspended by a debugger and later " 5542 "resumed by a tracee"); 5543} 5544 5545ATF_TC_BODY(suspend1, tc) 5546{ 5547 const int exitval = 5; 5548 const int sigval = SIGSTOP; 5549 pid_t child, wpid; 5550#if defined(TWAIT_HAVE_STATUS) 5551 int status; 5552#endif 5553 ucontext_t uc; 5554 lwpid_t lid; 5555 static const size_t ssize = 16*1024; 5556 void *stack; 5557 struct ptrace_lwpinfo pl; 5558 struct ptrace_siginfo psi; 5559 volatile int go = 0; 5560 5561 // Feature pending for refactoring 5562 atf_tc_expect_fail("PR kern/51995"); 5563 5564 // Hangs with qemu 5565 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5566 5567 DPRINTF("Before forking process PID=%d\n", getpid()); 5568 SYSCALL_REQUIRE((child = fork()) != -1); 5569 if (child == 0) { 5570 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5571 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5572 5573 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5574 FORKEE_ASSERT(raise(sigval) == 0); 5575 5576 DPRINTF("Before allocating memory for stack in child\n"); 5577 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5578 5579 DPRINTF("Before making context for new lwp in child\n"); 5580 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 5581 5582 DPRINTF("Before creating new in child\n"); 5583 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5584 5585 while (go == 0) 5586 continue; 5587 5588 raise(SIGINT); 5589 5590 FORKEE_ASSERT(_lwp_continue(lid) == 0); 5591 5592 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5593 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5594 5595 DPRINTF("Before verifying that reported %d and running lid %d " 5596 "are the same\n", lid, the_lwp_id); 5597 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5598 5599 DPRINTF("Before exiting of the child process\n"); 5600 _exit(exitval); 5601 } 5602 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5603 5604 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5605 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5606 5607 validate_status_stopped(status, sigval); 5608 5609 DPRINTF("Before resuming the child process where it left off and " 5610 "without signal to be sent\n"); 5611 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5612 5613 DPRINTF("Before calling %s() for the child - expected stopped " 5614 "SIGTRAP\n", TWAIT_FNAME); 5615 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5616 5617 validate_status_stopped(status, SIGTRAP); 5618 5619 DPRINTF("Before reading siginfo and lwpid_t\n"); 5620 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5621 5622 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5623 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5624 5625 DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 5626 child, getpid()); 5627 SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 5628 5629 DPRINTF("Before resuming the child process where it left off and " 5630 "without signal to be sent\n"); 5631 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5632 5633 DPRINTF("Before calling %s() for the child - expected stopped " 5634 "SIGINT\n", TWAIT_FNAME); 5635 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5636 5637 validate_status_stopped(status, SIGINT); 5638 5639 pl.pl_lwpid = 0; 5640 5641 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5642 while (pl.pl_lwpid != 0) { 5643 5644 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5645 switch (pl.pl_lwpid) { 5646 case 1: 5647 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 5648 break; 5649 case 2: 5650 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 5651 break; 5652 } 5653 } 5654 5655 DPRINTF("Before resuming the child process where it left off and " 5656 "without signal to be sent\n"); 5657 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5658 5659 DPRINTF("Before calling %s() for the child - expected exited\n", 5660 TWAIT_FNAME); 5661 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5662 5663 validate_status_exited(status, exitval); 5664 5665 DPRINTF("Before calling %s() for the child - expected no process\n", 5666 TWAIT_FNAME); 5667 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5668} 5669 5670ATF_TC(suspend2); 5671ATF_TC_HEAD(suspend2, tc) 5672{ 5673 atf_tc_set_md_var(tc, "descr", 5674 "Verify that the while the only thread within a process is " 5675 "suspended, the whole process cannot be unstopped"); 5676} 5677 5678ATF_TC_BODY(suspend2, tc) 5679{ 5680 const int exitval = 5; 5681 const int sigval = SIGSTOP; 5682 pid_t child, wpid; 5683#if defined(TWAIT_HAVE_STATUS) 5684 int status; 5685#endif 5686 struct ptrace_siginfo psi; 5687 5688 // Feature pending for refactoring 5689 atf_tc_expect_fail("PR kern/51995"); 5690 5691 // Hangs with qemu 5692 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5693 5694 DPRINTF("Before forking process PID=%d\n", getpid()); 5695 SYSCALL_REQUIRE((child = fork()) != -1); 5696 if (child == 0) { 5697 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5698 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5699 5700 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5701 FORKEE_ASSERT(raise(sigval) == 0); 5702 5703 DPRINTF("Before exiting of the child process\n"); 5704 _exit(exitval); 5705 } 5706 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5707 5708 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5709 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5710 5711 validate_status_stopped(status, sigval); 5712 5713 DPRINTF("Before reading siginfo and lwpid_t\n"); 5714 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5715 5716 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5717 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5718 5719 DPRINTF("Before resuming the child process where it left off and " 5720 "without signal to be sent\n"); 5721 ATF_REQUIRE_ERRNO(EDEADLK, 5722 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 5723 5724 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 5725 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 5726 5727 DPRINTF("Before resuming the child process where it left off and " 5728 "without signal to be sent\n"); 5729 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5730 5731 DPRINTF("Before calling %s() for the child - expected exited\n", 5732 TWAIT_FNAME); 5733 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5734 5735 validate_status_exited(status, exitval); 5736 5737 DPRINTF("Before calling %s() for the child - expected no process\n", 5738 TWAIT_FNAME); 5739 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5740} 5741 5742ATF_TC(resume1); 5743ATF_TC_HEAD(resume1, tc) 5744{ 5745 atf_tc_set_md_var(tc, "timeout", "5"); 5746 atf_tc_set_md_var(tc, "descr", 5747 "Verify that a thread can be suspended by a debugger and later " 5748 "resumed by the debugger"); 5749} 5750 5751ATF_TC_BODY(resume1, tc) 5752{ 5753 struct msg_fds fds; 5754 const int exitval = 5; 5755 const int sigval = SIGSTOP; 5756 pid_t child, wpid; 5757 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 5758#if defined(TWAIT_HAVE_STATUS) 5759 int status; 5760#endif 5761 ucontext_t uc; 5762 lwpid_t lid; 5763 static const size_t ssize = 16*1024; 5764 void *stack; 5765 struct ptrace_lwpinfo pl; 5766 struct ptrace_siginfo psi; 5767 5768 // Feature pending for refactoring 5769 atf_tc_expect_fail("PR kern/51995"); 5770 5771 // Hangs with qemu 5772 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5773 5774 SYSCALL_REQUIRE(msg_open(&fds) == 0); 5775 5776 DPRINTF("Before forking process PID=%d\n", getpid()); 5777 SYSCALL_REQUIRE((child = fork()) != -1); 5778 if (child == 0) { 5779 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5780 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5781 5782 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5783 FORKEE_ASSERT(raise(sigval) == 0); 5784 5785 DPRINTF("Before allocating memory for stack in child\n"); 5786 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5787 5788 DPRINTF("Before making context for new lwp in child\n"); 5789 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 5790 5791 DPRINTF("Before creating new in child\n"); 5792 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5793 5794 CHILD_TO_PARENT("Message", fds, msg); 5795 5796 raise(SIGINT); 5797 5798 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5799 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5800 5801 DPRINTF("Before verifying that reported %d and running lid %d " 5802 "are the same\n", lid, the_lwp_id); 5803 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5804 5805 DPRINTF("Before exiting of the child process\n"); 5806 _exit(exitval); 5807 } 5808 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5809 5810 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5811 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5812 5813 validate_status_stopped(status, sigval); 5814 5815 DPRINTF("Before resuming the child process where it left off and " 5816 "without signal to be sent\n"); 5817 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5818 5819 DPRINTF("Before calling %s() for the child - expected stopped " 5820 "SIGTRAP\n", TWAIT_FNAME); 5821 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5822 5823 validate_status_stopped(status, SIGTRAP); 5824 5825 DPRINTF("Before reading siginfo and lwpid_t\n"); 5826 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5827 5828 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5829 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5830 5831 PARENT_FROM_CHILD("Message", fds, msg); 5832 5833 DPRINTF("Before resuming the child process where it left off and " 5834 "without signal to be sent\n"); 5835 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5836 5837 DPRINTF("Before calling %s() for the child - expected stopped " 5838 "SIGINT\n", TWAIT_FNAME); 5839 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5840 5841 validate_status_stopped(status, SIGINT); 5842 5843 pl.pl_lwpid = 0; 5844 5845 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5846 while (pl.pl_lwpid != 0) { 5847 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5848 switch (pl.pl_lwpid) { 5849 case 1: 5850 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 5851 break; 5852 case 2: 5853 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 5854 break; 5855 } 5856 } 5857 5858 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 5859 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 5860 5861 DPRINTF("Before resuming the child process where it left off and " 5862 "without signal to be sent\n"); 5863 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5864 5865 DPRINTF("Before calling %s() for the child - expected exited\n", 5866 TWAIT_FNAME); 5867 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5868 5869 validate_status_exited(status, exitval); 5870 5871 DPRINTF("Before calling %s() for the child - expected no process\n", 5872 TWAIT_FNAME); 5873 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5874 5875 msg_close(&fds); 5876 5877 DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 5878 sleep(10); 5879} 5880 5881ATF_TC(syscall1); 5882ATF_TC_HEAD(syscall1, tc) 5883{ 5884 atf_tc_set_md_var(tc, "descr", 5885 "Verify that getpid(2) can be traced with PT_SYSCALL"); 5886} 5887 5888ATF_TC_BODY(syscall1, tc) 5889{ 5890 const int exitval = 5; 5891 const int sigval = SIGSTOP; 5892 pid_t child, wpid; 5893#if defined(TWAIT_HAVE_STATUS) 5894 int status; 5895#endif 5896 struct ptrace_siginfo info; 5897 memset(&info, 0, sizeof(info)); 5898 5899 DPRINTF("Before forking process PID=%d\n", getpid()); 5900 SYSCALL_REQUIRE((child = fork()) != -1); 5901 if (child == 0) { 5902 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5903 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5904 5905 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5906 FORKEE_ASSERT(raise(sigval) == 0); 5907 5908 syscall(SYS_getpid); 5909 5910 DPRINTF("Before exiting of the child process\n"); 5911 _exit(exitval); 5912 } 5913 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5914 5915 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5916 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5917 5918 validate_status_stopped(status, sigval); 5919 5920 DPRINTF("Before resuming the child process where it left off and " 5921 "without signal to be sent\n"); 5922 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5923 5924 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5925 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5926 5927 validate_status_stopped(status, SIGTRAP); 5928 5929 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5930 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5931 5932 DPRINTF("Before checking siginfo_t and lwpid\n"); 5933 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5934 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5935 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 5936 5937 DPRINTF("Before resuming the child process where it left off and " 5938 "without signal to be sent\n"); 5939 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5940 5941 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5942 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5943 5944 validate_status_stopped(status, SIGTRAP); 5945 5946 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5947 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5948 5949 DPRINTF("Before checking siginfo_t and lwpid\n"); 5950 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5951 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5952 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 5953 5954 DPRINTF("Before resuming the child process where it left off and " 5955 "without signal to be sent\n"); 5956 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5957 5958 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5959 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5960 5961 validate_status_exited(status, exitval); 5962 5963 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5964 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5965} 5966 5967ATF_TC(syscallemu1); 5968ATF_TC_HEAD(syscallemu1, tc) 5969{ 5970 atf_tc_set_md_var(tc, "descr", 5971 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 5972} 5973 5974ATF_TC_BODY(syscallemu1, tc) 5975{ 5976 const int exitval = 5; 5977 const int sigval = SIGSTOP; 5978 pid_t child, wpid; 5979#if defined(TWAIT_HAVE_STATUS) 5980 int status; 5981#endif 5982 5983#if defined(__sparc__) && !defined(__sparc64__) 5984 /* syscallemu does not work on sparc (32-bit) */ 5985 atf_tc_expect_fail("PR kern/52166"); 5986#endif 5987 5988 DPRINTF("Before forking process PID=%d\n", getpid()); 5989 SYSCALL_REQUIRE((child = fork()) != -1); 5990 if (child == 0) { 5991 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5992 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5993 5994 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5995 FORKEE_ASSERT(raise(sigval) == 0); 5996 5997 syscall(SYS_exit, 100); 5998 5999 DPRINTF("Before exiting of the child process\n"); 6000 _exit(exitval); 6001 } 6002 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6003 6004 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6005 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6006 6007 validate_status_stopped(status, sigval); 6008 6009 DPRINTF("Before resuming the child process where it left off and " 6010 "without signal to be sent\n"); 6011 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6012 6013 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6014 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6015 6016 validate_status_stopped(status, SIGTRAP); 6017 6018 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 6019 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 6020 6021 DPRINTF("Before resuming the child process where it left off and " 6022 "without signal to be sent\n"); 6023 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6024 6025 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6026 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6027 6028 validate_status_stopped(status, SIGTRAP); 6029 6030 DPRINTF("Before resuming the child process where it left off and " 6031 "without signal to be sent\n"); 6032 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6033 6034 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6035 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6036 6037 validate_status_exited(status, exitval); 6038 6039 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6040 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6041} 6042 6043#include "t_ptrace_amd64_wait.h" 6044#include "t_ptrace_i386_wait.h" 6045#include "t_ptrace_x86_wait.h" 6046 6047ATF_TP_ADD_TCS(tp) 6048{ 6049 setvbuf(stdout, NULL, _IONBF, 0); 6050 setvbuf(stderr, NULL, _IONBF, 0); 6051 6052 ATF_TP_ADD_TC(tp, traceme_raise1); 6053 ATF_TP_ADD_TC(tp, traceme_raise2); 6054 ATF_TP_ADD_TC(tp, traceme_raise3); 6055 ATF_TP_ADD_TC(tp, traceme_raise4); 6056 ATF_TP_ADD_TC(tp, traceme_raise5); 6057 ATF_TP_ADD_TC(tp, traceme_raise6); 6058 ATF_TP_ADD_TC(tp, traceme_raise7); 6059 ATF_TP_ADD_TC(tp, traceme_raise8); 6060 ATF_TP_ADD_TC(tp, traceme_raise9); 6061 ATF_TP_ADD_TC(tp, traceme_raise10); 6062 6063 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 6064 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 6065 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 6066 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 6067 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 6068 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 6069 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 6070 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 6071 6072 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 6073 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 6074 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 6075 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 6076 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 6077 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 6078 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 6079 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 6080 6081 ATF_TP_ADD_TC(tp, traceme_crash_trap); 6082 ATF_TP_ADD_TC(tp, traceme_crash_segv); 6083 ATF_TP_ADD_TC(tp, traceme_crash_ill); 6084 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 6085 ATF_TP_ADD_TC(tp, traceme_crash_bus); 6086 6087 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 6088 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 6089 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 6090 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 6091 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 6092 6093 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 6094 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 6095 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 6096 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 6097 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 6098 6099 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 6100 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 6101 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 6102 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 6103 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 6104 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 6105 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 6106 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 6107 6108 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 6109 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 6110 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 6111 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 6112 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 6113 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 6114 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 6115 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 6116 6117 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 6118 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 6119 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 6120 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 6121 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 6122 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 6123 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 6124 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 6125 6126 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 6127 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 6128 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 6129 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 6130 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 6131 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 6132 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 6133 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 6134 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 6135 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 6136 6137 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 6138 6139 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 6140 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 6141 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 6142 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 6143 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 6144 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 6145 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 6146 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 6147 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 6148 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 6149 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 6150 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 6151 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 6152 6153 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 6154 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 6155 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 6156 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 6157 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 6158 6159 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 6160 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 6161 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 6162 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 6163 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 6164 6165 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 6166 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 6167 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 6168 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 6169 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 6170 6171 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 6172 6173 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 6174 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 6175 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 6176 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 6177 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 6178 6179 ATF_TP_ADD_TC_HAVE_PID(tp, 6180 unrelated_tracer_sees_signalmasked_crash_trap); 6181 ATF_TP_ADD_TC_HAVE_PID(tp, 6182 unrelated_tracer_sees_signalmasked_crash_segv); 6183 ATF_TP_ADD_TC_HAVE_PID(tp, 6184 unrelated_tracer_sees_signalmasked_crash_ill); 6185 ATF_TP_ADD_TC_HAVE_PID(tp, 6186 unrelated_tracer_sees_signalmasked_crash_fpe); 6187 ATF_TP_ADD_TC_HAVE_PID(tp, 6188 unrelated_tracer_sees_signalmasked_crash_bus); 6189 6190 ATF_TP_ADD_TC_HAVE_PID(tp, 6191 unrelated_tracer_sees_signalignored_crash_trap); 6192 ATF_TP_ADD_TC_HAVE_PID(tp, 6193 unrelated_tracer_sees_signalignored_crash_segv); 6194 ATF_TP_ADD_TC_HAVE_PID(tp, 6195 unrelated_tracer_sees_signalignored_crash_ill); 6196 ATF_TP_ADD_TC_HAVE_PID(tp, 6197 unrelated_tracer_sees_signalignored_crash_fpe); 6198 ATF_TP_ADD_TC_HAVE_PID(tp, 6199 unrelated_tracer_sees_signalignored_crash_bus); 6200 6201 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 6202 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 6203 ATF_TP_ADD_TC_HAVE_PID(tp, 6204 unrelated_tracer_sees_terminaton_before_the_parent); 6205 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 6206 6207 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 6208 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 6209 6210 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 6211 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 6212 6213 ATF_TP_ADD_TC_HAVE_PID(tp, 6214 tracee_sees_its_original_parent_getppid); 6215 ATF_TP_ADD_TC_HAVE_PID(tp, 6216 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 6217 ATF_TP_ADD_TC_HAVE_PID(tp, 6218 tracee_sees_its_original_parent_procfs_status); 6219 6220 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 6221 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 6222 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 6223 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 6224 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 6225 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 6226 6227 ATF_TP_ADD_TC(tp, fork1); 6228 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 6229 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 6230 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 6231 ATF_TP_ADD_TC(tp, fork5); 6232 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 6233 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 6234 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 6235 6236 ATF_TP_ADD_TC(tp, vfork1); 6237 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 6238 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 6239 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 6240 ATF_TP_ADD_TC(tp, vfork5); 6241 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 6242// thes tests hang on SMP machines, disable them for now 6243// ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 6244// ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 6245 6246 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 6247 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 6248 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 6249 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 6250 6251 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 6252 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 6253 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 6254 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 6255 6256 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 6257 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 6258 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 6259 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 6260 6261 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 6262 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 6263 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 6264 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 6265 6266 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 6267 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 6268 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 6269 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 6270 6271 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 6272 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 6273 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 6274 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 6275 6276 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 6277 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 6278 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 6279 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 6280 6281 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 6282 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 6283 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 6284 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 6285 6286 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 6287 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 6288 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 6289 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 6290 6291 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 6292 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 6293 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 6294 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 6295 6296 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 6297 6298 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 6299 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 6300 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 6301 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 6302 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 6303 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 6304 6305 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 6306 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 6307 6308 ATF_TP_ADD_TC_PT_STEP(tp, step1); 6309 ATF_TP_ADD_TC_PT_STEP(tp, step2); 6310 ATF_TP_ADD_TC_PT_STEP(tp, step3); 6311 ATF_TP_ADD_TC_PT_STEP(tp, step4); 6312 6313 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 6314 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 6315 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 6316 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 6317 6318 ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked); 6319 ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored); 6320 6321 ATF_TP_ADD_TC(tp, kill1); 6322 ATF_TP_ADD_TC(tp, kill2); 6323 ATF_TP_ADD_TC(tp, kill3); 6324 6325 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 6326 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 6327 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 6328 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 6329 6330 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 6331 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 6332 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 6333 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 6334 6335 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 6336 ATF_TP_ADD_TC(tp, siginfo_set_faked); 6337 6338 ATF_TP_ADD_TC(tp, traceme_exec); 6339 6340 ATF_TP_ADD_TC(tp, trace_thread1); 6341 ATF_TP_ADD_TC(tp, trace_thread2); 6342 ATF_TP_ADD_TC(tp, trace_thread3); 6343 ATF_TP_ADD_TC(tp, trace_thread4); 6344 6345 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 6346 6347 ATF_TP_ADD_TC(tp, signal5); 6348 ATF_TP_ADD_TC_HAVE_PID(tp, signal6); 6349 ATF_TP_ADD_TC_HAVE_PID(tp, signal7); 6350 ATF_TP_ADD_TC(tp, signal8); 6351 ATF_TP_ADD_TC(tp, signal9); 6352 ATF_TP_ADD_TC(tp, signal10); 6353 6354 ATF_TP_ADD_TC(tp, suspend1); 6355 ATF_TP_ADD_TC(tp, suspend2); 6356 6357 ATF_TP_ADD_TC(tp, resume1); 6358 6359 ATF_TP_ADD_TC(tp, syscall1); 6360 6361 ATF_TP_ADD_TC(tp, syscallemu1); 6362 6363 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 6364 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 6365 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 6366 6367 return atf_no_error(); 6368} 6369