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