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