t_ptrace_wait.c revision 1.108
1/* $NetBSD: t_ptrace_wait.c,v 1.108 2019/04/11 23:23:53 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.108 2019/04/11 23:23:53 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) 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,fun,tfork,tvfork,tvforkdone) \ 3122ATF_TC(name); \ 3123ATF_TC_HEAD(name, tc) \ 3124{ \ 3125 atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) " \ 3126 "called with 0%s%s%s in EVENT_MASK", \ 3127 tfork ? "|PTRACE_FORK" : "", \ 3128 tvfork ? "|PTRACE_VFORK" : "", \ 3129 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 3130} \ 3131 \ 3132ATF_TC_BODY(name, tc) \ 3133{ \ 3134 \ 3135 fork_body(fun, tfork, tvfork, tvforkdone); \ 3136} 3137 3138FORK_TEST(fork1, fork, false, false, false) 3139#if defined(TWAIT_HAVE_PID) 3140FORK_TEST(fork2, fork, true, false, false) 3141FORK_TEST(fork3, fork, false, true, false) 3142FORK_TEST(fork4, fork, true, true, false) 3143#endif 3144FORK_TEST(fork5, fork, false, false, true) 3145#if defined(TWAIT_HAVE_PID) 3146FORK_TEST(fork6, fork, true, false, true) 3147FORK_TEST(fork7, fork, false, true, true) 3148FORK_TEST(fork8, fork, true, true, true) 3149#endif 3150 3151FORK_TEST(vfork1, vfork, false, false, false) 3152#if defined(TWAIT_HAVE_PID) 3153FORK_TEST(vfork2, vfork, true, false, false) 3154FORK_TEST(vfork3, vfork, false, true, false) 3155FORK_TEST(vfork4, vfork, true, true, false) 3156#endif 3157FORK_TEST(vfork5, vfork, false, false, true) 3158#if defined(TWAIT_HAVE_PID) 3159FORK_TEST(vfork6, vfork, true, false, true) 3160FORK_TEST(vfork7, vfork, false, true, true) 3161FORK_TEST(vfork8, vfork, true, true, true) 3162#endif 3163 3164/// ---------------------------------------------------------------------------- 3165 3166static void 3167traceme_vfork_fork_body(pid_t (*fn)(void)) 3168{ 3169 const int exitval = 5; 3170 const int exitval2 = 15; 3171 pid_t child, child2 = 0, wpid; 3172#if defined(TWAIT_HAVE_STATUS) 3173 int status; 3174#endif 3175 3176 DPRINTF("Before forking process PID=%d\n", getpid()); 3177 SYSCALL_REQUIRE((child = vfork()) != -1); 3178 if (child == 0) { 3179 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3180 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3181 3182 FORKEE_ASSERT((child2 = (fn)()) != -1); 3183 3184 if (child2 == 0) 3185 _exit(exitval2); 3186 3187 FORKEE_REQUIRE_SUCCESS 3188 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3189 3190 forkee_status_exited(status, exitval2); 3191 3192 DPRINTF("Before exiting of the child process\n"); 3193 _exit(exitval); 3194 } 3195 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3196 3197 DPRINTF("Before calling %s() for the child - expected exited\n", 3198 TWAIT_FNAME); 3199 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3200 3201 validate_status_exited(status, exitval); 3202 3203 DPRINTF("Before calling %s() for the child - expected no process\n", 3204 TWAIT_FNAME); 3205 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3206} 3207 3208#define TRACEME_VFORK_FORK_TEST(name,fun) \ 3209ATF_TC(name); \ 3210ATF_TC_HEAD(name, tc) \ 3211{ \ 3212 atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) " \ 3213 "called from vfork(2)ed child"); \ 3214} \ 3215 \ 3216ATF_TC_BODY(name, tc) \ 3217{ \ 3218 \ 3219 traceme_vfork_fork_body(fun); \ 3220} 3221 3222TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork) 3223TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork) 3224 3225/// ---------------------------------------------------------------------------- 3226 3227enum bytes_transfer_type { 3228 BYTES_TRANSFER_DATA, 3229 BYTES_TRANSFER_DATAIO, 3230 BYTES_TRANSFER_TEXT, 3231 BYTES_TRANSFER_TEXTIO, 3232 BYTES_TRANSFER_AUXV 3233}; 3234 3235static int __used 3236bytes_transfer_dummy(int a, int b, int c, int d) 3237{ 3238 int e, f, g, h; 3239 3240 a *= 4; 3241 b += 3; 3242 c -= 2; 3243 d /= 1; 3244 3245 e = strtol("10", NULL, 10); 3246 f = strtol("20", NULL, 10); 3247 g = strtol("30", NULL, 10); 3248 h = strtol("40", NULL, 10); 3249 3250 return (a + b * c - d) + (e * f - g / h); 3251} 3252 3253static void 3254bytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 3255{ 3256 const int exitval = 5; 3257 const int sigval = SIGSTOP; 3258 pid_t child, wpid; 3259 bool skip = false; 3260 3261 int lookup_me = 0; 3262 uint8_t lookup_me8 = 0; 3263 uint16_t lookup_me16 = 0; 3264 uint32_t lookup_me32 = 0; 3265 uint64_t lookup_me64 = 0; 3266 3267 int magic = 0x13579246; 3268 uint8_t magic8 = 0xab; 3269 uint16_t magic16 = 0x1234; 3270 uint32_t magic32 = 0x98765432; 3271 uint64_t magic64 = 0xabcdef0123456789; 3272 3273 struct ptrace_io_desc io; 3274#if defined(TWAIT_HAVE_STATUS) 3275 int status; 3276#endif 3277 /* 513 is just enough, for the purposes of ATF it's good enough */ 3278 AuxInfo ai[513], *aip; 3279 3280 ATF_REQUIRE(size < sizeof(ai)); 3281 3282 /* Prepare variables for .TEXT transfers */ 3283 switch (type) { 3284 case BYTES_TRANSFER_TEXT: 3285 memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 3286 break; 3287 case BYTES_TRANSFER_TEXTIO: 3288 switch (size) { 3289 case 8: 3290 memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 3291 break; 3292 case 16: 3293 memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 3294 break; 3295 case 32: 3296 memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 3297 break; 3298 case 64: 3299 memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 3300 break; 3301 } 3302 break; 3303 default: 3304 break; 3305 } 3306 3307 /* Prepare variables for PIOD and AUXV transfers */ 3308 switch (type) { 3309 case BYTES_TRANSFER_TEXTIO: 3310 case BYTES_TRANSFER_DATAIO: 3311 io.piod_op = operation; 3312 switch (size) { 3313 case 8: 3314 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3315 (void *)bytes_transfer_dummy : 3316 &lookup_me8; 3317 io.piod_addr = &lookup_me8; 3318 io.piod_len = sizeof(lookup_me8); 3319 break; 3320 case 16: 3321 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3322 (void *)bytes_transfer_dummy : 3323 &lookup_me16; 3324 io.piod_addr = &lookup_me16; 3325 io.piod_len = sizeof(lookup_me16); 3326 break; 3327 case 32: 3328 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3329 (void *)bytes_transfer_dummy : 3330 &lookup_me32; 3331 io.piod_addr = &lookup_me32; 3332 io.piod_len = sizeof(lookup_me32); 3333 break; 3334 case 64: 3335 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3336 (void *)bytes_transfer_dummy : 3337 &lookup_me64; 3338 io.piod_addr = &lookup_me64; 3339 io.piod_len = sizeof(lookup_me64); 3340 break; 3341 default: 3342 break; 3343 } 3344 break; 3345 case BYTES_TRANSFER_AUXV: 3346 io.piod_op = operation; 3347 io.piod_offs = 0; 3348 io.piod_addr = ai; 3349 io.piod_len = size; 3350 break; 3351 default: 3352 break; 3353 } 3354 3355 DPRINTF("Before forking process PID=%d\n", getpid()); 3356 SYSCALL_REQUIRE((child = fork()) != -1); 3357 if (child == 0) { 3358 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3359 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3360 3361 switch (type) { 3362 case BYTES_TRANSFER_DATA: 3363 switch (operation) { 3364 case PT_READ_D: 3365 case PT_READ_I: 3366 lookup_me = magic; 3367 break; 3368 default: 3369 break; 3370 } 3371 break; 3372 case BYTES_TRANSFER_DATAIO: 3373 switch (operation) { 3374 case PIOD_READ_D: 3375 case PIOD_READ_I: 3376 switch (size) { 3377 case 8: 3378 lookup_me8 = magic8; 3379 break; 3380 case 16: 3381 lookup_me16 = magic16; 3382 break; 3383 case 32: 3384 lookup_me32 = magic32; 3385 break; 3386 case 64: 3387 lookup_me64 = magic64; 3388 break; 3389 default: 3390 break; 3391 } 3392 break; 3393 default: 3394 break; 3395 } 3396 default: 3397 break; 3398 } 3399 3400 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3401 FORKEE_ASSERT(raise(sigval) == 0); 3402 3403 /* Handle PIOD and PT separately as operation values overlap */ 3404 switch (type) { 3405 case BYTES_TRANSFER_DATA: 3406 switch (operation) { 3407 case PT_WRITE_D: 3408 case PT_WRITE_I: 3409 FORKEE_ASSERT_EQ(lookup_me, magic); 3410 break; 3411 default: 3412 break; 3413 } 3414 break; 3415 case BYTES_TRANSFER_DATAIO: 3416 switch (operation) { 3417 case PIOD_WRITE_D: 3418 case PIOD_WRITE_I: 3419 switch (size) { 3420 case 8: 3421 FORKEE_ASSERT_EQ(lookup_me8, magic8); 3422 break; 3423 case 16: 3424 FORKEE_ASSERT_EQ(lookup_me16, magic16); 3425 break; 3426 case 32: 3427 FORKEE_ASSERT_EQ(lookup_me32, magic32); 3428 break; 3429 case 64: 3430 FORKEE_ASSERT_EQ(lookup_me64, magic64); 3431 break; 3432 default: 3433 break; 3434 } 3435 break; 3436 default: 3437 break; 3438 } 3439 break; 3440 case BYTES_TRANSFER_TEXT: 3441 FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 3442 sizeof(magic)) == 0); 3443 break; 3444 case BYTES_TRANSFER_TEXTIO: 3445 switch (size) { 3446 case 8: 3447 FORKEE_ASSERT(memcmp(&magic8, 3448 bytes_transfer_dummy, 3449 sizeof(magic8)) == 0); 3450 break; 3451 case 16: 3452 FORKEE_ASSERT(memcmp(&magic16, 3453 bytes_transfer_dummy, 3454 sizeof(magic16)) == 0); 3455 break; 3456 case 32: 3457 FORKEE_ASSERT(memcmp(&magic32, 3458 bytes_transfer_dummy, 3459 sizeof(magic32)) == 0); 3460 break; 3461 case 64: 3462 FORKEE_ASSERT(memcmp(&magic64, 3463 bytes_transfer_dummy, 3464 sizeof(magic64)) == 0); 3465 break; 3466 } 3467 break; 3468 default: 3469 break; 3470 } 3471 3472 DPRINTF("Before exiting of the child process\n"); 3473 _exit(exitval); 3474 } 3475 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3476 3477 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3478 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3479 3480 validate_status_stopped(status, sigval); 3481 3482 /* Check PaX MPROTECT */ 3483 if (!can_we_write_to_text(child)) { 3484 switch (type) { 3485 case BYTES_TRANSFER_TEXTIO: 3486 switch (operation) { 3487 case PIOD_WRITE_D: 3488 case PIOD_WRITE_I: 3489 skip = true; 3490 break; 3491 default: 3492 break; 3493 } 3494 break; 3495 case BYTES_TRANSFER_TEXT: 3496 switch (operation) { 3497 case PT_WRITE_D: 3498 case PT_WRITE_I: 3499 skip = true; 3500 break; 3501 default: 3502 break; 3503 } 3504 break; 3505 default: 3506 break; 3507 } 3508 } 3509 3510 /* Bailout cleanly killing the child process */ 3511 if (skip) { 3512 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 3513 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3514 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3515 child); 3516 3517 validate_status_signaled(status, SIGKILL, 0); 3518 3519 atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 3520 } 3521 3522 DPRINTF("Calling operation to transfer bytes between child=%d and " 3523 "parent=%d\n", child, getpid()); 3524 3525 switch (type) { 3526 case BYTES_TRANSFER_TEXTIO: 3527 case BYTES_TRANSFER_DATAIO: 3528 case BYTES_TRANSFER_AUXV: 3529 switch (operation) { 3530 case PIOD_WRITE_D: 3531 case PIOD_WRITE_I: 3532 switch (size) { 3533 case 8: 3534 lookup_me8 = magic8; 3535 break; 3536 case 16: 3537 lookup_me16 = magic16; 3538 break; 3539 case 32: 3540 lookup_me32 = magic32; 3541 break; 3542 case 64: 3543 lookup_me64 = magic64; 3544 break; 3545 default: 3546 break; 3547 } 3548 break; 3549 default: 3550 break; 3551 } 3552 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 3553 switch (operation) { 3554 case PIOD_READ_D: 3555 case PIOD_READ_I: 3556 switch (size) { 3557 case 8: 3558 ATF_REQUIRE_EQ(lookup_me8, magic8); 3559 break; 3560 case 16: 3561 ATF_REQUIRE_EQ(lookup_me16, magic16); 3562 break; 3563 case 32: 3564 ATF_REQUIRE_EQ(lookup_me32, magic32); 3565 break; 3566 case 64: 3567 ATF_REQUIRE_EQ(lookup_me64, magic64); 3568 break; 3569 default: 3570 break; 3571 } 3572 break; 3573 case PIOD_READ_AUXV: 3574 DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 3575 io.piod_len); 3576 ATF_REQUIRE(io.piod_len > 0); 3577 for (aip = ai; aip->a_type != AT_NULL; aip++) 3578 DPRINTF("a_type=%#llx a_v=%#llx\n", 3579 (long long int)aip->a_type, 3580 (long long int)aip->a_v); 3581 break; 3582 default: 3583 break; 3584 } 3585 break; 3586 case BYTES_TRANSFER_TEXT: 3587 switch (operation) { 3588 case PT_READ_D: 3589 case PT_READ_I: 3590 errno = 0; 3591 lookup_me = ptrace(operation, child, 3592 bytes_transfer_dummy, 0); 3593 ATF_REQUIRE_EQ(lookup_me, magic); 3594 SYSCALL_REQUIRE_ERRNO(errno, 0); 3595 break; 3596 case PT_WRITE_D: 3597 case PT_WRITE_I: 3598 SYSCALL_REQUIRE(ptrace(operation, child, 3599 bytes_transfer_dummy, magic) 3600 != -1); 3601 break; 3602 default: 3603 break; 3604 } 3605 break; 3606 case BYTES_TRANSFER_DATA: 3607 switch (operation) { 3608 case PT_READ_D: 3609 case PT_READ_I: 3610 errno = 0; 3611 lookup_me = ptrace(operation, child, &lookup_me, 0); 3612 ATF_REQUIRE_EQ(lookup_me, magic); 3613 SYSCALL_REQUIRE_ERRNO(errno, 0); 3614 break; 3615 case PT_WRITE_D: 3616 case PT_WRITE_I: 3617 lookup_me = magic; 3618 SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 3619 magic) != -1); 3620 break; 3621 default: 3622 break; 3623 } 3624 break; 3625 default: 3626 break; 3627 } 3628 3629 DPRINTF("Before resuming the child process where it left off and " 3630 "without signal to be sent\n"); 3631 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3632 3633 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3634 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3635 3636 validate_status_exited(status, exitval); 3637 3638 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3639 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3640} 3641 3642#define BYTES_TRANSFER(test, operation, size, type) \ 3643ATF_TC(test); \ 3644ATF_TC_HEAD(test, tc) \ 3645{ \ 3646 atf_tc_set_md_var(tc, "descr", \ 3647 "Verify bytes transfer operation" #operation " and size " #size \ 3648 " of type " #type); \ 3649} \ 3650 \ 3651ATF_TC_BODY(test, tc) \ 3652{ \ 3653 \ 3654 bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 3655} 3656 3657// DATA 3658 3659BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 3660BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 3661BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 3662BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 3663 3664BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 3665BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 3666BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 3667BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 3668 3669BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 3670BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 3671BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 3672BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 3673 3674BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 3675BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 3676BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 3677BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 3678 3679BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 3680BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 3681BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 3682BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 3683 3684// TEXT 3685 3686BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 3687BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 3688BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 3689BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 3690 3691BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 3692BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 3693BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 3694BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 3695 3696BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 3697BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 3698BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 3699BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 3700 3701BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 3702BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 3703BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 3704BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 3705 3706BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 3707BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 3708BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 3709BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 3710 3711// AUXV 3712 3713BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 3714 3715/// ---------------------------------------------------------------------------- 3716 3717static void 3718bytes_transfer_alignment(const char *operation) 3719{ 3720 const int exitval = 5; 3721 const int sigval = SIGSTOP; 3722 pid_t child, wpid; 3723#if defined(TWAIT_HAVE_STATUS) 3724 int status; 3725#endif 3726 char *buffer; 3727 int vector; 3728 size_t len; 3729 size_t i; 3730 int op; 3731 3732 struct ptrace_io_desc io; 3733 struct ptrace_siginfo info; 3734 3735 memset(&io, 0, sizeof(io)); 3736 memset(&info, 0, sizeof(info)); 3737 3738 /* Testing misaligned byte transfer crossing page boundaries */ 3739 len = sysconf(_SC_PAGESIZE) * 2; 3740 buffer = malloc(len); 3741 ATF_REQUIRE(buffer != NULL); 3742 3743 /* Initialize the buffer with random data */ 3744 for (i = 0; i < len; i++) 3745 buffer[i] = i & 0xff; 3746 3747 DPRINTF("Before forking process PID=%d\n", getpid()); 3748 SYSCALL_REQUIRE((child = fork()) != -1); 3749 if (child == 0) { 3750 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3751 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3752 3753 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3754 FORKEE_ASSERT(raise(sigval) == 0); 3755 3756 DPRINTF("Before exiting of the child process\n"); 3757 _exit(exitval); 3758 } 3759 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3760 3761 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3762 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3763 3764 validate_status_stopped(status, sigval); 3765 3766 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3767 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) 3768 != -1); 3769 3770 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3771 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3772 "si_errno=%#x\n", 3773 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3774 info.psi_siginfo.si_errno); 3775 3776 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3777 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3778 3779 if (strcmp(operation, "PT_READ_I") == 0 || 3780 strcmp(operation, "PT_READ_D") == 0) { 3781 if (strcmp(operation, "PT_READ_I")) 3782 op = PT_READ_I; 3783 else 3784 op = PT_READ_D; 3785 3786 for (i = 0; i <= (len - sizeof(int)); i++) { 3787 errno = 0; 3788 vector = ptrace(op, child, buffer + i, 0); 3789 ATF_REQUIRE_EQ(errno, 0); 3790 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int))); 3791 } 3792 } else if (strcmp(operation, "PT_WRITE_I") == 0 || 3793 strcmp(operation, "PT_WRITE_D") == 0) { 3794 if (strcmp(operation, "PT_WRITE_I")) 3795 op = PT_WRITE_I; 3796 else 3797 op = PT_WRITE_D; 3798 3799 for (i = 0; i <= (len - sizeof(int)); i++) { 3800 memcpy(&vector, buffer + i, sizeof(int)); 3801 SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector) 3802 != -1); 3803 } 3804 } else if (strcmp(operation, "PIOD_READ_I") == 0 || 3805 strcmp(operation, "PIOD_READ_D") == 0) { 3806 if (strcmp(operation, "PIOD_READ_I")) 3807 op = PIOD_READ_I; 3808 else 3809 op = PIOD_READ_D; 3810 3811 io.piod_op = op; 3812 io.piod_addr = &vector; 3813 io.piod_len = sizeof(int); 3814 3815 for (i = 0; i <= (len - sizeof(int)); i++) { 3816 io.piod_offs = buffer + i; 3817 3818 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 3819 != -1); 3820 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int))); 3821 } 3822 } else if (strcmp(operation, "PIOD_WRITE_I") == 0 || 3823 strcmp(operation, "PIOD_WRITE_D") == 0) { 3824 if (strcmp(operation, "PIOD_WRITE_I")) 3825 op = PIOD_WRITE_I; 3826 else 3827 op = PIOD_WRITE_D; 3828 3829 io.piod_op = op; 3830 io.piod_addr = &vector; 3831 io.piod_len = sizeof(int); 3832 3833 for (i = 0; i <= (len - sizeof(int)); i++) { 3834 io.piod_offs = buffer + i; 3835 3836 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 3837 != -1); 3838 } 3839 } else if (strcmp(operation, "PIOD_READ_AUXV") == 0) { 3840 io.piod_op = PIOD_READ_AUXV; 3841 io.piod_addr = &vector; 3842 io.piod_len = sizeof(int); 3843 3844 errno = 0; 3845 i = 0; 3846 /* Read the whole AUXV vector, it has no clear length */ 3847 while (errno != EIO) { 3848 io.piod_offs = (void *)(intptr_t)i; 3849 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 3850 != -1 || (errno == EIO && i > 0)); 3851 ++i; 3852 } 3853 } 3854 3855 DPRINTF("Before resuming the child process where it left off " 3856 "and without signal to be sent\n"); 3857 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3858 3859 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3860 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3861 child); 3862 3863 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3864 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3865} 3866 3867#define BYTES_TRANSFER_ALIGNMENT(test, operation) \ 3868ATF_TC(test); \ 3869ATF_TC_HEAD(test, tc) \ 3870{ \ 3871 atf_tc_set_md_var(tc, "descr", \ 3872 "Verify bytes transfer for potentially misaligned " \ 3873 "operation " operation); \ 3874} \ 3875 \ 3876ATF_TC_BODY(test, tc) \ 3877{ \ 3878 \ 3879 bytes_transfer_alignment(operation); \ 3880} 3881 3882BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I") 3883BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D") 3884BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I") 3885BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D") 3886 3887BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I") 3888BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D") 3889BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I") 3890BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D") 3891 3892BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV") 3893 3894/// ---------------------------------------------------------------------------- 3895 3896#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 3897static void 3898access_regs(const char *regset, const char *aux) 3899{ 3900 const int exitval = 5; 3901 const int sigval = SIGSTOP; 3902 pid_t child, wpid; 3903#if defined(TWAIT_HAVE_STATUS) 3904 int status; 3905#endif 3906#if defined(HAVE_GPREGS) 3907 struct reg gpr; 3908 register_t rgstr; 3909#endif 3910#if defined(HAVE_FPREGS) 3911 struct fpreg fpr; 3912#endif 3913 3914#if !defined(HAVE_GPREGS) 3915 if (strcmp(regset, "regs") == 0) 3916 atf_tc_fail("Impossible test scenario!"); 3917#endif 3918 3919#if !defined(HAVE_FPREGS) 3920 if (strcmp(regset, "fpregs") == 0) 3921 atf_tc_fail("Impossible test scenario!"); 3922#endif 3923 3924 DPRINTF("Before forking process PID=%d\n", getpid()); 3925 SYSCALL_REQUIRE((child = fork()) != -1); 3926 if (child == 0) { 3927 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3928 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3929 3930 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3931 FORKEE_ASSERT(raise(sigval) == 0); 3932 3933 DPRINTF("Before exiting of the child process\n"); 3934 _exit(exitval); 3935 } 3936 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3937 3938 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3939 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3940 3941 validate_status_stopped(status, sigval); 3942 3943#if defined(HAVE_GPREGS) 3944 if (strcmp(regset, "regs") == 0) { 3945 DPRINTF("Call GETREGS for the child process\n"); 3946 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 3947 3948 if (strcmp(aux, "none") == 0) { 3949 DPRINTF("Retrieved registers\n"); 3950 } else if (strcmp(aux, "pc") == 0) { 3951 rgstr = PTRACE_REG_PC(&gpr); 3952 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 3953 } else if (strcmp(aux, "set_pc") == 0) { 3954 rgstr = PTRACE_REG_PC(&gpr); 3955 PTRACE_REG_SET_PC(&gpr, rgstr); 3956 } else if (strcmp(aux, "sp") == 0) { 3957 rgstr = PTRACE_REG_SP(&gpr); 3958 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 3959 } else if (strcmp(aux, "intrv") == 0) { 3960 rgstr = PTRACE_REG_INTRV(&gpr); 3961 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 3962 } else if (strcmp(aux, "setregs") == 0) { 3963 DPRINTF("Call SETREGS for the child process\n"); 3964 SYSCALL_REQUIRE( 3965 ptrace(PT_GETREGS, child, &gpr, 0) != -1); 3966 } 3967 } 3968#endif 3969 3970#if defined(HAVE_FPREGS) 3971 if (strcmp(regset, "fpregs") == 0) { 3972 DPRINTF("Call GETFPREGS for the child process\n"); 3973 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 3974 3975 if (strcmp(aux, "getfpregs") == 0) { 3976 DPRINTF("Retrieved FP registers\n"); 3977 } else if (strcmp(aux, "setfpregs") == 0) { 3978 DPRINTF("Call SETFPREGS for the child\n"); 3979 SYSCALL_REQUIRE( 3980 ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 3981 } 3982 } 3983#endif 3984 3985 DPRINTF("Before resuming the child process where it left off and " 3986 "without signal to be sent\n"); 3987 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3988 3989 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3990 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3991 3992 validate_status_exited(status, exitval); 3993 3994 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3995 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3996} 3997 3998#define ACCESS_REGS(test, regset, aux) \ 3999ATF_TC(test); \ 4000ATF_TC_HEAD(test, tc) \ 4001{ \ 4002 atf_tc_set_md_var(tc, "descr", \ 4003 "Verify " regset " with auxiliary operation: " aux); \ 4004} \ 4005 \ 4006ATF_TC_BODY(test, tc) \ 4007{ \ 4008 \ 4009 access_regs(regset, aux); \ 4010} 4011#endif 4012 4013#if defined(HAVE_GPREGS) 4014ACCESS_REGS(access_regs1, "regs", "none") 4015ACCESS_REGS(access_regs2, "regs", "pc") 4016ACCESS_REGS(access_regs3, "regs", "set_pc") 4017ACCESS_REGS(access_regs4, "regs", "sp") 4018ACCESS_REGS(access_regs5, "regs", "intrv") 4019ACCESS_REGS(access_regs6, "regs", "setregs") 4020#endif 4021#if defined(HAVE_FPREGS) 4022ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 4023ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 4024#endif 4025 4026/// ---------------------------------------------------------------------------- 4027 4028#if defined(PT_STEP) 4029static void 4030ptrace_step(int N, int setstep, bool masked, bool ignored) 4031{ 4032 const int exitval = 5; 4033 const int sigval = SIGSTOP; 4034 pid_t child, wpid; 4035#if defined(TWAIT_HAVE_STATUS) 4036 int status; 4037#endif 4038 int happy; 4039 struct sigaction sa; 4040 struct ptrace_siginfo info; 4041 sigset_t intmask; 4042 struct kinfo_proc2 kp; 4043 size_t len = sizeof(kp); 4044 4045 int name[6]; 4046 const size_t namelen = __arraycount(name); 4047 ki_sigset_t kp_sigmask; 4048 ki_sigset_t kp_sigignore; 4049 4050#if defined(__arm__) 4051 /* PT_STEP not supported on arm 32-bit */ 4052 atf_tc_expect_fail("PR kern/52119"); 4053#endif 4054 4055 DPRINTF("Before forking process PID=%d\n", getpid()); 4056 SYSCALL_REQUIRE((child = fork()) != -1); 4057 if (child == 0) { 4058 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4059 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4060 4061 if (masked) { 4062 sigemptyset(&intmask); 4063 sigaddset(&intmask, SIGTRAP); 4064 sigprocmask(SIG_BLOCK, &intmask, NULL); 4065 } 4066 4067 if (ignored) { 4068 memset(&sa, 0, sizeof(sa)); 4069 sa.sa_handler = SIG_IGN; 4070 sigemptyset(&sa.sa_mask); 4071 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 4072 } 4073 4074 happy = check_happy(999); 4075 4076 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4077 FORKEE_ASSERT(raise(sigval) == 0); 4078 4079 FORKEE_ASSERT_EQ(happy, check_happy(999)); 4080 4081 DPRINTF("Before exiting of the child process\n"); 4082 _exit(exitval); 4083 } 4084 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4085 4086 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4087 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4088 4089 validate_status_stopped(status, sigval); 4090 4091 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4092 SYSCALL_REQUIRE( 4093 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4094 4095 DPRINTF("Before checking siginfo_t\n"); 4096 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4097 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4098 4099 name[0] = CTL_KERN, 4100 name[1] = KERN_PROC2, 4101 name[2] = KERN_PROC_PID; 4102 name[3] = child; 4103 name[4] = sizeof(kp); 4104 name[5] = 1; 4105 4106 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 4107 4108 if (masked) 4109 kp_sigmask = kp.p_sigmask; 4110 4111 if (ignored) 4112 kp_sigignore = kp.p_sigignore; 4113 4114 while (N --> 0) { 4115 if (setstep) { 4116 DPRINTF("Before resuming the child process where it " 4117 "left off and without signal to be sent (use " 4118 "PT_SETSTEP and PT_CONTINUE)\n"); 4119 SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 4120 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 4121 != -1); 4122 } else { 4123 DPRINTF("Before resuming the child process where it " 4124 "left off and without signal to be sent (use " 4125 "PT_STEP)\n"); 4126 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 4127 != -1); 4128 } 4129 4130 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4131 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4132 child); 4133 4134 validate_status_stopped(status, SIGTRAP); 4135 4136 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4137 SYSCALL_REQUIRE( 4138 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4139 4140 DPRINTF("Before checking siginfo_t\n"); 4141 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4142 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 4143 4144 if (setstep) { 4145 SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 4146 } 4147 4148 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 4149 4150 if (masked) { 4151 DPRINTF("kp_sigmask=" 4152 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4153 PRIx32 "\n", 4154 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 4155 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 4156 4157 DPRINTF("kp.p_sigmask=" 4158 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4159 PRIx32 "\n", 4160 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 4161 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 4162 4163 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 4164 sizeof(kp_sigmask))); 4165 } 4166 4167 if (ignored) { 4168 DPRINTF("kp_sigignore=" 4169 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4170 PRIx32 "\n", 4171 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 4172 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 4173 4174 DPRINTF("kp.p_sigignore=" 4175 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4176 PRIx32 "\n", 4177 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 4178 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 4179 4180 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 4181 sizeof(kp_sigignore))); 4182 } 4183 } 4184 4185 DPRINTF("Before resuming the child process where it left off and " 4186 "without signal to be sent\n"); 4187 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4188 4189 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4190 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4191 4192 validate_status_exited(status, exitval); 4193 4194 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4195 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4196} 4197 4198#define PTRACE_STEP(test, N, setstep) \ 4199ATF_TC(test); \ 4200ATF_TC_HEAD(test, tc) \ 4201{ \ 4202 atf_tc_set_md_var(tc, "descr", \ 4203 "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 4204} \ 4205 \ 4206ATF_TC_BODY(test, tc) \ 4207{ \ 4208 \ 4209 ptrace_step(N, setstep, false, false); \ 4210} 4211 4212PTRACE_STEP(step1, 1, 0) 4213PTRACE_STEP(step2, 2, 0) 4214PTRACE_STEP(step3, 3, 0) 4215PTRACE_STEP(step4, 4, 0) 4216PTRACE_STEP(setstep1, 1, 1) 4217PTRACE_STEP(setstep2, 2, 1) 4218PTRACE_STEP(setstep3, 3, 1) 4219PTRACE_STEP(setstep4, 4, 1) 4220 4221ATF_TC(step_signalmasked); 4222ATF_TC_HEAD(step_signalmasked, tc) 4223{ 4224 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with masked SIGTRAP"); 4225} 4226 4227ATF_TC_BODY(step_signalmasked, tc) 4228{ 4229 4230 ptrace_step(1, 0, true, false); 4231} 4232 4233ATF_TC(step_signalignored); 4234ATF_TC_HEAD(step_signalignored, tc) 4235{ 4236 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with ignored SIGTRAP"); 4237} 4238 4239ATF_TC_BODY(step_signalignored, tc) 4240{ 4241 4242 ptrace_step(1, 0, false, true); 4243} 4244#endif 4245 4246/// ---------------------------------------------------------------------------- 4247 4248static void 4249ptrace_kill(const char *type) 4250{ 4251 const int sigval = SIGSTOP; 4252 pid_t child, wpid; 4253#if defined(TWAIT_HAVE_STATUS) 4254 int status; 4255#endif 4256 4257 DPRINTF("Before forking process PID=%d\n", getpid()); 4258 SYSCALL_REQUIRE((child = fork()) != -1); 4259 if (child == 0) { 4260 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4261 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4262 4263 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4264 FORKEE_ASSERT(raise(sigval) == 0); 4265 4266 /* NOTREACHED */ 4267 FORKEE_ASSERTX(0 && 4268 "Child should be terminated by a signal from its parent"); 4269 } 4270 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4271 4272 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4273 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4274 4275 validate_status_stopped(status, sigval); 4276 4277 DPRINTF("Before killing the child process with %s\n", type); 4278 if (strcmp(type, "ptrace(PT_KILL)") == 0) { 4279 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 4280 } else if (strcmp(type, "kill(SIGKILL)") == 0) { 4281 kill(child, SIGKILL); 4282 } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 4283 setpgid(child, 0); 4284 killpg(getpgid(child), SIGKILL); 4285 } 4286 4287 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4288 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4289 4290 validate_status_signaled(status, SIGKILL, 0); 4291 4292 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4293 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4294} 4295 4296#define PTRACE_KILL(test, type) \ 4297ATF_TC(test); \ 4298ATF_TC_HEAD(test, tc) \ 4299{ \ 4300 atf_tc_set_md_var(tc, "descr", \ 4301 "Verify killing the child with " type); \ 4302} \ 4303 \ 4304ATF_TC_BODY(test, tc) \ 4305{ \ 4306 \ 4307 ptrace_kill(type); \ 4308} 4309 4310// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 4311PTRACE_KILL(kill1, "ptrace(PT_KILL)") 4312PTRACE_KILL(kill2, "kill(SIGKILL)") 4313PTRACE_KILL(kill3, "killpg(SIGKILL)") 4314 4315/// ---------------------------------------------------------------------------- 4316 4317static void 4318traceme_lwpinfo(const int threads) 4319{ 4320 const int sigval = SIGSTOP; 4321 const int sigval2 = SIGINT; 4322 pid_t child, wpid; 4323#if defined(TWAIT_HAVE_STATUS) 4324 int status; 4325#endif 4326 struct ptrace_lwpinfo lwp = {0, 0}; 4327 struct ptrace_siginfo info; 4328 4329 /* Maximum number of supported threads in this test */ 4330 pthread_t t[3]; 4331 int n, rv; 4332 4333 ATF_REQUIRE((int)__arraycount(t) >= threads); 4334 4335 DPRINTF("Before forking process PID=%d\n", getpid()); 4336 SYSCALL_REQUIRE((child = fork()) != -1); 4337 if (child == 0) { 4338 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4339 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4340 4341 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4342 FORKEE_ASSERT(raise(sigval) == 0); 4343 4344 for (n = 0; n < threads; n++) { 4345 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 4346 FORKEE_ASSERT(rv == 0); 4347 } 4348 4349 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 4350 FORKEE_ASSERT(raise(sigval2) == 0); 4351 4352 /* NOTREACHED */ 4353 FORKEE_ASSERTX(0 && "Not reached"); 4354 } 4355 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4356 4357 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4358 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4359 4360 validate_status_stopped(status, sigval); 4361 4362 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4363 SYSCALL_REQUIRE( 4364 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4365 4366 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4367 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4368 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4369 info.psi_siginfo.si_errno); 4370 4371 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4372 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4373 4374 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4375 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4376 4377 DPRINTF("Assert that there exists a single thread only\n"); 4378 ATF_REQUIRE(lwp.pl_lwpid > 0); 4379 4380 DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 4381 lwp.pl_lwpid); 4382 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 4383 4384 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4385 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4386 4387 DPRINTF("Assert that there exists a single thread only\n"); 4388 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 4389 4390 DPRINTF("Before resuming the child process where it left off and " 4391 "without signal to be sent\n"); 4392 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4393 4394 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4395 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4396 4397 validate_status_stopped(status, sigval2); 4398 4399 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4400 SYSCALL_REQUIRE( 4401 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4402 4403 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4404 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4405 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4406 info.psi_siginfo.si_errno); 4407 4408 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 4409 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4410 4411 memset(&lwp, 0, sizeof(lwp)); 4412 4413 for (n = 0; n <= threads; n++) { 4414 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4415 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4416 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4417 4418 DPRINTF("Assert that the thread exists\n"); 4419 ATF_REQUIRE(lwp.pl_lwpid > 0); 4420 4421 DPRINTF("Assert that lwp thread %d received expected event\n", 4422 lwp.pl_lwpid); 4423 FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ? 4424 PL_EVENT_SIGNAL : PL_EVENT_NONE); 4425 } 4426 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4427 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 4428 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4429 4430 DPRINTF("Assert that there are no more threads\n"); 4431 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 4432 4433 DPRINTF("Before resuming the child process where it left off and " 4434 "without signal to be sent\n"); 4435 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 4436 4437 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4438 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4439 4440 validate_status_signaled(status, SIGKILL, 0); 4441 4442 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4443 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4444} 4445 4446#define TRACEME_LWPINFO(test, threads) \ 4447ATF_TC(test); \ 4448ATF_TC_HEAD(test, tc) \ 4449{ \ 4450 atf_tc_set_md_var(tc, "descr", \ 4451 "Verify LWPINFO with the child with " #threads \ 4452 " spawned extra threads"); \ 4453} \ 4454 \ 4455ATF_TC_BODY(test, tc) \ 4456{ \ 4457 \ 4458 traceme_lwpinfo(threads); \ 4459} 4460 4461TRACEME_LWPINFO(traceme_lwpinfo0, 0) 4462TRACEME_LWPINFO(traceme_lwpinfo1, 1) 4463TRACEME_LWPINFO(traceme_lwpinfo2, 2) 4464TRACEME_LWPINFO(traceme_lwpinfo3, 3) 4465 4466/// ---------------------------------------------------------------------------- 4467 4468#if defined(TWAIT_HAVE_PID) 4469static void 4470attach_lwpinfo(const int threads) 4471{ 4472 const int sigval = SIGINT; 4473 struct msg_fds parent_tracee, parent_tracer; 4474 const int exitval_tracer = 10; 4475 pid_t tracee, tracer, wpid; 4476 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 4477#if defined(TWAIT_HAVE_STATUS) 4478 int status; 4479#endif 4480 struct ptrace_lwpinfo lwp = {0, 0}; 4481 struct ptrace_siginfo info; 4482 4483 /* Maximum number of supported threads in this test */ 4484 pthread_t t[3]; 4485 int n, rv; 4486 4487 DPRINTF("Spawn tracee\n"); 4488 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 4489 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 4490 tracee = atf_utils_fork(); 4491 if (tracee == 0) { 4492 /* Wait for message from the parent */ 4493 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 4494 4495 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 4496 4497 for (n = 0; n < threads; n++) { 4498 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 4499 FORKEE_ASSERT(rv == 0); 4500 } 4501 4502 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 4503 4504 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4505 FORKEE_ASSERT(raise(sigval) == 0); 4506 4507 /* NOTREACHED */ 4508 FORKEE_ASSERTX(0 && "Not reached"); 4509 } 4510 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 4511 4512 DPRINTF("Spawn debugger\n"); 4513 tracer = atf_utils_fork(); 4514 if (tracer == 0) { 4515 /* No IPC to communicate with the child */ 4516 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 4517 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 4518 4519 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 4520 FORKEE_REQUIRE_SUCCESS( 4521 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4522 4523 forkee_status_stopped(status, SIGSTOP); 4524 4525 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4526 "tracee"); 4527 FORKEE_ASSERT( 4528 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 4529 4530 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4531 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4532 "si_errno=%#x\n", 4533 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4534 info.psi_siginfo.si_errno); 4535 4536 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 4537 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 4538 4539 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4540 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 4541 != -1); 4542 4543 DPRINTF("Assert that there exists a thread\n"); 4544 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 4545 4546 DPRINTF("Assert that lwp thread %d received event " 4547 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 4548 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 4549 4550 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 4551 "tracee\n"); 4552 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 4553 != -1); 4554 4555 DPRINTF("Assert that there are no more lwp threads in " 4556 "tracee\n"); 4557 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 4558 4559 /* Resume tracee with PT_CONTINUE */ 4560 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 4561 4562 /* Inform parent that tracer has attached to tracee */ 4563 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 4564 4565 /* Wait for parent */ 4566 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 4567 4568 /* Wait for tracee and assert that it raised a signal */ 4569 FORKEE_REQUIRE_SUCCESS( 4570 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4571 4572 forkee_status_stopped(status, SIGINT); 4573 4574 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4575 "child"); 4576 FORKEE_ASSERT( 4577 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 4578 4579 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4580 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4581 "si_errno=%#x\n", 4582 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4583 info.psi_siginfo.si_errno); 4584 4585 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 4586 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 4587 4588 memset(&lwp, 0, sizeof(lwp)); 4589 4590 for (n = 0; n <= threads; n++) { 4591 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 4592 "child\n"); 4593 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 4594 sizeof(lwp)) != -1); 4595 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4596 4597 DPRINTF("Assert that the thread exists\n"); 4598 FORKEE_ASSERT(lwp.pl_lwpid > 0); 4599 4600 DPRINTF("Assert that lwp thread %d received expected " 4601 "event\n", lwp.pl_lwpid); 4602 FORKEE_ASSERT_EQ(lwp.pl_event, 4603 info.psi_lwpid == lwp.pl_lwpid ? 4604 PL_EVENT_SIGNAL : PL_EVENT_NONE); 4605 } 4606 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 4607 "tracee\n"); 4608 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 4609 != -1); 4610 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 4611 4612 DPRINTF("Assert that there are no more threads\n"); 4613 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 4614 4615 DPRINTF("Before resuming the child process where it left off " 4616 "and without signal to be sent\n"); 4617 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 4618 != -1); 4619 4620 /* Wait for tracee and assert that it exited */ 4621 FORKEE_REQUIRE_SUCCESS( 4622 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4623 4624 forkee_status_signaled(status, SIGKILL, 0); 4625 4626 DPRINTF("Before exiting of the tracer process\n"); 4627 _exit(exitval_tracer); 4628 } 4629 4630 DPRINTF("Wait for the tracer to attach to the tracee\n"); 4631 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 4632 4633 DPRINTF("Resume the tracee and spawn threads\n"); 4634 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 4635 4636 DPRINTF("Resume the tracee and let it exit\n"); 4637 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 4638 4639 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 4640 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 4641 4642 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 4643 TWAIT_FNAME); 4644 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 4645 tracer); 4646 4647 validate_status_exited(status, exitval_tracer); 4648 4649 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 4650 TWAIT_FNAME); 4651 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 4652 tracee); 4653 4654 validate_status_signaled(status, SIGKILL, 0); 4655 4656 msg_close(&parent_tracer); 4657 msg_close(&parent_tracee); 4658} 4659 4660#define ATTACH_LWPINFO(test, threads) \ 4661ATF_TC(test); \ 4662ATF_TC_HEAD(test, tc) \ 4663{ \ 4664 atf_tc_set_md_var(tc, "descr", \ 4665 "Verify LWPINFO with the child with " #threads \ 4666 " spawned extra threads (tracer is not the original " \ 4667 "parent)"); \ 4668} \ 4669 \ 4670ATF_TC_BODY(test, tc) \ 4671{ \ 4672 \ 4673 attach_lwpinfo(threads); \ 4674} 4675 4676ATTACH_LWPINFO(attach_lwpinfo0, 0) 4677ATTACH_LWPINFO(attach_lwpinfo1, 1) 4678ATTACH_LWPINFO(attach_lwpinfo2, 2) 4679ATTACH_LWPINFO(attach_lwpinfo3, 3) 4680#endif 4681 4682/// ---------------------------------------------------------------------------- 4683 4684static void 4685ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 4686{ 4687 const int exitval = 5; 4688 const int sigval = SIGINT; 4689 const int sigfaked = SIGTRAP; 4690 const int sicodefaked = TRAP_BRKPT; 4691 pid_t child, wpid; 4692 struct sigaction sa; 4693#if defined(TWAIT_HAVE_STATUS) 4694 int status; 4695#endif 4696 struct ptrace_siginfo info; 4697 memset(&info, 0, sizeof(info)); 4698 4699 DPRINTF("Before forking process PID=%d\n", getpid()); 4700 SYSCALL_REQUIRE((child = fork()) != -1); 4701 if (child == 0) { 4702 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4703 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4704 4705 sa.sa_sigaction = sah; 4706 sa.sa_flags = SA_SIGINFO; 4707 sigemptyset(&sa.sa_mask); 4708 4709 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 4710 != -1); 4711 4712 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4713 FORKEE_ASSERT(raise(sigval) == 0); 4714 4715 FORKEE_ASSERT_EQ(*signal_caught, 1); 4716 4717 DPRINTF("Before exiting of the child process\n"); 4718 _exit(exitval); 4719 } 4720 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4721 4722 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4723 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4724 4725 validate_status_stopped(status, sigval); 4726 4727 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4728 SYSCALL_REQUIRE( 4729 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4730 4731 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4732 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4733 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4734 info.psi_siginfo.si_errno); 4735 4736 if (faked) { 4737 DPRINTF("Before setting new faked signal to signo=%d " 4738 "si_code=%d\n", sigfaked, sicodefaked); 4739 info.psi_siginfo.si_signo = sigfaked; 4740 info.psi_siginfo.si_code = sicodefaked; 4741 } 4742 4743 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 4744 SYSCALL_REQUIRE( 4745 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 4746 4747 if (faked) { 4748 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 4749 "child\n"); 4750 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 4751 sizeof(info)) != -1); 4752 4753 DPRINTF("Before checking siginfo_t\n"); 4754 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 4755 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 4756 } 4757 4758 DPRINTF("Before resuming the child process where it left off and " 4759 "without signal to be sent\n"); 4760 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 4761 faked ? sigfaked : sigval) != -1); 4762 4763 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4764 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4765 4766 validate_status_exited(status, exitval); 4767 4768 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4769 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4770} 4771 4772#define PTRACE_SIGINFO(test, faked) \ 4773ATF_TC(test); \ 4774ATF_TC_HEAD(test, tc) \ 4775{ \ 4776 atf_tc_set_md_var(tc, "descr", \ 4777 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 4778 "with%s setting signal to new value", faked ? "" : "out"); \ 4779} \ 4780 \ 4781static int test##_caught = 0; \ 4782 \ 4783static void \ 4784test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 4785{ \ 4786 if (faked) { \ 4787 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 4788 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 4789 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 4790 } else { \ 4791 FORKEE_ASSERT_EQ(sig, SIGINT); \ 4792 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 4793 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 4794 } \ 4795 \ 4796 ++ test##_caught; \ 4797} \ 4798 \ 4799ATF_TC_BODY(test, tc) \ 4800{ \ 4801 \ 4802 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 4803} 4804 4805PTRACE_SIGINFO(siginfo_set_unmodified, false) 4806PTRACE_SIGINFO(siginfo_set_faked, true) 4807 4808/// ---------------------------------------------------------------------------- 4809 4810static void 4811traceme_exec(bool masked, bool ignored) 4812{ 4813 const int sigval = SIGTRAP; 4814 pid_t child, wpid; 4815#if defined(TWAIT_HAVE_STATUS) 4816 int status; 4817#endif 4818 struct sigaction sa; 4819 struct ptrace_siginfo info; 4820 sigset_t intmask; 4821 struct kinfo_proc2 kp; 4822 size_t len = sizeof(kp); 4823 4824 int name[6]; 4825 const size_t namelen = __arraycount(name); 4826 ki_sigset_t kp_sigmask; 4827 ki_sigset_t kp_sigignore; 4828 4829 memset(&info, 0, sizeof(info)); 4830 4831 DPRINTF("Before forking process PID=%d\n", getpid()); 4832 SYSCALL_REQUIRE((child = fork()) != -1); 4833 if (child == 0) { 4834 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4835 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4836 4837 if (masked) { 4838 sigemptyset(&intmask); 4839 sigaddset(&intmask, sigval); 4840 sigprocmask(SIG_BLOCK, &intmask, NULL); 4841 } 4842 4843 if (ignored) { 4844 memset(&sa, 0, sizeof(sa)); 4845 sa.sa_handler = SIG_IGN; 4846 sigemptyset(&sa.sa_mask); 4847 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 4848 } 4849 4850 DPRINTF("Before calling execve(2) from child\n"); 4851 execlp("/bin/echo", "/bin/echo", NULL); 4852 4853 FORKEE_ASSERT(0 && "Not reached"); 4854 } 4855 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4856 4857 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4858 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4859 4860 validate_status_stopped(status, sigval); 4861 4862 name[0] = CTL_KERN, 4863 name[1] = KERN_PROC2, 4864 name[2] = KERN_PROC_PID; 4865 name[3] = getpid(); 4866 name[4] = sizeof(kp); 4867 name[5] = 1; 4868 4869 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 4870 4871 if (masked) 4872 kp_sigmask = kp.p_sigmask; 4873 4874 if (ignored) 4875 kp_sigignore = kp.p_sigignore; 4876 4877 name[3] = getpid(); 4878 4879 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 4880 4881 if (masked) { 4882 DPRINTF("kp_sigmask=" 4883 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 4884 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 4885 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 4886 4887 DPRINTF("kp.p_sigmask=" 4888 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 4889 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 4890 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 4891 4892 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 4893 sizeof(kp_sigmask))); 4894 } 4895 4896 if (ignored) { 4897 DPRINTF("kp_sigignore=" 4898 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 4899 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 4900 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 4901 4902 DPRINTF("kp.p_sigignore=" 4903 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 4904 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 4905 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 4906 4907 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 4908 sizeof(kp_sigignore))); 4909 } 4910 4911 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4912 SYSCALL_REQUIRE( 4913 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4914 4915 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4916 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4917 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4918 info.psi_siginfo.si_errno); 4919 4920 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4921 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4922 4923 DPRINTF("Before resuming the child process where it left off and " 4924 "without signal to be sent\n"); 4925 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4926 4927 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4928 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4929 4930 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4931 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4932} 4933 4934#define TRACEME_EXEC(test, masked, ignored) \ 4935ATF_TC(test); \ 4936ATF_TC_HEAD(test, tc) \ 4937{ \ 4938 atf_tc_set_md_var(tc, "descr", \ 4939 "Detect SIGTRAP TRAP_EXEC from " \ 4940 "child%s%s", masked ? " with masked signal" : "", \ 4941 masked ? " with ignored signal" : ""); \ 4942} \ 4943 \ 4944ATF_TC_BODY(test, tc) \ 4945{ \ 4946 \ 4947 traceme_exec(masked, ignored); \ 4948} 4949 4950TRACEME_EXEC(traceme_exec, false, false) 4951TRACEME_EXEC(traceme_signalmasked_exec, true, false) 4952TRACEME_EXEC(traceme_signalignored_exec, false, true) 4953 4954/// ---------------------------------------------------------------------------- 4955 4956static volatile int done; 4957 4958static void * 4959trace_threads_cb(void *arg __unused) 4960{ 4961 4962 done++; 4963 4964 while (done < 3) 4965 continue; 4966 4967 return NULL; 4968} 4969 4970static void 4971trace_threads(bool trace_create, bool trace_exit) 4972{ 4973 const int sigval = SIGSTOP; 4974 pid_t child, wpid; 4975#if defined(TWAIT_HAVE_STATUS) 4976 int status; 4977#endif 4978 ptrace_state_t state; 4979 const int slen = sizeof(state); 4980 ptrace_event_t event; 4981 const int elen = sizeof(event); 4982 struct ptrace_siginfo info; 4983 4984 pthread_t t[3]; 4985 int rv; 4986 size_t n; 4987 lwpid_t lid; 4988 4989 /* Track created and exited threads */ 4990 bool traced_lwps[__arraycount(t)]; 4991 4992 atf_tc_skip("PR kern/51995"); 4993 4994 DPRINTF("Before forking process PID=%d\n", getpid()); 4995 SYSCALL_REQUIRE((child = fork()) != -1); 4996 if (child == 0) { 4997 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4998 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4999 5000 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5001 FORKEE_ASSERT(raise(sigval) == 0); 5002 5003 for (n = 0; n < __arraycount(t); n++) { 5004 rv = pthread_create(&t[n], NULL, trace_threads_cb, 5005 NULL); 5006 FORKEE_ASSERT(rv == 0); 5007 } 5008 5009 for (n = 0; n < __arraycount(t); n++) { 5010 rv = pthread_join(t[n], NULL); 5011 FORKEE_ASSERT(rv == 0); 5012 } 5013 5014 /* 5015 * There is race between _exit() and pthread_join() detaching 5016 * a thread. For simplicity kill the process after detecting 5017 * LWP events. 5018 */ 5019 while (true) 5020 continue; 5021 5022 FORKEE_ASSERT(0 && "Not reached"); 5023 } 5024 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5025 5026 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5027 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5028 5029 validate_status_stopped(status, sigval); 5030 5031 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5032 SYSCALL_REQUIRE( 5033 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5034 5035 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5036 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5037 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5038 info.psi_siginfo.si_errno); 5039 5040 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5041 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5042 5043 DPRINTF("Set LWP event mask for the child %d\n", child); 5044 memset(&event, 0, sizeof(event)); 5045 if (trace_create) 5046 event.pe_set_event |= PTRACE_LWP_CREATE; 5047 if (trace_exit) 5048 event.pe_set_event |= PTRACE_LWP_EXIT; 5049 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5050 5051 DPRINTF("Before resuming the child process where it left off and " 5052 "without signal to be sent\n"); 5053 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5054 5055 memset(traced_lwps, 0, sizeof(traced_lwps)); 5056 5057 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 5058 DPRINTF("Before calling %s() for the child - expected stopped " 5059 "SIGTRAP\n", TWAIT_FNAME); 5060 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5061 child); 5062 5063 validate_status_stopped(status, SIGTRAP); 5064 5065 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5066 "child\n"); 5067 SYSCALL_REQUIRE( 5068 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5069 5070 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5071 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5072 "si_errno=%#x\n", 5073 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5074 info.psi_siginfo.si_errno); 5075 5076 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5077 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5078 5079 SYSCALL_REQUIRE( 5080 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5081 5082 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 5083 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 5084 5085 lid = state.pe_lwp; 5086 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 5087 5088 traced_lwps[lid - 1] = true; 5089 5090 DPRINTF("Before resuming the child process where it left off " 5091 "and without signal to be sent\n"); 5092 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5093 } 5094 5095 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 5096 DPRINTF("Before calling %s() for the child - expected stopped " 5097 "SIGTRAP\n", TWAIT_FNAME); 5098 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5099 child); 5100 5101 validate_status_stopped(status, SIGTRAP); 5102 5103 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5104 "child\n"); 5105 SYSCALL_REQUIRE( 5106 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5107 5108 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5109 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5110 "si_errno=%#x\n", 5111 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5112 info.psi_siginfo.si_errno); 5113 5114 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5115 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5116 5117 SYSCALL_REQUIRE( 5118 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5119 5120 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 5121 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 5122 5123 lid = state.pe_lwp; 5124 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 5125 5126 if (trace_create) { 5127 ATF_REQUIRE(traced_lwps[lid - 1] == true); 5128 traced_lwps[lid - 1] = false; 5129 } 5130 5131 DPRINTF("Before resuming the child process where it left off " 5132 "and without signal to be sent\n"); 5133 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5134 } 5135 5136 kill(child, SIGKILL); 5137 5138 DPRINTF("Before calling %s() for the child - expected exited\n", 5139 TWAIT_FNAME); 5140 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5141 5142 validate_status_signaled(status, SIGKILL, 0); 5143 5144 DPRINTF("Before calling %s() for the child - expected no process\n", 5145 TWAIT_FNAME); 5146 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5147} 5148 5149#define TRACE_THREADS(test, trace_create, trace_exit) \ 5150ATF_TC(test); \ 5151ATF_TC_HEAD(test, tc) \ 5152{ \ 5153 atf_tc_set_md_var(tc, "descr", \ 5154 "Verify spawning threads with%s tracing LWP create and" \ 5155 "with%s tracing LWP exit", trace_create ? "" : "out", \ 5156 trace_exit ? "" : "out"); \ 5157} \ 5158 \ 5159ATF_TC_BODY(test, tc) \ 5160{ \ 5161 \ 5162 trace_threads(trace_create, trace_exit); \ 5163} 5164 5165TRACE_THREADS(trace_thread1, false, false) 5166TRACE_THREADS(trace_thread2, false, true) 5167TRACE_THREADS(trace_thread3, true, false) 5168TRACE_THREADS(trace_thread4, true, true) 5169 5170/// ---------------------------------------------------------------------------- 5171 5172ATF_TC(signal_mask_unrelated); 5173ATF_TC_HEAD(signal_mask_unrelated, tc) 5174{ 5175 atf_tc_set_md_var(tc, "descr", 5176 "Verify that masking single unrelated signal does not stop tracer " 5177 "from catching other signals"); 5178} 5179 5180ATF_TC_BODY(signal_mask_unrelated, tc) 5181{ 5182 const int exitval = 5; 5183 const int sigval = SIGSTOP; 5184 const int sigmasked = SIGTRAP; 5185 const int signotmasked = SIGINT; 5186 pid_t child, wpid; 5187#if defined(TWAIT_HAVE_STATUS) 5188 int status; 5189#endif 5190 sigset_t intmask; 5191 5192 DPRINTF("Before forking process PID=%d\n", getpid()); 5193 SYSCALL_REQUIRE((child = fork()) != -1); 5194 if (child == 0) { 5195 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5196 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5197 5198 sigemptyset(&intmask); 5199 sigaddset(&intmask, sigmasked); 5200 sigprocmask(SIG_BLOCK, &intmask, NULL); 5201 5202 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5203 FORKEE_ASSERT(raise(sigval) == 0); 5204 5205 DPRINTF("Before raising %s from child\n", 5206 strsignal(signotmasked)); 5207 FORKEE_ASSERT(raise(signotmasked) == 0); 5208 5209 DPRINTF("Before exiting of the child process\n"); 5210 _exit(exitval); 5211 } 5212 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5213 5214 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5215 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5216 5217 validate_status_stopped(status, sigval); 5218 5219 DPRINTF("Before resuming the child process where it left off and " 5220 "without signal to be sent\n"); 5221 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5222 5223 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5224 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5225 5226 validate_status_stopped(status, signotmasked); 5227 5228 DPRINTF("Before resuming the child process where it left off and " 5229 "without signal to be sent\n"); 5230 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5231 5232 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5233 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5234 5235 validate_status_exited(status, exitval); 5236 5237 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5238 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5239} 5240 5241/// ---------------------------------------------------------------------------- 5242 5243#if defined(TWAIT_HAVE_PID) 5244static void 5245fork2_body(bool trackfork, bool trackvfork, bool trackvforkdone, bool masked, 5246 bool ignored) 5247{ 5248 const int exitval = 5; 5249 const int exitval2 = 15; 5250 const int sigval = SIGSTOP; 5251 pid_t child, child2 = 0, wpid; 5252#if defined(TWAIT_HAVE_STATUS) 5253 int status; 5254#endif 5255 ptrace_state_t state; 5256 const int slen = sizeof(state); 5257 ptrace_event_t event; 5258 const int elen = sizeof(event); 5259 pid_t (*fn)(void); 5260 struct sigaction sa; 5261 struct ptrace_siginfo info; 5262 sigset_t intmask; 5263 struct kinfo_proc2 kp; 5264 size_t len = sizeof(kp); 5265 5266 int name[6]; 5267 const size_t namelen = __arraycount(name); 5268 ki_sigset_t kp_sigmask; 5269 ki_sigset_t kp_sigignore; 5270 5271 if (trackfork) 5272 fn = fork; 5273 if (trackvfork || trackvforkdone) 5274 fn = vfork; 5275 5276 DPRINTF("Before forking process PID=%d\n", getpid()); 5277 SYSCALL_REQUIRE((child = fork()) != -1); 5278 if (child == 0) { 5279 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5280 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5281 5282 if (masked) { 5283 sigemptyset(&intmask); 5284 sigaddset(&intmask, SIGTRAP); 5285 sigprocmask(SIG_BLOCK, &intmask, NULL); 5286 } 5287 5288 if (ignored) { 5289 memset(&sa, 0, sizeof(sa)); 5290 sa.sa_handler = SIG_IGN; 5291 sigemptyset(&sa.sa_mask); 5292 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 5293 } 5294 5295 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5296 FORKEE_ASSERT(raise(sigval) == 0); 5297 5298 FORKEE_ASSERT((child2 = (fn)()) != -1); 5299 5300 if (child2 == 0) 5301 _exit(exitval2); 5302 5303 FORKEE_REQUIRE_SUCCESS 5304 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 5305 5306 forkee_status_exited(status, exitval2); 5307 5308 DPRINTF("Before exiting of the child process\n"); 5309 _exit(exitval); 5310 } 5311 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5312 5313 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5314 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5315 5316 validate_status_stopped(status, sigval); 5317 5318 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5319 SYSCALL_REQUIRE( 5320 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5321 5322 DPRINTF("Before checking siginfo_t\n"); 5323 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5324 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5325 5326 name[0] = CTL_KERN, 5327 name[1] = KERN_PROC2, 5328 name[2] = KERN_PROC_PID; 5329 name[3] = child; 5330 name[4] = sizeof(kp); 5331 name[5] = 1; 5332 5333 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5334 5335 if (masked) 5336 kp_sigmask = kp.p_sigmask; 5337 5338 if (ignored) 5339 kp_sigignore = kp.p_sigignore; 5340 5341 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 5342 trackfork ? "|PTRACE_FORK" : "", 5343 trackvfork ? "|PTRACE_VFORK" : "", 5344 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 5345 event.pe_set_event = 0; 5346 if (trackfork) 5347 event.pe_set_event |= PTRACE_FORK; 5348 if (trackvfork) 5349 event.pe_set_event |= PTRACE_VFORK; 5350 if (trackvforkdone) 5351 event.pe_set_event |= PTRACE_VFORK_DONE; 5352 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5353 5354 DPRINTF("Before resuming the child process where it left off and " 5355 "without signal to be sent\n"); 5356 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5357 5358 if (trackfork || trackvfork) { 5359 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 5360 child); 5361 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5362 child); 5363 5364 validate_status_stopped(status, SIGTRAP); 5365 5366 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5367 5368 if (masked) { 5369 DPRINTF("kp_sigmask=" 5370 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5371 PRIx32 "\n", 5372 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5373 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5374 5375 DPRINTF("kp.p_sigmask=" 5376 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5377 PRIx32 "\n", 5378 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5379 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5380 5381 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5382 sizeof(kp_sigmask))); 5383 } 5384 5385 if (ignored) { 5386 DPRINTF("kp_sigignore=" 5387 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5388 PRIx32 "\n", 5389 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5390 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5391 5392 DPRINTF("kp.p_sigignore=" 5393 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5394 PRIx32 "\n", 5395 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5396 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5397 5398 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5399 sizeof(kp_sigignore))); 5400 } 5401 5402 SYSCALL_REQUIRE( 5403 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5404 if (trackfork) { 5405 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 5406 PTRACE_FORK); 5407 } 5408 if (trackvfork) { 5409 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 5410 PTRACE_VFORK); 5411 } 5412 5413 child2 = state.pe_other_pid; 5414 DPRINTF("Reported ptrace event with forkee %d\n", child2); 5415 5416 DPRINTF("Before calling %s() for the forkee %d of the child " 5417 "%d\n", TWAIT_FNAME, child2, child); 5418 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 5419 child2); 5420 5421 validate_status_stopped(status, SIGTRAP); 5422 5423 name[3] = child2; 5424 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5425 5426 if (masked) { 5427 DPRINTF("kp_sigmask=" 5428 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5429 PRIx32 "\n", 5430 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5431 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5432 5433 DPRINTF("kp.p_sigmask=" 5434 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5435 PRIx32 "\n", 5436 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5437 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5438 5439 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5440 sizeof(kp_sigmask))); 5441 } 5442 5443 if (ignored) { 5444 DPRINTF("kp_sigignore=" 5445 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5446 PRIx32 "\n", 5447 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5448 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5449 5450 DPRINTF("kp.p_sigignore=" 5451 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5452 PRIx32 "\n", 5453 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5454 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5455 5456 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5457 sizeof(kp_sigignore))); 5458 } 5459 5460 SYSCALL_REQUIRE( 5461 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 5462 if (trackfork) { 5463 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 5464 PTRACE_FORK); 5465 } 5466 if (trackvfork) { 5467 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 5468 PTRACE_VFORK); 5469 } 5470 5471 ATF_REQUIRE_EQ(state.pe_other_pid, child); 5472 5473 DPRINTF("Before resuming the forkee process where it left off " 5474 "and without signal to be sent\n"); 5475 SYSCALL_REQUIRE( 5476 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 5477 5478 DPRINTF("Before resuming the child process where it left off " 5479 "and without signal to be sent\n"); 5480 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5481 } 5482 5483 if (trackvforkdone) { 5484 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 5485 child); 5486 TWAIT_REQUIRE_SUCCESS( 5487 wpid = TWAIT_GENERIC(child, &status, 0), child); 5488 5489 validate_status_stopped(status, SIGTRAP); 5490 5491 name[3] = child; 5492 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5493 5494 /* 5495 * SIGCHLD is now pending in the signal queue and 5496 * the kernel presents it to userland as a masked signal. 5497 */ 5498 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 5499 5500 if (masked) { 5501 DPRINTF("kp_sigmask=" 5502 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5503 PRIx32 "\n", 5504 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5505 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5506 5507 DPRINTF("kp.p_sigmask=" 5508 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5509 PRIx32 "\n", 5510 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5511 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5512 5513 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5514 sizeof(kp_sigmask))); 5515 } 5516 5517 if (ignored) { 5518 DPRINTF("kp_sigignore=" 5519 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5520 PRIx32 "\n", 5521 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5522 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5523 5524 DPRINTF("kp.p_sigignore=" 5525 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5526 PRIx32 "\n", 5527 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5528 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5529 5530 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5531 sizeof(kp_sigignore))); 5532 } 5533 5534 SYSCALL_REQUIRE( 5535 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5536 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 5537 5538 child2 = state.pe_other_pid; 5539 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 5540 child2); 5541 5542 DPRINTF("Before resuming the child process where it left off " 5543 "and without signal to be sent\n"); 5544 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5545 } 5546 5547 if (trackfork || trackvfork) { 5548 DPRINTF("Before calling %s() for the forkee - expected exited" 5549 "\n", TWAIT_FNAME); 5550 TWAIT_REQUIRE_SUCCESS( 5551 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 5552 5553 validate_status_exited(status, exitval2); 5554 5555 DPRINTF("Before calling %s() for the forkee - expected no " 5556 "process\n", TWAIT_FNAME); 5557 TWAIT_REQUIRE_FAILURE(ECHILD, 5558 wpid = TWAIT_GENERIC(child2, &status, 0)); 5559 } 5560 5561 DPRINTF("Before calling %s() for the child - expected stopped " 5562 "SIGCHLD\n", TWAIT_FNAME); 5563 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5564 5565 validate_status_stopped(status, SIGCHLD); 5566 5567 DPRINTF("Before resuming the child process where it left off and " 5568 "without signal to be sent\n"); 5569 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5570 5571 DPRINTF("Before calling %s() for the child - expected exited\n", 5572 TWAIT_FNAME); 5573 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5574 5575 validate_status_exited(status, exitval); 5576 5577 DPRINTF("Before calling %s() for the child - expected no process\n", 5578 TWAIT_FNAME); 5579 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5580} 5581 5582#define FORK2_TEST(name,trackfork,trackvfork,trackvforkdone, \ 5583 masked,ignored) \ 5584ATF_TC(name); \ 5585ATF_TC_HEAD(name, tc) \ 5586{ \ 5587 atf_tc_set_md_var(tc, "descr", "Verify that %s%s%s is caught " \ 5588 "regardless of signal %s%s", \ 5589 trackfork ? "PTRACE_FORK" : "", \ 5590 trackvfork ? "PTRACE_VFORK" : "", \ 5591 trackvforkdone ? "PTRACE_VFORK_DONE" : "", \ 5592 masked ? "masked" : "", ignored ? "ignored" : ""); \ 5593} \ 5594 \ 5595ATF_TC_BODY(name, tc) \ 5596{ \ 5597 \ 5598 fork2_body(trackfork, trackvfork, trackvforkdone, masked, \ 5599 ignored); \ 5600} 5601 5602FORK2_TEST(fork_singalmasked, true, false, false, true, false) 5603FORK2_TEST(fork_singalignored, true, false, false, false, true) 5604FORK2_TEST(vfork_singalmasked, false, true, false, true, false) 5605FORK2_TEST(vfork_singalignored, false, true, false, false, true) 5606FORK2_TEST(vforkdone_singalmasked, false, false, true, true, false) 5607FORK2_TEST(vforkdone_singalignored, false, false, true, false, true) 5608#endif 5609 5610/// ---------------------------------------------------------------------------- 5611 5612volatile lwpid_t the_lwp_id = 0; 5613 5614static void 5615lwp_main_func(void *arg) 5616{ 5617 the_lwp_id = _lwp_self(); 5618 _lwp_exit(); 5619} 5620 5621ATF_TC(signal9); 5622ATF_TC_HEAD(signal9, tc) 5623{ 5624 atf_tc_set_md_var(tc, "descr", 5625 "Verify that masking SIGTRAP in tracee does not stop tracer from " 5626 "catching PTRACE_LWP_CREATE breakpoint"); 5627} 5628 5629ATF_TC_BODY(signal9, tc) 5630{ 5631 const int exitval = 5; 5632 const int sigval = SIGSTOP; 5633 const int sigmasked = SIGTRAP; 5634 pid_t child, wpid; 5635#if defined(TWAIT_HAVE_STATUS) 5636 int status; 5637#endif 5638 sigset_t intmask; 5639 ptrace_state_t state; 5640 const int slen = sizeof(state); 5641 ptrace_event_t event; 5642 const int elen = sizeof(event); 5643 ucontext_t uc; 5644 lwpid_t lid; 5645 static const size_t ssize = 16*1024; 5646 void *stack; 5647 5648 atf_tc_expect_fail("PR kern/51918"); 5649 5650 DPRINTF("Before forking process PID=%d\n", getpid()); 5651 SYSCALL_REQUIRE((child = fork()) != -1); 5652 if (child == 0) { 5653 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5654 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5655 5656 sigemptyset(&intmask); 5657 sigaddset(&intmask, sigmasked); 5658 sigprocmask(SIG_BLOCK, &intmask, NULL); 5659 5660 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5661 FORKEE_ASSERT(raise(sigval) == 0); 5662 5663 DPRINTF("Before allocating memory for stack in child\n"); 5664 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5665 5666 DPRINTF("Before making context for new lwp in child\n"); 5667 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 5668 5669 DPRINTF("Before creating new in child\n"); 5670 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5671 5672 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5673 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5674 5675 DPRINTF("Before verifying that reported %d and running lid %d " 5676 "are the same\n", lid, the_lwp_id); 5677 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5678 5679 DPRINTF("Before exiting of the child process\n"); 5680 _exit(exitval); 5681 } 5682 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5683 5684 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5685 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5686 5687 validate_status_stopped(status, sigval); 5688 5689 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 5690 event.pe_set_event = PTRACE_LWP_CREATE; 5691 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5692 5693 DPRINTF("Before resuming the child process where it left off and " 5694 "without signal to be sent\n"); 5695 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5696 5697 DPRINTF("Before calling %s() for the child - expected stopped " 5698 "SIGTRAP\n", TWAIT_FNAME); 5699 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5700 5701 validate_status_stopped(status, sigmasked); 5702 5703 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5704 5705 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 5706 5707 lid = state.pe_lwp; 5708 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 5709 5710 DPRINTF("Before resuming the child process where it left off and " 5711 "without signal to be sent\n"); 5712 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5713 5714 DPRINTF("Before calling %s() for the child - expected exited\n", 5715 TWAIT_FNAME); 5716 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5717 5718 validate_status_exited(status, exitval); 5719 5720 DPRINTF("Before calling %s() for the child - expected no process\n", 5721 TWAIT_FNAME); 5722 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5723} 5724 5725ATF_TC(signal10); 5726ATF_TC_HEAD(signal10, tc) 5727{ 5728 atf_tc_set_md_var(tc, "descr", 5729 "Verify that masking SIGTRAP in tracee does not stop tracer from " 5730 "catching PTRACE_LWP_EXIT breakpoint"); 5731} 5732 5733ATF_TC_BODY(signal10, tc) 5734{ 5735 const int exitval = 5; 5736 const int sigval = SIGSTOP; 5737 const int sigmasked = SIGTRAP; 5738 pid_t child, wpid; 5739#if defined(TWAIT_HAVE_STATUS) 5740 int status; 5741#endif 5742 sigset_t intmask; 5743 ptrace_state_t state; 5744 const int slen = sizeof(state); 5745 ptrace_event_t event; 5746 const int elen = sizeof(event); 5747 ucontext_t uc; 5748 lwpid_t lid; 5749 static const size_t ssize = 16*1024; 5750 void *stack; 5751 5752 atf_tc_expect_fail("PR kern/51918"); 5753 5754 DPRINTF("Before forking process PID=%d\n", getpid()); 5755 SYSCALL_REQUIRE((child = fork()) != -1); 5756 if (child == 0) { 5757 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5758 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5759 5760 sigemptyset(&intmask); 5761 sigaddset(&intmask, sigmasked); 5762 sigprocmask(SIG_BLOCK, &intmask, NULL); 5763 5764 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5765 FORKEE_ASSERT(raise(sigval) == 0); 5766 5767 DPRINTF("Before allocating memory for stack in child\n"); 5768 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5769 5770 DPRINTF("Before making context for new lwp in child\n"); 5771 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 5772 5773 DPRINTF("Before creating new in child\n"); 5774 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5775 5776 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5777 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5778 5779 DPRINTF("Before verifying that reported %d and running lid %d " 5780 "are the same\n", lid, the_lwp_id); 5781 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5782 5783 DPRINTF("Before exiting of the child process\n"); 5784 _exit(exitval); 5785 } 5786 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5787 5788 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5789 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5790 5791 validate_status_stopped(status, sigval); 5792 5793 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 5794 event.pe_set_event = PTRACE_LWP_EXIT; 5795 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5796 5797 DPRINTF("Before resuming the child process where it left off and " 5798 "without signal to be sent\n"); 5799 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5800 5801 DPRINTF("Before calling %s() for the child - expected stopped " 5802 "SIGTRAP\n", TWAIT_FNAME); 5803 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5804 5805 validate_status_stopped(status, sigmasked); 5806 5807 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5808 5809 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 5810 5811 lid = state.pe_lwp; 5812 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 5813 5814 DPRINTF("Before resuming the child process where it left off and " 5815 "without signal to be sent\n"); 5816 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5817 5818 DPRINTF("Before calling %s() for the child - expected exited\n", 5819 TWAIT_FNAME); 5820 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5821 5822 validate_status_exited(status, exitval); 5823 5824 DPRINTF("Before calling %s() for the child - expected no process\n", 5825 TWAIT_FNAME); 5826 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5827} 5828 5829static void 5830lwp_main_stop(void *arg) 5831{ 5832 the_lwp_id = _lwp_self(); 5833 5834 raise(SIGTRAP); 5835 5836 _lwp_exit(); 5837} 5838 5839ATF_TC(suspend1); 5840ATF_TC_HEAD(suspend1, tc) 5841{ 5842 atf_tc_set_md_var(tc, "descr", 5843 "Verify that a thread can be suspended by a debugger and later " 5844 "resumed by a tracee"); 5845} 5846 5847ATF_TC_BODY(suspend1, tc) 5848{ 5849 const int exitval = 5; 5850 const int sigval = SIGSTOP; 5851 pid_t child, wpid; 5852#if defined(TWAIT_HAVE_STATUS) 5853 int status; 5854#endif 5855 ucontext_t uc; 5856 lwpid_t lid; 5857 static const size_t ssize = 16*1024; 5858 void *stack; 5859 struct ptrace_lwpinfo pl; 5860 struct ptrace_siginfo psi; 5861 volatile int go = 0; 5862 5863 // Feature pending for refactoring 5864 atf_tc_expect_fail("PR kern/51995"); 5865 5866 // Hangs with qemu 5867 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5868 5869 DPRINTF("Before forking process PID=%d\n", getpid()); 5870 SYSCALL_REQUIRE((child = fork()) != -1); 5871 if (child == 0) { 5872 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5873 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5874 5875 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5876 FORKEE_ASSERT(raise(sigval) == 0); 5877 5878 DPRINTF("Before allocating memory for stack in child\n"); 5879 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5880 5881 DPRINTF("Before making context for new lwp in child\n"); 5882 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 5883 5884 DPRINTF("Before creating new in child\n"); 5885 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5886 5887 while (go == 0) 5888 continue; 5889 5890 raise(SIGINT); 5891 5892 FORKEE_ASSERT(_lwp_continue(lid) == 0); 5893 5894 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5895 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5896 5897 DPRINTF("Before verifying that reported %d and running lid %d " 5898 "are the same\n", lid, the_lwp_id); 5899 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5900 5901 DPRINTF("Before exiting of the child process\n"); 5902 _exit(exitval); 5903 } 5904 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5905 5906 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5907 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5908 5909 validate_status_stopped(status, sigval); 5910 5911 DPRINTF("Before resuming the child process where it left off and " 5912 "without signal to be sent\n"); 5913 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5914 5915 DPRINTF("Before calling %s() for the child - expected stopped " 5916 "SIGTRAP\n", TWAIT_FNAME); 5917 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5918 5919 validate_status_stopped(status, SIGTRAP); 5920 5921 DPRINTF("Before reading siginfo and lwpid_t\n"); 5922 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5923 5924 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5925 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5926 5927 DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 5928 child, getpid()); 5929 SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 5930 5931 DPRINTF("Before resuming the child process where it left off and " 5932 "without signal to be sent\n"); 5933 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5934 5935 DPRINTF("Before calling %s() for the child - expected stopped " 5936 "SIGINT\n", TWAIT_FNAME); 5937 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5938 5939 validate_status_stopped(status, SIGINT); 5940 5941 pl.pl_lwpid = 0; 5942 5943 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5944 while (pl.pl_lwpid != 0) { 5945 5946 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5947 switch (pl.pl_lwpid) { 5948 case 1: 5949 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 5950 break; 5951 case 2: 5952 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 5953 break; 5954 } 5955 } 5956 5957 DPRINTF("Before resuming the child process where it left off and " 5958 "without signal to be sent\n"); 5959 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5960 5961 DPRINTF("Before calling %s() for the child - expected exited\n", 5962 TWAIT_FNAME); 5963 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5964 5965 validate_status_exited(status, exitval); 5966 5967 DPRINTF("Before calling %s() for the child - expected no process\n", 5968 TWAIT_FNAME); 5969 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5970} 5971 5972ATF_TC(suspend2); 5973ATF_TC_HEAD(suspend2, tc) 5974{ 5975 atf_tc_set_md_var(tc, "descr", 5976 "Verify that the while the only thread within a process is " 5977 "suspended, the whole process cannot be unstopped"); 5978} 5979 5980ATF_TC_BODY(suspend2, tc) 5981{ 5982 const int exitval = 5; 5983 const int sigval = SIGSTOP; 5984 pid_t child, wpid; 5985#if defined(TWAIT_HAVE_STATUS) 5986 int status; 5987#endif 5988 struct ptrace_siginfo psi; 5989 5990 // Feature pending for refactoring 5991 atf_tc_expect_fail("PR kern/51995"); 5992 5993 // Hangs with qemu 5994 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5995 5996 DPRINTF("Before forking process PID=%d\n", getpid()); 5997 SYSCALL_REQUIRE((child = fork()) != -1); 5998 if (child == 0) { 5999 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6000 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6001 6002 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6003 FORKEE_ASSERT(raise(sigval) == 0); 6004 6005 DPRINTF("Before exiting of the child process\n"); 6006 _exit(exitval); 6007 } 6008 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6009 6010 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6011 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6012 6013 validate_status_stopped(status, sigval); 6014 6015 DPRINTF("Before reading siginfo and lwpid_t\n"); 6016 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6017 6018 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6019 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6020 6021 DPRINTF("Before resuming the child process where it left off and " 6022 "without signal to be sent\n"); 6023 ATF_REQUIRE_ERRNO(EDEADLK, 6024 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 6025 6026 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6027 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6028 6029 DPRINTF("Before resuming the child process where it left off and " 6030 "without signal to be sent\n"); 6031 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6032 6033 DPRINTF("Before calling %s() for the child - expected exited\n", 6034 TWAIT_FNAME); 6035 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6036 6037 validate_status_exited(status, exitval); 6038 6039 DPRINTF("Before calling %s() for the child - expected no process\n", 6040 TWAIT_FNAME); 6041 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6042} 6043 6044ATF_TC(resume1); 6045ATF_TC_HEAD(resume1, tc) 6046{ 6047 atf_tc_set_md_var(tc, "timeout", "5"); 6048 atf_tc_set_md_var(tc, "descr", 6049 "Verify that a thread can be suspended by a debugger and later " 6050 "resumed by the debugger"); 6051} 6052 6053ATF_TC_BODY(resume1, tc) 6054{ 6055 struct msg_fds fds; 6056 const int exitval = 5; 6057 const int sigval = SIGSTOP; 6058 pid_t child, wpid; 6059 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 6060#if defined(TWAIT_HAVE_STATUS) 6061 int status; 6062#endif 6063 ucontext_t uc; 6064 lwpid_t lid; 6065 static const size_t ssize = 16*1024; 6066 void *stack; 6067 struct ptrace_lwpinfo pl; 6068 struct ptrace_siginfo psi; 6069 6070 // Feature pending for refactoring 6071 atf_tc_expect_fail("PR kern/51995"); 6072 6073 // Hangs with qemu 6074 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 6075 6076 SYSCALL_REQUIRE(msg_open(&fds) == 0); 6077 6078 DPRINTF("Before forking process PID=%d\n", getpid()); 6079 SYSCALL_REQUIRE((child = fork()) != -1); 6080 if (child == 0) { 6081 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6082 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6083 6084 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6085 FORKEE_ASSERT(raise(sigval) == 0); 6086 6087 DPRINTF("Before allocating memory for stack in child\n"); 6088 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6089 6090 DPRINTF("Before making context for new lwp in child\n"); 6091 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 6092 6093 DPRINTF("Before creating new in child\n"); 6094 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6095 6096 CHILD_TO_PARENT("Message", fds, msg); 6097 6098 raise(SIGINT); 6099 6100 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6101 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6102 6103 DPRINTF("Before verifying that reported %d and running lid %d " 6104 "are the same\n", lid, the_lwp_id); 6105 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6106 6107 DPRINTF("Before exiting of the child process\n"); 6108 _exit(exitval); 6109 } 6110 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6111 6112 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6113 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6114 6115 validate_status_stopped(status, sigval); 6116 6117 DPRINTF("Before resuming the child process where it left off and " 6118 "without signal to be sent\n"); 6119 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6120 6121 DPRINTF("Before calling %s() for the child - expected stopped " 6122 "SIGTRAP\n", TWAIT_FNAME); 6123 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6124 6125 validate_status_stopped(status, SIGTRAP); 6126 6127 DPRINTF("Before reading siginfo and lwpid_t\n"); 6128 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6129 6130 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6131 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6132 6133 PARENT_FROM_CHILD("Message", fds, msg); 6134 6135 DPRINTF("Before resuming the child process where it left off and " 6136 "without signal to be sent\n"); 6137 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6138 6139 DPRINTF("Before calling %s() for the child - expected stopped " 6140 "SIGINT\n", TWAIT_FNAME); 6141 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6142 6143 validate_status_stopped(status, SIGINT); 6144 6145 pl.pl_lwpid = 0; 6146 6147 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6148 while (pl.pl_lwpid != 0) { 6149 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6150 switch (pl.pl_lwpid) { 6151 case 1: 6152 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 6153 break; 6154 case 2: 6155 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 6156 break; 6157 } 6158 } 6159 6160 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6161 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6162 6163 DPRINTF("Before resuming the child process where it left off and " 6164 "without signal to be sent\n"); 6165 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6166 6167 DPRINTF("Before calling %s() for the child - expected exited\n", 6168 TWAIT_FNAME); 6169 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6170 6171 validate_status_exited(status, exitval); 6172 6173 DPRINTF("Before calling %s() for the child - expected no process\n", 6174 TWAIT_FNAME); 6175 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6176 6177 msg_close(&fds); 6178 6179 DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 6180 sleep(10); 6181} 6182 6183ATF_TC(syscall1); 6184ATF_TC_HEAD(syscall1, tc) 6185{ 6186 atf_tc_set_md_var(tc, "descr", 6187 "Verify that getpid(2) can be traced with PT_SYSCALL"); 6188} 6189 6190ATF_TC_BODY(syscall1, tc) 6191{ 6192 const int exitval = 5; 6193 const int sigval = SIGSTOP; 6194 pid_t child, wpid; 6195#if defined(TWAIT_HAVE_STATUS) 6196 int status; 6197#endif 6198 struct ptrace_siginfo info; 6199 memset(&info, 0, sizeof(info)); 6200 6201 DPRINTF("Before forking process PID=%d\n", getpid()); 6202 SYSCALL_REQUIRE((child = fork()) != -1); 6203 if (child == 0) { 6204 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6205 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6206 6207 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6208 FORKEE_ASSERT(raise(sigval) == 0); 6209 6210 syscall(SYS_getpid); 6211 6212 DPRINTF("Before exiting of the child process\n"); 6213 _exit(exitval); 6214 } 6215 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6216 6217 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6218 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6219 6220 validate_status_stopped(status, sigval); 6221 6222 DPRINTF("Before resuming the child process where it left off and " 6223 "without signal to be sent\n"); 6224 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6225 6226 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6227 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6228 6229 validate_status_stopped(status, SIGTRAP); 6230 6231 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6232 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6233 6234 DPRINTF("Before checking siginfo_t and lwpid\n"); 6235 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6236 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6237 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 6238 6239 DPRINTF("Before resuming the child process where it left off and " 6240 "without signal to be sent\n"); 6241 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6242 6243 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6244 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6245 6246 validate_status_stopped(status, SIGTRAP); 6247 6248 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6249 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6250 6251 DPRINTF("Before checking siginfo_t and lwpid\n"); 6252 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6253 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6254 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 6255 6256 DPRINTF("Before resuming the child process where it left off and " 6257 "without signal to be sent\n"); 6258 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6259 6260 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6262 6263 validate_status_exited(status, exitval); 6264 6265 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6266 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6267} 6268 6269ATF_TC(syscallemu1); 6270ATF_TC_HEAD(syscallemu1, tc) 6271{ 6272 atf_tc_set_md_var(tc, "descr", 6273 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 6274} 6275 6276ATF_TC_BODY(syscallemu1, tc) 6277{ 6278 const int exitval = 5; 6279 const int sigval = SIGSTOP; 6280 pid_t child, wpid; 6281#if defined(TWAIT_HAVE_STATUS) 6282 int status; 6283#endif 6284 6285#if defined(__sparc__) && !defined(__sparc64__) 6286 /* syscallemu does not work on sparc (32-bit) */ 6287 atf_tc_expect_fail("PR kern/52166"); 6288#endif 6289 6290 DPRINTF("Before forking process PID=%d\n", getpid()); 6291 SYSCALL_REQUIRE((child = fork()) != -1); 6292 if (child == 0) { 6293 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6294 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6295 6296 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6297 FORKEE_ASSERT(raise(sigval) == 0); 6298 6299 syscall(SYS_exit, 100); 6300 6301 DPRINTF("Before exiting of the child process\n"); 6302 _exit(exitval); 6303 } 6304 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6305 6306 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6307 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6308 6309 validate_status_stopped(status, sigval); 6310 6311 DPRINTF("Before resuming the child process where it left off and " 6312 "without signal to be sent\n"); 6313 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6314 6315 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6316 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6317 6318 validate_status_stopped(status, SIGTRAP); 6319 6320 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 6321 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 6322 6323 DPRINTF("Before resuming the child process where it left off and " 6324 "without signal to be sent\n"); 6325 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6326 6327 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6328 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6329 6330 validate_status_stopped(status, SIGTRAP); 6331 6332 DPRINTF("Before resuming the child process where it left off and " 6333 "without signal to be sent\n"); 6334 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6335 6336 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6337 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6338 6339 validate_status_exited(status, exitval); 6340 6341 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6342 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6343} 6344 6345/// ---------------------------------------------------------------------------- 6346 6347static void 6348clone_body(int flags, bool trackfork, bool trackvfork, 6349 bool trackvforkdone) 6350{ 6351 const int exitval = 5; 6352 const int exitval2 = 15; 6353 const int sigval = SIGSTOP; 6354 pid_t child, child2 = 0, wpid; 6355#if defined(TWAIT_HAVE_STATUS) 6356 int status; 6357#endif 6358 ptrace_state_t state; 6359 const int slen = sizeof(state); 6360 ptrace_event_t event; 6361 const int elen = sizeof(event); 6362 6363 const size_t stack_size = 1024 * 1024; 6364 void *stack, *stack_base; 6365 6366 stack = malloc(stack_size); 6367 ATF_REQUIRE(stack != NULL); 6368 6369#ifdef __MACHINE_STACK_GROWS_UP 6370 stack_base = stack; 6371#else 6372 stack_base = (char *)stack + stack_size; 6373#endif 6374 6375 DPRINTF("Before forking process PID=%d\n", getpid()); 6376 SYSCALL_REQUIRE((child = fork()) != -1); 6377 if (child == 0) { 6378 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6379 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6380 6381 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6382 FORKEE_ASSERT(raise(sigval) == 0); 6383 6384 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 6385 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 6386 6387 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 6388 child2); 6389 6390 // XXX WALLSIG? 6391 FORKEE_REQUIRE_SUCCESS 6392 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 6393 6394 forkee_status_exited(status, exitval2); 6395 6396 DPRINTF("Before exiting of the child process\n"); 6397 _exit(exitval); 6398 } 6399 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6400 6401 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6402 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6403 6404 validate_status_stopped(status, sigval); 6405 6406 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 6407 trackfork ? "|PTRACE_FORK" : "", 6408 trackvfork ? "|PTRACE_VFORK" : "", 6409 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 6410 event.pe_set_event = 0; 6411 if (trackfork) 6412 event.pe_set_event |= PTRACE_FORK; 6413 if (trackvfork) 6414 event.pe_set_event |= PTRACE_VFORK; 6415 if (trackvforkdone) 6416 event.pe_set_event |= PTRACE_VFORK_DONE; 6417 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6418 6419 DPRINTF("Before resuming the child process where it left off and " 6420 "without signal to be sent\n"); 6421 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6422 6423#if defined(TWAIT_HAVE_PID) 6424 if ((trackfork && !(flags & CLONE_VFORK)) || 6425 (trackvfork && (flags & CLONE_VFORK))) { 6426 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6427 child); 6428 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6429 child); 6430 6431 validate_status_stopped(status, SIGTRAP); 6432 6433 SYSCALL_REQUIRE( 6434 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6435 if (trackfork && !(flags & CLONE_VFORK)) { 6436 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6437 PTRACE_FORK); 6438 } 6439 if (trackvfork && (flags & CLONE_VFORK)) { 6440 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6441 PTRACE_VFORK); 6442 } 6443 6444 child2 = state.pe_other_pid; 6445 DPRINTF("Reported ptrace event with forkee %d\n", child2); 6446 6447 DPRINTF("Before calling %s() for the forkee %d of the child " 6448 "%d\n", TWAIT_FNAME, child2, child); 6449 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 6450 child2); 6451 6452 validate_status_stopped(status, SIGTRAP); 6453 6454 SYSCALL_REQUIRE( 6455 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 6456 if (trackfork && !(flags & CLONE_VFORK)) { 6457 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6458 PTRACE_FORK); 6459 } 6460 if (trackvfork && (flags & CLONE_VFORK)) { 6461 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6462 PTRACE_VFORK); 6463 } 6464 6465 ATF_REQUIRE_EQ(state.pe_other_pid, child); 6466 6467 DPRINTF("Before resuming the forkee process where it left off " 6468 "and without signal to be sent\n"); 6469 SYSCALL_REQUIRE( 6470 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6471 6472 DPRINTF("Before resuming the child process where it left off " 6473 "and without signal to be sent\n"); 6474 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6475 } 6476#endif 6477 6478 if (trackvforkdone && (flags & CLONE_VFORK)) { 6479 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6480 child); 6481 TWAIT_REQUIRE_SUCCESS( 6482 wpid = TWAIT_GENERIC(child, &status, 0), child); 6483 6484 validate_status_stopped(status, SIGTRAP); 6485 6486 SYSCALL_REQUIRE( 6487 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6488 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6489 6490 child2 = state.pe_other_pid; 6491 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6492 child2); 6493 6494 DPRINTF("Before resuming the child process where it left off " 6495 "and without signal to be sent\n"); 6496 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6497 } 6498 6499#if defined(TWAIT_HAVE_PID) 6500 if ((trackfork && !(flags & CLONE_VFORK)) || 6501 (trackvfork && (flags & CLONE_VFORK))) { 6502 DPRINTF("Before calling %s() for the forkee - expected exited" 6503 "\n", TWAIT_FNAME); 6504 TWAIT_REQUIRE_SUCCESS( 6505 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6506 6507 validate_status_exited(status, exitval2); 6508 6509 DPRINTF("Before calling %s() for the forkee - expected no " 6510 "process\n", TWAIT_FNAME); 6511 TWAIT_REQUIRE_FAILURE(ECHILD, 6512 wpid = TWAIT_GENERIC(child2, &status, 0)); 6513 } 6514#endif 6515 6516 DPRINTF("Before calling %s() for the child - expected stopped " 6517 "SIGCHLD\n", TWAIT_FNAME); 6518 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6519 6520 validate_status_stopped(status, SIGCHLD); 6521 6522 DPRINTF("Before resuming the child process where it left off and " 6523 "without signal to be sent\n"); 6524 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6525 6526 DPRINTF("Before calling %s() for the child - expected exited\n", 6527 TWAIT_FNAME); 6528 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6529 6530 validate_status_exited(status, exitval); 6531 6532 DPRINTF("Before calling %s() for the child - expected no process\n", 6533 TWAIT_FNAME); 6534 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6535} 6536 6537#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \ 6538ATF_TC(name); \ 6539ATF_TC_HEAD(name, tc) \ 6540{ \ 6541 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \ 6542 "called with 0%s%s%s in EVENT_MASK", \ 6543 #flags, \ 6544 tfork ? "|PTRACE_FORK" : "", \ 6545 tvfork ? "|PTRACE_VFORK" : "", \ 6546 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 6547} \ 6548 \ 6549ATF_TC_BODY(name, tc) \ 6550{ \ 6551 \ 6552 clone_body(flags, tfork, tvfork, tvforkdone); \ 6553} 6554 6555CLONE_TEST(clone1, 0, false, false, false) 6556#if defined(TWAIT_HAVE_PID) 6557CLONE_TEST(clone2, 0, true, false, false) 6558CLONE_TEST(clone3, 0, false, true, false) 6559CLONE_TEST(clone4, 0, true, true, false) 6560#endif 6561CLONE_TEST(clone5, 0, false, false, true) 6562#if defined(TWAIT_HAVE_PID) 6563CLONE_TEST(clone6, 0, true, false, true) 6564CLONE_TEST(clone7, 0, false, true, true) 6565CLONE_TEST(clone8, 0, true, true, true) 6566#endif 6567 6568CLONE_TEST(clone_vm1, CLONE_VM, false, false, false) 6569#if defined(TWAIT_HAVE_PID) 6570CLONE_TEST(clone_vm2, CLONE_VM, true, false, false) 6571CLONE_TEST(clone_vm3, CLONE_VM, false, true, false) 6572CLONE_TEST(clone_vm4, CLONE_VM, true, true, false) 6573#endif 6574CLONE_TEST(clone_vm5, CLONE_VM, false, false, true) 6575#if defined(TWAIT_HAVE_PID) 6576CLONE_TEST(clone_vm6, CLONE_VM, true, false, true) 6577CLONE_TEST(clone_vm7, CLONE_VM, false, true, true) 6578CLONE_TEST(clone_vm8, CLONE_VM, true, true, true) 6579#endif 6580 6581CLONE_TEST(clone_fs1, CLONE_FS, false, false, false) 6582#if defined(TWAIT_HAVE_PID) 6583CLONE_TEST(clone_fs2, CLONE_FS, true, false, false) 6584CLONE_TEST(clone_fs3, CLONE_FS, false, true, false) 6585CLONE_TEST(clone_fs4, CLONE_FS, true, true, false) 6586#endif 6587CLONE_TEST(clone_fs5, CLONE_FS, false, false, true) 6588#if defined(TWAIT_HAVE_PID) 6589CLONE_TEST(clone_fs6, CLONE_FS, true, false, true) 6590CLONE_TEST(clone_fs7, CLONE_FS, false, true, true) 6591CLONE_TEST(clone_fs8, CLONE_FS, true, true, true) 6592#endif 6593 6594CLONE_TEST(clone_files1, CLONE_FILES, false, false, false) 6595#if defined(TWAIT_HAVE_PID) 6596CLONE_TEST(clone_files2, CLONE_FILES, true, false, false) 6597CLONE_TEST(clone_files3, CLONE_FILES, false, true, false) 6598CLONE_TEST(clone_files4, CLONE_FILES, true, true, false) 6599#endif 6600CLONE_TEST(clone_files5, CLONE_FILES, false, false, true) 6601#if defined(TWAIT_HAVE_PID) 6602CLONE_TEST(clone_files6, CLONE_FILES, true, false, true) 6603CLONE_TEST(clone_files7, CLONE_FILES, false, true, true) 6604CLONE_TEST(clone_files8, CLONE_FILES, true, true, true) 6605#endif 6606 6607//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false) 6608#if defined(TWAIT_HAVE_PID) 6609//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false) 6610//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false) 6611//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false) 6612#endif 6613//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true) 6614#if defined(TWAIT_HAVE_PID) 6615//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true) 6616//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true) 6617//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true) 6618#endif 6619 6620CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false) 6621#if defined(TWAIT_HAVE_PID) 6622CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false) 6623CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false) 6624CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false) 6625#endif 6626CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true) 6627#if defined(TWAIT_HAVE_PID) 6628CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true) 6629CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true) 6630CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true) 6631#endif 6632 6633/// ---------------------------------------------------------------------------- 6634 6635#if defined(TWAIT_HAVE_PID) 6636static void 6637clone_body2(int flags, bool masked, bool ignored) 6638{ 6639 const int exitval = 5; 6640 const int exitval2 = 15; 6641 const int sigval = SIGSTOP; 6642 pid_t child, child2 = 0, wpid; 6643#if defined(TWAIT_HAVE_STATUS) 6644 int status; 6645#endif 6646 ptrace_state_t state; 6647 const int slen = sizeof(state); 6648 ptrace_event_t event; 6649 const int elen = sizeof(event); 6650 struct sigaction sa; 6651 struct ptrace_siginfo info; 6652 sigset_t intmask; 6653 struct kinfo_proc2 kp; 6654 size_t len = sizeof(kp); 6655 6656 int name[6]; 6657 const size_t namelen = __arraycount(name); 6658 ki_sigset_t kp_sigmask; 6659 ki_sigset_t kp_sigignore; 6660 6661 const size_t stack_size = 1024 * 1024; 6662 void *stack, *stack_base; 6663 6664 stack = malloc(stack_size); 6665 ATF_REQUIRE(stack != NULL); 6666 6667#ifdef __MACHINE_STACK_GROWS_UP 6668 stack_base = stack; 6669#else 6670 stack_base = (char *)stack + stack_size; 6671#endif 6672 6673 SYSCALL_REQUIRE((child = fork()) != -1); 6674 if (child == 0) { 6675 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6676 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6677 6678 if (masked) { 6679 sigemptyset(&intmask); 6680 sigaddset(&intmask, SIGTRAP); 6681 sigprocmask(SIG_BLOCK, &intmask, NULL); 6682 } 6683 6684 if (ignored) { 6685 memset(&sa, 0, sizeof(sa)); 6686 sa.sa_handler = SIG_IGN; 6687 sigemptyset(&sa.sa_mask); 6688 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 6689 } 6690 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6691 FORKEE_ASSERT(raise(sigval) == 0); 6692 6693 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 6694 flags); 6695 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 6696 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 6697 6698 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 6699 child2); 6700 6701 // XXX WALLSIG? 6702 FORKEE_REQUIRE_SUCCESS 6703 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 6704 6705 forkee_status_exited(status, exitval2); 6706 6707 DPRINTF("Before exiting of the child process\n"); 6708 _exit(exitval); 6709 } 6710 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6711 6712 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6713 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6714 6715 validate_status_stopped(status, sigval); 6716 6717 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6718 SYSCALL_REQUIRE( 6719 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6720 6721 DPRINTF("Before checking siginfo_t\n"); 6722 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6723 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6724 6725 name[0] = CTL_KERN, 6726 name[1] = KERN_PROC2, 6727 name[2] = KERN_PROC_PID; 6728 name[3] = child; 6729 name[4] = sizeof(kp); 6730 name[5] = 1; 6731 6732 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6733 6734 if (masked) 6735 kp_sigmask = kp.p_sigmask; 6736 6737 if (ignored) 6738 kp_sigignore = kp.p_sigignore; 6739 6740 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in " 6741 "EVENT_MASK for the child %d\n", child); 6742 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; 6743 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6744 6745 DPRINTF("Before resuming the child process where it left off and " 6746 "without signal to be sent\n"); 6747 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6748 6749 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6750 child); 6751 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6752 child); 6753 6754 validate_status_stopped(status, SIGTRAP); 6755 6756 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6757 6758 if (masked) { 6759 DPRINTF("kp_sigmask=" 6760 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6761 PRIx32 "\n", 6762 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6763 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6764 6765 DPRINTF("kp.p_sigmask=" 6766 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6767 PRIx32 "\n", 6768 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6769 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6770 6771 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6772 sizeof(kp_sigmask))); 6773 } 6774 6775 if (ignored) { 6776 DPRINTF("kp_sigignore=" 6777 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6778 PRIx32 "\n", 6779 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6780 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6781 6782 DPRINTF("kp.p_sigignore=" 6783 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6784 PRIx32 "\n", 6785 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6786 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6787 6788 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6789 sizeof(kp_sigignore))); 6790 } 6791 6792 SYSCALL_REQUIRE( 6793 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6794 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event, 6795 child2); 6796 if (!(flags & CLONE_VFORK)) { 6797 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6798 PTRACE_FORK); 6799 } else { 6800 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6801 PTRACE_VFORK); 6802 } 6803 6804 child2 = state.pe_other_pid; 6805 DPRINTF("Reported ptrace event with forkee %d\n", child2); 6806 6807 DPRINTF("Before calling %s() for the forkee %d of the child " 6808 "%d\n", TWAIT_FNAME, child2, child); 6809 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 6810 child2); 6811 6812 validate_status_stopped(status, SIGTRAP); 6813 6814 name[3] = child2; 6815 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6816 6817 if (masked) { 6818 DPRINTF("kp_sigmask=" 6819 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6820 PRIx32 "\n", 6821 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6822 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6823 6824 DPRINTF("kp.p_sigmask=" 6825 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6826 PRIx32 "\n", 6827 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6828 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6829 6830 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6831 sizeof(kp_sigmask))); 6832 } 6833 6834 if (ignored) { 6835 DPRINTF("kp_sigignore=" 6836 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6837 PRIx32 "\n", 6838 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6839 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6840 6841 DPRINTF("kp.p_sigignore=" 6842 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6843 PRIx32 "\n", 6844 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6845 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6846 6847 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6848 sizeof(kp_sigignore))); 6849 } 6850 6851 SYSCALL_REQUIRE( 6852 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 6853 if (!(flags & CLONE_VFORK)) { 6854 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6855 PTRACE_FORK); 6856 } else { 6857 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6858 PTRACE_VFORK); 6859 } 6860 6861 ATF_REQUIRE_EQ(state.pe_other_pid, child); 6862 6863 DPRINTF("Before resuming the forkee process where it left off " 6864 "and without signal to be sent\n"); 6865 SYSCALL_REQUIRE( 6866 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6867 6868 DPRINTF("Before resuming the child process where it left off " 6869 "and without signal to be sent\n"); 6870 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6871 6872 if (flags & CLONE_VFORK) { 6873 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6874 child); 6875 TWAIT_REQUIRE_SUCCESS( 6876 wpid = TWAIT_GENERIC(child, &status, 0), child); 6877 6878 validate_status_stopped(status, SIGTRAP); 6879 6880 name[3] = child; 6881 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6882 6883 /* 6884 * SIGCHLD is now pending in the signal queue and 6885 * the kernel presents it to userland as a masked signal. 6886 */ 6887 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 6888 6889 if (masked) { 6890 DPRINTF("kp_sigmask=" 6891 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6892 PRIx32 "\n", 6893 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6894 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6895 6896 DPRINTF("kp.p_sigmask=" 6897 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6898 PRIx32 "\n", 6899 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6900 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6901 6902 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6903 sizeof(kp_sigmask))); 6904 } 6905 6906 if (ignored) { 6907 DPRINTF("kp_sigignore=" 6908 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6909 PRIx32 "\n", 6910 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6911 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6912 6913 DPRINTF("kp.p_sigignore=" 6914 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6915 PRIx32 "\n", 6916 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6917 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6918 6919 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6920 sizeof(kp_sigignore))); 6921 } 6922 6923 SYSCALL_REQUIRE( 6924 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6925 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6926 6927 child2 = state.pe_other_pid; 6928 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6929 child2); 6930 6931 DPRINTF("Before resuming the child process where it left off " 6932 "and without signal to be sent\n"); 6933 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6934 } 6935 6936 DPRINTF("Before calling %s() for the forkee - expected exited" 6937 "\n", TWAIT_FNAME); 6938 TWAIT_REQUIRE_SUCCESS( 6939 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6940 6941 validate_status_exited(status, exitval2); 6942 6943 DPRINTF("Before calling %s() for the forkee - expected no " 6944 "process\n", TWAIT_FNAME); 6945 TWAIT_REQUIRE_FAILURE(ECHILD, 6946 wpid = TWAIT_GENERIC(child2, &status, 0)); 6947 6948 DPRINTF("Before calling %s() for the child - expected stopped " 6949 "SIGCHLD\n", TWAIT_FNAME); 6950 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6951 6952 validate_status_stopped(status, SIGCHLD); 6953 6954 DPRINTF("Before resuming the child process where it left off and " 6955 "without signal to be sent\n"); 6956 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6957 6958 DPRINTF("Before calling %s() for the child - expected exited\n", 6959 TWAIT_FNAME); 6960 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6961 6962 validate_status_exited(status, exitval); 6963 6964 DPRINTF("Before calling %s() for the child - expected no process\n", 6965 TWAIT_FNAME); 6966 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6967} 6968 6969#define CLONE_TEST2(name,flags,masked,ignored) \ 6970ATF_TC(name); \ 6971ATF_TC_HEAD(name, tc) \ 6972{ \ 6973 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\ 6974 " regardless of signal %s%s", \ 6975 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \ 6976} \ 6977 \ 6978ATF_TC_BODY(name, tc) \ 6979{ \ 6980 \ 6981 clone_body2(flags, masked, ignored); \ 6982} 6983 6984CLONE_TEST2(clone_signalignored, 0, true, false) 6985CLONE_TEST2(clone_signalmasked, 0, false, true) 6986CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false) 6987CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true) 6988CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false) 6989CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true) 6990CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false) 6991CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true) 6992//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX 6993//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX 6994CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false) 6995CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true) 6996#endif 6997 6998/// ---------------------------------------------------------------------------- 6999 7000#if defined(TWAIT_HAVE_PID) 7001static void 7002traceme_vfork_clone_body(int flags) 7003{ 7004 const int exitval = 5; 7005 const int exitval2 = 15; 7006 pid_t child, child2 = 0, wpid; 7007#if defined(TWAIT_HAVE_STATUS) 7008 int status; 7009#endif 7010 7011 const size_t stack_size = 1024 * 1024; 7012 void *stack, *stack_base; 7013 7014 stack = malloc(stack_size); 7015 ATF_REQUIRE(stack != NULL); 7016 7017#ifdef __MACHINE_STACK_GROWS_UP 7018 stack_base = stack; 7019#else 7020 stack_base = (char *)stack + stack_size; 7021#endif 7022 7023 SYSCALL_REQUIRE((child = vfork()) != -1); 7024 if (child == 0) { 7025 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7026 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7027 7028 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7029 flags); 7030 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7031 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7032 7033 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7034 child2); 7035 7036 // XXX WALLSIG? 7037 FORKEE_REQUIRE_SUCCESS 7038 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7039 7040 forkee_status_exited(status, exitval2); 7041 7042 DPRINTF("Before exiting of the child process\n"); 7043 _exit(exitval); 7044 } 7045 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7046 7047 DPRINTF("Before calling %s() for the child - expected exited\n", 7048 TWAIT_FNAME); 7049 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7050 7051 validate_status_exited(status, exitval); 7052 7053 DPRINTF("Before calling %s() for the child - expected no process\n", 7054 TWAIT_FNAME); 7055 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7056} 7057 7058#define TRACEME_VFORK_CLONE_TEST(name,flags) \ 7059ATF_TC(name); \ 7060ATF_TC_HEAD(name, tc) \ 7061{ \ 7062 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \ 7063 "handled correctly with vfork(2)ed tracer", \ 7064 #flags); \ 7065} \ 7066 \ 7067ATF_TC_BODY(name, tc) \ 7068{ \ 7069 \ 7070 traceme_vfork_clone_body(flags); \ 7071} 7072 7073TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0) 7074TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM) 7075TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS) 7076TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES) 7077//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX 7078TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK) 7079#endif 7080 7081/// ---------------------------------------------------------------------------- 7082 7083#include "t_ptrace_amd64_wait.h" 7084#include "t_ptrace_i386_wait.h" 7085#include "t_ptrace_x86_wait.h" 7086 7087ATF_TP_ADD_TCS(tp) 7088{ 7089 setvbuf(stdout, NULL, _IONBF, 0); 7090 setvbuf(stderr, NULL, _IONBF, 0); 7091 7092 ATF_TP_ADD_TC(tp, traceme_raise1); 7093 ATF_TP_ADD_TC(tp, traceme_raise2); 7094 ATF_TP_ADD_TC(tp, traceme_raise3); 7095 ATF_TP_ADD_TC(tp, traceme_raise4); 7096 ATF_TP_ADD_TC(tp, traceme_raise5); 7097 ATF_TP_ADD_TC(tp, traceme_raise6); 7098 ATF_TP_ADD_TC(tp, traceme_raise7); 7099 ATF_TP_ADD_TC(tp, traceme_raise8); 7100 ATF_TP_ADD_TC(tp, traceme_raise9); 7101 ATF_TP_ADD_TC(tp, traceme_raise10); 7102 7103 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 7104 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 7105 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 7106 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 7107 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 7108 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 7109 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 7110 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 7111 7112 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 7113 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 7114 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 7115 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 7116 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 7117 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 7118 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 7119 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 7120 7121 ATF_TP_ADD_TC(tp, traceme_crash_trap); 7122 ATF_TP_ADD_TC(tp, traceme_crash_segv); 7123 ATF_TP_ADD_TC(tp, traceme_crash_ill); 7124 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 7125 ATF_TP_ADD_TC(tp, traceme_crash_bus); 7126 7127 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 7128 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 7129 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 7130 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 7131 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 7132 7133 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 7134 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 7135 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 7136 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 7137 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 7138 7139 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 7140 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 7141 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 7142 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 7143 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 7144 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 7145 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 7146 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 7147 7148 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 7149 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 7150 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 7151 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 7152 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 7153 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 7154 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 7155 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 7156 7157 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 7158 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 7159 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 7160 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 7161 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 7162 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 7163 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 7164 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 7165 7166 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 7167 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 7168 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 7169 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 7170 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 7171 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 7172 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 7173 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 7174 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 7175 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 7176 7177 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 7178 7179 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 7180 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 7181 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 7182 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 7183 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 7184 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 7185 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 7186 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 7187 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 7188 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 7189 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 7190 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 7191 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 7192 7193 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 7194 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 7195 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 7196 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 7197 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 7198 7199 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 7200 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 7201 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 7202 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 7203 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 7204 7205 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 7206 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 7207 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 7208 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 7209 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 7210 7211 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 7212 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 7213 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 7214 7215 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 7216 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 7217 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 7218 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 7219 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 7220 7221 ATF_TP_ADD_TC_HAVE_PID(tp, 7222 unrelated_tracer_sees_signalmasked_crash_trap); 7223 ATF_TP_ADD_TC_HAVE_PID(tp, 7224 unrelated_tracer_sees_signalmasked_crash_segv); 7225 ATF_TP_ADD_TC_HAVE_PID(tp, 7226 unrelated_tracer_sees_signalmasked_crash_ill); 7227 ATF_TP_ADD_TC_HAVE_PID(tp, 7228 unrelated_tracer_sees_signalmasked_crash_fpe); 7229 ATF_TP_ADD_TC_HAVE_PID(tp, 7230 unrelated_tracer_sees_signalmasked_crash_bus); 7231 7232 ATF_TP_ADD_TC_HAVE_PID(tp, 7233 unrelated_tracer_sees_signalignored_crash_trap); 7234 ATF_TP_ADD_TC_HAVE_PID(tp, 7235 unrelated_tracer_sees_signalignored_crash_segv); 7236 ATF_TP_ADD_TC_HAVE_PID(tp, 7237 unrelated_tracer_sees_signalignored_crash_ill); 7238 ATF_TP_ADD_TC_HAVE_PID(tp, 7239 unrelated_tracer_sees_signalignored_crash_fpe); 7240 ATF_TP_ADD_TC_HAVE_PID(tp, 7241 unrelated_tracer_sees_signalignored_crash_bus); 7242 7243 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 7244 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 7245 ATF_TP_ADD_TC_HAVE_PID(tp, 7246 unrelated_tracer_sees_terminaton_before_the_parent); 7247 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 7248 7249 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 7250 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 7251 7252 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 7253 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 7254 7255 ATF_TP_ADD_TC_HAVE_PID(tp, 7256 tracee_sees_its_original_parent_getppid); 7257 ATF_TP_ADD_TC_HAVE_PID(tp, 7258 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 7259 ATF_TP_ADD_TC_HAVE_PID(tp, 7260 tracee_sees_its_original_parent_procfs_status); 7261 7262 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 7263 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 7264 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 7265 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 7266 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 7267 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 7268 7269 ATF_TP_ADD_TC(tp, fork1); 7270 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 7271 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 7272 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 7273 ATF_TP_ADD_TC(tp, fork5); 7274 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 7275 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 7276 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 7277 7278 ATF_TP_ADD_TC(tp, vfork1); 7279 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 7280 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 7281 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 7282 ATF_TP_ADD_TC(tp, vfork5); 7283 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 7284// thes tests hang on SMP machines, disable them for now // still true? 7285 ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 7286 ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 7287 7288 ATF_TP_ADD_TC(tp, traceme_vfork_fork); 7289 ATF_TP_ADD_TC(tp, traceme_vfork_vfork); 7290 7291 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 7292 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 7293 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 7294 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 7295 7296 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 7297 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 7298 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 7299 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 7300 7301 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 7302 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 7303 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 7304 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 7305 7306 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 7307 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 7308 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 7309 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 7310 7311 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 7312 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 7313 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 7314 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 7315 7316 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 7317 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 7318 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 7319 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 7320 7321 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 7322 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 7323 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 7324 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 7325 7326 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 7327 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 7328 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 7329 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 7330 7331 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 7332 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 7333 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 7334 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 7335 7336 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 7337 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 7338 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 7339 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 7340 7341 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 7342 7343 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); 7344 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); 7345 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); 7346 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); 7347 7348 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); 7349 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); 7350 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); 7351 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); 7352 7353 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); 7354 7355 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 7356 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 7357 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 7358 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 7359 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 7360 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 7361 7362 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 7363 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 7364 7365 ATF_TP_ADD_TC_PT_STEP(tp, step1); 7366 ATF_TP_ADD_TC_PT_STEP(tp, step2); 7367 ATF_TP_ADD_TC_PT_STEP(tp, step3); 7368 ATF_TP_ADD_TC_PT_STEP(tp, step4); 7369 7370 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 7371 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 7372 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 7373 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 7374 7375 ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked); 7376 ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored); 7377 7378 ATF_TP_ADD_TC(tp, kill1); 7379 ATF_TP_ADD_TC(tp, kill2); 7380 ATF_TP_ADD_TC(tp, kill3); 7381 7382 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 7383 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 7384 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 7385 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 7386 7387 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 7388 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 7389 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 7390 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 7391 7392 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 7393 ATF_TP_ADD_TC(tp, siginfo_set_faked); 7394 7395 ATF_TP_ADD_TC(tp, traceme_exec); 7396 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 7397 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 7398 7399 ATF_TP_ADD_TC(tp, trace_thread1); 7400 ATF_TP_ADD_TC(tp, trace_thread2); 7401 ATF_TP_ADD_TC(tp, trace_thread3); 7402 ATF_TP_ADD_TC(tp, trace_thread4); 7403 7404 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 7405 7406 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked); 7407 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored); 7408 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked); 7409 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored); 7410 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked); 7411 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored); 7412 7413 ATF_TP_ADD_TC(tp, signal9); 7414 ATF_TP_ADD_TC(tp, signal10); 7415 7416 ATF_TP_ADD_TC(tp, suspend1); 7417 ATF_TP_ADD_TC(tp, suspend2); 7418 7419 ATF_TP_ADD_TC(tp, resume1); 7420 7421 ATF_TP_ADD_TC(tp, syscall1); 7422 7423 ATF_TP_ADD_TC(tp, syscallemu1); 7424 7425 ATF_TP_ADD_TC(tp, clone1); 7426 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); 7427 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); 7428 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); 7429 ATF_TP_ADD_TC(tp, clone5); 7430 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); 7431 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); 7432 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); 7433 7434 ATF_TP_ADD_TC(tp, clone_vm1); 7435 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); 7436 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); 7437 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); 7438 ATF_TP_ADD_TC(tp, clone_vm5); 7439 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); 7440 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); 7441 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); 7442 7443 ATF_TP_ADD_TC(tp, clone_fs1); 7444 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); 7445 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); 7446 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); 7447 ATF_TP_ADD_TC(tp, clone_fs5); 7448 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); 7449 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); 7450 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); 7451 7452 ATF_TP_ADD_TC(tp, clone_files1); 7453 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); 7454 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); 7455 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); 7456 ATF_TP_ADD_TC(tp, clone_files5); 7457 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); 7458 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); 7459 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); 7460 7461// ATF_TP_ADD_TC(tp, clone_sighand1); // XXX 7462// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX 7463// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX 7464// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX 7465// ATF_TP_ADD_TC(tp, clone_sighand5); // XXX 7466// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX 7467// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX 7468// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX 7469 7470 ATF_TP_ADD_TC(tp, clone_vfork1); 7471 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); 7472 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); 7473 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); 7474 ATF_TP_ADD_TC(tp, clone_vfork5); 7475 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); 7476 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); 7477 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); 7478 7479 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); 7480 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); 7481 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); 7482 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); 7483 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); 7484 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); 7485 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); 7486 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); 7487// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX 7488// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX 7489 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); 7490 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); 7491 7492 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); 7493 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); 7494 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); 7495 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); 7496// ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX 7497 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork); 7498 7499 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 7500 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 7501 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 7502 7503 return atf_no_error(); 7504} 7505