t_ptrace_wait.c revision 1.81
1/* $NetBSD: t_ptrace_wait.c,v 1.81 2019/02/11 05:51:20 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.81 2019/02/11 05:51:20 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(siginfo4); 3435ATF_TC_HEAD(siginfo4, tc) 3436{ 3437 atf_tc_set_md_var(tc, "descr", 3438 "Detect SIGTRAP TRAP_EXEC from tracee"); 3439} 3440 3441ATF_TC_BODY(siginfo4, 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 3493volatile lwpid_t the_lwp_id = 0; 3494 3495static void 3496lwp_main_func(void *arg) 3497{ 3498 the_lwp_id = _lwp_self(); 3499 _lwp_exit(); 3500} 3501 3502ATF_TC(lwp_create1); 3503ATF_TC_HEAD(lwp_create1, tc) 3504{ 3505 atf_tc_set_md_var(tc, "descr", 3506 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 3507 "EVENT_MASK set to PTRACE_LWP_CREATE"); 3508} 3509 3510ATF_TC_BODY(lwp_create1, tc) 3511{ 3512 const int exitval = 5; 3513 const int sigval = SIGSTOP; 3514 pid_t child, wpid; 3515#if defined(TWAIT_HAVE_STATUS) 3516 int status; 3517#endif 3518 ptrace_state_t state; 3519 const int slen = sizeof(state); 3520 ptrace_event_t event; 3521 const int elen = sizeof(event); 3522 ucontext_t uc; 3523 lwpid_t lid; 3524 static const size_t ssize = 16*1024; 3525 void *stack; 3526 3527 DPRINTF("Before forking process PID=%d\n", getpid()); 3528 SYSCALL_REQUIRE((child = fork()) != -1); 3529 if (child == 0) { 3530 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3531 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3532 3533 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3534 FORKEE_ASSERT(raise(sigval) == 0); 3535 3536 DPRINTF("Before allocating memory for stack in child\n"); 3537 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 3538 3539 DPRINTF("Before making context for new lwp in child\n"); 3540 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 3541 3542 DPRINTF("Before creating new in child\n"); 3543 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 3544 3545 DPRINTF("Before waiting for lwp %d to exit\n", lid); 3546 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 3547 3548 DPRINTF("Before verifying that reported %d and running lid %d " 3549 "are the same\n", lid, the_lwp_id); 3550 FORKEE_ASSERT_EQ(lid, the_lwp_id); 3551 3552 DPRINTF("Before exiting of the child process\n"); 3553 _exit(exitval); 3554 } 3555 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3556 3557 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3558 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3559 3560 validate_status_stopped(status, sigval); 3561 3562 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 3563 event.pe_set_event = PTRACE_LWP_CREATE; 3564 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3565 3566 DPRINTF("Before resuming the child process where it left off and " 3567 "without signal to be sent\n"); 3568 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3569 3570 DPRINTF("Before calling %s() for the child - expected stopped " 3571 "SIGTRAP\n", TWAIT_FNAME); 3572 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3573 3574 validate_status_stopped(status, SIGTRAP); 3575 3576 SYSCALL_REQUIRE( 3577 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3578 3579 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 3580 3581 lid = state.pe_lwp; 3582 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 3583 3584 DPRINTF("Before resuming the child process where it left off and " 3585 "without signal to be sent\n"); 3586 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3587 3588 DPRINTF("Before calling %s() for the child - expected exited\n", 3589 TWAIT_FNAME); 3590 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3591 3592 validate_status_exited(status, exitval); 3593 3594 DPRINTF("Before calling %s() for the child - expected no process\n", 3595 TWAIT_FNAME); 3596 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3597} 3598 3599ATF_TC(lwp_exit1); 3600ATF_TC_HEAD(lwp_exit1, tc) 3601{ 3602 atf_tc_set_md_var(tc, "descr", 3603 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 3604 "EVENT_MASK set to PTRACE_LWP_EXIT"); 3605} 3606 3607ATF_TC_BODY(lwp_exit1, tc) 3608{ 3609 const int exitval = 5; 3610 const int sigval = SIGSTOP; 3611 pid_t child, wpid; 3612#if defined(TWAIT_HAVE_STATUS) 3613 int status; 3614#endif 3615 ptrace_state_t state; 3616 const int slen = sizeof(state); 3617 ptrace_event_t event; 3618 const int elen = sizeof(event); 3619 ucontext_t uc; 3620 lwpid_t lid; 3621 static const size_t ssize = 16*1024; 3622 void *stack; 3623 3624 DPRINTF("Before forking process PID=%d\n", getpid()); 3625 SYSCALL_REQUIRE((child = fork()) != -1); 3626 if (child == 0) { 3627 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3628 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3629 3630 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3631 FORKEE_ASSERT(raise(sigval) == 0); 3632 3633 DPRINTF("Before allocating memory for stack in child\n"); 3634 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 3635 3636 DPRINTF("Before making context for new lwp in child\n"); 3637 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 3638 3639 DPRINTF("Before creating new in child\n"); 3640 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 3641 3642 DPRINTF("Before waiting for lwp %d to exit\n", lid); 3643 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 3644 3645 DPRINTF("Before verifying that reported %d and running lid %d " 3646 "are the same\n", lid, the_lwp_id); 3647 FORKEE_ASSERT_EQ(lid, the_lwp_id); 3648 3649 DPRINTF("Before exiting of the child process\n"); 3650 _exit(exitval); 3651 } 3652 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3653 3654 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3655 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3656 3657 validate_status_stopped(status, sigval); 3658 3659 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 3660 event.pe_set_event = PTRACE_LWP_EXIT; 3661 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3662 3663 DPRINTF("Before resuming the child process where it left off and " 3664 "without signal to be sent\n"); 3665 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3666 3667 DPRINTF("Before calling %s() for the child - expected stopped " 3668 "SIGTRAP\n", TWAIT_FNAME); 3669 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3670 3671 validate_status_stopped(status, SIGTRAP); 3672 3673 SYSCALL_REQUIRE( 3674 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3675 3676 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 3677 3678 lid = state.pe_lwp; 3679 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 3680 3681 DPRINTF("Before resuming the child process where it left off and " 3682 "without signal to be sent\n"); 3683 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3684 3685 DPRINTF("Before calling %s() for the child - expected exited\n", 3686 TWAIT_FNAME); 3687 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3688 3689 validate_status_exited(status, exitval); 3690 3691 DPRINTF("Before calling %s() for the child - expected no process\n", 3692 TWAIT_FNAME); 3693 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3694} 3695 3696ATF_TC(signal1); 3697ATF_TC_HEAD(signal1, tc) 3698{ 3699 atf_tc_set_md_var(tc, "descr", 3700 "Verify that masking single unrelated signal does not stop tracer " 3701 "from catching other signals"); 3702} 3703 3704ATF_TC_BODY(signal1, tc) 3705{ 3706 const int exitval = 5; 3707 const int sigval = SIGSTOP; 3708 const int sigmasked = SIGTRAP; 3709 const int signotmasked = SIGINT; 3710 pid_t child, wpid; 3711#if defined(TWAIT_HAVE_STATUS) 3712 int status; 3713#endif 3714 sigset_t intmask; 3715 3716 DPRINTF("Before forking process PID=%d\n", getpid()); 3717 SYSCALL_REQUIRE((child = fork()) != -1); 3718 if (child == 0) { 3719 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3720 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3721 3722 sigemptyset(&intmask); 3723 sigaddset(&intmask, sigmasked); 3724 sigprocmask(SIG_BLOCK, &intmask, NULL); 3725 3726 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3727 FORKEE_ASSERT(raise(sigval) == 0); 3728 3729 DPRINTF("Before raising %s from child\n", 3730 strsignal(signotmasked)); 3731 FORKEE_ASSERT(raise(signotmasked) == 0); 3732 3733 DPRINTF("Before exiting of the child process\n"); 3734 _exit(exitval); 3735 } 3736 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3737 3738 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3739 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3740 3741 validate_status_stopped(status, sigval); 3742 3743 DPRINTF("Before resuming the child process where it left off and " 3744 "without signal to be sent\n"); 3745 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3746 3747 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3748 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3749 3750 validate_status_stopped(status, signotmasked); 3751 3752 DPRINTF("Before resuming the child process where it left off and " 3753 "without signal to be sent\n"); 3754 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3755 3756 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3757 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3758 3759 validate_status_exited(status, exitval); 3760 3761 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3762 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3763} 3764 3765ATF_TC(signal2); 3766ATF_TC_HEAD(signal2, tc) 3767{ 3768 atf_tc_set_md_var(tc, "descr", 3769 "Verify that masking SIGTRAP in tracee stops tracer from " 3770 "catching this raised signal"); 3771} 3772 3773ATF_TC_BODY(signal2, tc) 3774{ 3775 const int exitval = 5; 3776 const int sigval = SIGSTOP; 3777 const int sigmasked = SIGTRAP; 3778 pid_t child, wpid; 3779#if defined(TWAIT_HAVE_STATUS) 3780 int status; 3781#endif 3782 sigset_t intmask; 3783 3784 DPRINTF("Before forking process PID=%d\n", getpid()); 3785 SYSCALL_REQUIRE((child = fork()) != -1); 3786 if (child == 0) { 3787 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3788 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3789 3790 sigemptyset(&intmask); 3791 sigaddset(&intmask, sigmasked); 3792 sigprocmask(SIG_BLOCK, &intmask, NULL); 3793 3794 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3795 FORKEE_ASSERT(raise(sigval) == 0); 3796 3797 DPRINTF("Before raising %s breakpoint from child\n", 3798 strsignal(sigmasked)); 3799 FORKEE_ASSERT(raise(sigmasked) == 0); 3800 3801 DPRINTF("Before exiting of the child process\n"); 3802 _exit(exitval); 3803 } 3804 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3805 3806 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3807 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3808 3809 validate_status_stopped(status, sigval); 3810 3811 DPRINTF("Before resuming the child process where it left off and " 3812 "without signal to be sent\n"); 3813 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3814 3815 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3816 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3817 3818 validate_status_exited(status, exitval); 3819 3820 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3821 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3822} 3823 3824ATF_TC(signal3); 3825ATF_TC_HEAD(signal3, tc) 3826{ 3827 atf_tc_set_md_var(tc, "timeout", "5"); 3828 atf_tc_set_md_var(tc, "descr", 3829 "Verify that masking SIGTRAP in tracee does not stop tracer from " 3830 "catching software breakpoints"); 3831} 3832 3833ATF_TC_BODY(signal3, tc) 3834{ 3835 const int exitval = 5; 3836 const int sigval = SIGSTOP; 3837 const int sigmasked = SIGTRAP; 3838 pid_t child, wpid; 3839#if defined(TWAIT_HAVE_STATUS) 3840 int status; 3841#endif 3842 sigset_t intmask; 3843 3844 DPRINTF("Before forking process PID=%d\n", getpid()); 3845 SYSCALL_REQUIRE((child = fork()) != -1); 3846 if (child == 0) { 3847 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3848 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3849 3850 sigemptyset(&intmask); 3851 sigaddset(&intmask, sigmasked); 3852 sigprocmask(SIG_BLOCK, &intmask, NULL); 3853 3854 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3855 FORKEE_ASSERT(raise(sigval) == 0); 3856 3857 DPRINTF("Before raising software breakpoint from child\n"); 3858 trigger_trap(); 3859 3860 DPRINTF("Before exiting of the child process\n"); 3861 _exit(exitval); 3862 } 3863 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3864 3865 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3866 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3867 3868 validate_status_stopped(status, sigval); 3869 3870 DPRINTF("Before resuming the child process where it left off and " 3871 "without signal to be sent\n"); 3872 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3873 3874 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3875 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3876 3877 validate_status_stopped(status, sigmasked); 3878 3879 DPRINTF("Before resuming the child process where it left off and " 3880 "without signal to be sent\n"); 3881 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 3882 3883 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3884 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3885 3886 validate_status_signaled(status, SIGKILL, 0); 3887 3888 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3889 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3890} 3891 3892#if defined(PT_STEP) 3893ATF_TC(signal4); 3894ATF_TC_HEAD(signal4, tc) 3895{ 3896 atf_tc_set_md_var(tc, "descr", 3897 "Verify that masking SIGTRAP in tracee does not stop tracer from " 3898 "catching single step trap"); 3899} 3900 3901ATF_TC_BODY(signal4, tc) 3902{ 3903 const int exitval = 5; 3904 const int sigval = SIGSTOP; 3905 const int sigmasked = SIGTRAP; 3906 pid_t child, wpid; 3907#if defined(TWAIT_HAVE_STATUS) 3908 int status; 3909#endif 3910 sigset_t intmask; 3911 int happy; 3912 3913#if defined(__arm__) 3914 /* PT_STEP not supported on arm 32-bit */ 3915 atf_tc_expect_fail("PR kern/51918 PR kern/52119"); 3916#endif 3917 3918 DPRINTF("Before forking process PID=%d\n", getpid()); 3919 SYSCALL_REQUIRE((child = fork()) != -1); 3920 if (child == 0) { 3921 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3922 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3923 3924 happy = check_happy(100); 3925 3926 sigemptyset(&intmask); 3927 sigaddset(&intmask, sigmasked); 3928 sigprocmask(SIG_BLOCK, &intmask, NULL); 3929 3930 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3931 FORKEE_ASSERT(raise(sigval) == 0); 3932 3933 FORKEE_ASSERT_EQ(happy, check_happy(100)); 3934 3935 DPRINTF("Before exiting of the child process\n"); 3936 _exit(exitval); 3937 } 3938 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3939 3940 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3941 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3942 3943 validate_status_stopped(status, sigval); 3944 3945 DPRINTF("Before resuming the child process where it left off and " 3946 "without signal to be sent\n"); 3947 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 3948 3949 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3950 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3951 3952 validate_status_stopped(status, sigmasked); 3953 3954 DPRINTF("Before resuming the child process where it left off and " 3955 "without signal to be sent\n"); 3956 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3957 3958 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3959 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3960 3961 validate_status_exited(status, exitval); 3962 3963 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3964 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3965} 3966#endif 3967 3968ATF_TC(signal5); 3969ATF_TC_HEAD(signal5, tc) 3970{ 3971 atf_tc_set_md_var(tc, "descr", 3972 "Verify that masking SIGTRAP in tracee does not stop tracer from " 3973 "catching exec() breakpoint"); 3974} 3975 3976ATF_TC_BODY(signal5, tc) 3977{ 3978 const int sigval = SIGSTOP; 3979 const int sigmasked = SIGTRAP; 3980 pid_t child, wpid; 3981#if defined(TWAIT_HAVE_STATUS) 3982 int status; 3983#endif 3984 struct ptrace_siginfo info; 3985 sigset_t intmask; 3986 3987 memset(&info, 0, sizeof(info)); 3988 3989 DPRINTF("Before forking process PID=%d\n", getpid()); 3990 SYSCALL_REQUIRE((child = fork()) != -1); 3991 if (child == 0) { 3992 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3993 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3994 3995 sigemptyset(&intmask); 3996 sigaddset(&intmask, sigmasked); 3997 sigprocmask(SIG_BLOCK, &intmask, NULL); 3998 3999 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4000 FORKEE_ASSERT(raise(sigval) == 0); 4001 4002 DPRINTF("Before calling execve(2) from child\n"); 4003 execlp("/bin/echo", "/bin/echo", NULL); 4004 4005 /* NOTREACHED */ 4006 FORKEE_ASSERTX(0 && "Not reached"); 4007 } 4008 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4009 4010 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4011 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4012 4013 validate_status_stopped(status, sigval); 4014 4015 DPRINTF("Before resuming the child process where it left off and " 4016 "without signal to be sent\n"); 4017 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4018 4019 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4020 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4021 4022 validate_status_stopped(status, sigmasked); 4023 4024 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4025 SYSCALL_REQUIRE( 4026 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4027 4028 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4029 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4030 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4031 info.psi_siginfo.si_errno); 4032 4033 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked); 4034 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4035 4036 DPRINTF("Before resuming the child process where it left off and " 4037 "without signal to be sent\n"); 4038 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4039 4040 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4041 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4042 4043 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4044 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4045} 4046 4047#if defined(TWAIT_HAVE_PID) 4048ATF_TC(signal6); 4049ATF_TC_HEAD(signal6, tc) 4050{ 4051 atf_tc_set_md_var(tc, "timeout", "5"); 4052 atf_tc_set_md_var(tc, "descr", 4053 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4054 "catching PTRACE_FORK breakpoint"); 4055} 4056 4057ATF_TC_BODY(signal6, tc) 4058{ 4059 const int exitval = 5; 4060 const int exitval2 = 15; 4061 const int sigval = SIGSTOP; 4062 const int sigmasked = SIGTRAP; 4063 pid_t child, child2, wpid; 4064#if defined(TWAIT_HAVE_STATUS) 4065 int status; 4066#endif 4067 sigset_t intmask; 4068 ptrace_state_t state; 4069 const int slen = sizeof(state); 4070 ptrace_event_t event; 4071 const int elen = sizeof(event); 4072 4073 atf_tc_expect_fail("PR kern/51918"); 4074 4075 DPRINTF("Before forking process PID=%d\n", getpid()); 4076 SYSCALL_REQUIRE((child = fork()) != -1); 4077 if (child == 0) { 4078 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4079 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4080 4081 sigemptyset(&intmask); 4082 sigaddset(&intmask, sigmasked); 4083 sigprocmask(SIG_BLOCK, &intmask, NULL); 4084 4085 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4086 FORKEE_ASSERT(raise(sigval) == 0); 4087 4088 FORKEE_ASSERT((child2 = fork()) != -1); 4089 4090 if (child2 == 0) 4091 _exit(exitval2); 4092 4093 FORKEE_REQUIRE_SUCCESS 4094 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4095 4096 forkee_status_exited(status, exitval2); 4097 4098 DPRINTF("Before exiting of the child process\n"); 4099 _exit(exitval); 4100 } 4101 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4102 4103 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4104 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4105 4106 validate_status_stopped(status, sigval); 4107 4108 DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 4109 event.pe_set_event = PTRACE_FORK; 4110 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4111 4112 DPRINTF("Before resuming the child process where it left off and " 4113 "without signal to be sent\n"); 4114 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4115 4116 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4117 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4118 4119 validate_status_stopped(status, sigmasked); 4120 4121 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4122 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4123 4124 child2 = state.pe_other_pid; 4125 DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2); 4126 4127 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 4128 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4129 child2); 4130 4131 validate_status_stopped(status, SIGTRAP); 4132 4133 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 4134 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4135 ATF_REQUIRE_EQ(state.pe_other_pid, child); 4136 4137 DPRINTF("Before resuming the forkee process where it left off and " 4138 "without signal to be sent\n"); 4139 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 4140 4141 DPRINTF("Before resuming the child process where it left off and " 4142 "without signal to be sent\n"); 4143 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4144 4145 DPRINTF("Before calling %s() for the forkee - expected exited\n", 4146 TWAIT_FNAME); 4147 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4148 child2); 4149 4150 validate_status_exited(status, exitval2); 4151 4152 DPRINTF("Before calling %s() for the forkee - expected no process\n", 4153 TWAIT_FNAME); 4154 TWAIT_REQUIRE_FAILURE(ECHILD, 4155 wpid = TWAIT_GENERIC(child2, &status, 0)); 4156 4157 DPRINTF("Before calling %s() for the child - expected stopped " 4158 "SIGCHLD\n", TWAIT_FNAME); 4159 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4160 4161 validate_status_stopped(status, SIGCHLD); 4162 4163 DPRINTF("Before resuming the child process where it left off and " 4164 "without signal to be sent\n"); 4165 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4166 4167 DPRINTF("Before calling %s() for the child - expected exited\n", 4168 TWAIT_FNAME); 4169 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4170 4171 validate_status_exited(status, exitval); 4172 4173 DPRINTF("Before calling %s() for the child - expected no process\n", 4174 TWAIT_FNAME); 4175 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4176} 4177#endif 4178 4179#if defined(TWAIT_HAVE_PID) 4180ATF_TC(signal7); 4181ATF_TC_HEAD(signal7, tc) 4182{ 4183 atf_tc_set_md_var(tc, "descr", 4184 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4185 "catching PTRACE_VFORK breakpoint"); 4186} 4187 4188ATF_TC_BODY(signal7, tc) 4189{ 4190 const int exitval = 5; 4191 const int exitval2 = 15; 4192 const int sigval = SIGSTOP; 4193 const int sigmasked = SIGTRAP; 4194 pid_t child, child2, wpid; 4195#if defined(TWAIT_HAVE_STATUS) 4196 int status; 4197#endif 4198 sigset_t intmask; 4199 ptrace_state_t state; 4200 const int slen = sizeof(state); 4201 ptrace_event_t event; 4202 const int elen = sizeof(event); 4203 4204 atf_tc_expect_fail("PR kern/51918"); 4205 4206 DPRINTF("Before forking process PID=%d\n", getpid()); 4207 SYSCALL_REQUIRE((child = fork()) != -1); 4208 if (child == 0) { 4209 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4210 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4211 4212 sigemptyset(&intmask); 4213 sigaddset(&intmask, sigmasked); 4214 sigprocmask(SIG_BLOCK, &intmask, NULL); 4215 4216 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4217 FORKEE_ASSERT(raise(sigval) == 0); 4218 4219 FORKEE_ASSERT((child2 = fork()) != -1); 4220 4221 if (child2 == 0) 4222 _exit(exitval2); 4223 4224 FORKEE_REQUIRE_SUCCESS 4225 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4226 4227 forkee_status_exited(status, exitval2); 4228 4229 DPRINTF("Before exiting of the child process\n"); 4230 _exit(exitval); 4231 } 4232 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4233 4234 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4235 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4236 4237 validate_status_stopped(status, sigval); 4238 4239 DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 4240 event.pe_set_event = PTRACE_VFORK; 4241 SYSCALL_REQUIRE( 4242 ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || 4243 errno == ENOTSUP); 4244 4245 DPRINTF("Before resuming the child process where it left off and " 4246 "without signal to be sent\n"); 4247 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4248 4249 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4250 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4251 4252 validate_status_stopped(status, sigmasked); 4253 4254 SYSCALL_REQUIRE( 4255 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4256 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 4257 4258 child2 = state.pe_other_pid; 4259 DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2); 4260 4261 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 4262 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4263 child2); 4264 4265 validate_status_stopped(status, SIGTRAP); 4266 4267 SYSCALL_REQUIRE( 4268 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 4269 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 4270 ATF_REQUIRE_EQ(state.pe_other_pid, child); 4271 4272 DPRINTF("Before resuming the forkee process where it left off and " 4273 "without signal to be sent\n"); 4274 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 4275 4276 DPRINTF("Before resuming the child process where it left off and " 4277 "without signal to be sent\n"); 4278 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4279 4280 DPRINTF("Before calling %s() for the forkee - expected exited\n", 4281 TWAIT_FNAME); 4282 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4283 child2); 4284 4285 validate_status_exited(status, exitval2); 4286 4287 DPRINTF("Before calling %s() for the forkee - expected no process\n", 4288 TWAIT_FNAME); 4289 TWAIT_REQUIRE_FAILURE(ECHILD, 4290 wpid = TWAIT_GENERIC(child2, &status, 0)); 4291 4292 DPRINTF("Before calling %s() for the child - expected stopped " 4293 "SIGCHLD\n", TWAIT_FNAME); 4294 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4295 4296 validate_status_stopped(status, SIGCHLD); 4297 4298 DPRINTF("Before resuming the child process where it left off and " 4299 "without signal to be sent\n"); 4300 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4301 4302 DPRINTF("Before calling %s() for the child - expected exited\n", 4303 TWAIT_FNAME); 4304 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4305 4306 validate_status_exited(status, exitval); 4307 4308 DPRINTF("Before calling %s() for the child - expected no process\n", 4309 TWAIT_FNAME); 4310 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4311} 4312#endif 4313 4314ATF_TC(signal8); 4315ATF_TC_HEAD(signal8, tc) 4316{ 4317 atf_tc_set_md_var(tc, "descr", 4318 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4319 "catching PTRACE_VFORK_DONE breakpoint"); 4320} 4321 4322ATF_TC_BODY(signal8, tc) 4323{ 4324 const int exitval = 5; 4325 const int exitval2 = 15; 4326 const int sigval = SIGSTOP; 4327 const int sigmasked = SIGTRAP; 4328 pid_t child, child2, wpid; 4329#if defined(TWAIT_HAVE_STATUS) 4330 int status; 4331#endif 4332 sigset_t intmask; 4333 ptrace_state_t state; 4334 const int slen = sizeof(state); 4335 ptrace_event_t event; 4336 const int elen = sizeof(event); 4337 4338 atf_tc_expect_fail("PR kern/51918"); 4339 4340 DPRINTF("Before forking process PID=%d\n", getpid()); 4341 SYSCALL_REQUIRE((child = fork()) != -1); 4342 if (child == 0) { 4343 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4344 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4345 4346 sigemptyset(&intmask); 4347 sigaddset(&intmask, sigmasked); 4348 sigprocmask(SIG_BLOCK, &intmask, NULL); 4349 4350 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4351 FORKEE_ASSERT(raise(sigval) == 0); 4352 4353 FORKEE_ASSERT((child2 = vfork()) != -1); 4354 4355 if (child2 == 0) 4356 _exit(exitval2); 4357 4358 FORKEE_REQUIRE_SUCCESS 4359 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4360 4361 forkee_status_exited(status, exitval2); 4362 4363 DPRINTF("Before exiting of the child process\n"); 4364 _exit(exitval); 4365 } 4366 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4367 4368 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4369 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4370 4371 validate_status_stopped(status, sigval); 4372 4373 DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", 4374 child); 4375 event.pe_set_event = PTRACE_VFORK_DONE; 4376 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4377 4378 DPRINTF("Before resuming the child process where it left off and " 4379 "without signal to be sent\n"); 4380 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4381 4382 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4383 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4384 4385 validate_status_stopped(status, sigmasked); 4386 4387 SYSCALL_REQUIRE( 4388 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4389 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 4390 4391 child2 = state.pe_other_pid; 4392 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); 4393 4394 DPRINTF("Before resuming the child process where it left off and " 4395 "without signal to be sent\n"); 4396 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4397 4398 DPRINTF("Before calling %s() for the child - expected stopped " 4399 "SIGCHLD\n", TWAIT_FNAME); 4400 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4401 4402 validate_status_stopped(status, SIGCHLD); 4403 4404 DPRINTF("Before resuming the child process where it left off and " 4405 "without signal to be sent\n"); 4406 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4407 4408 DPRINTF("Before calling %s() for the child - expected exited\n", 4409 TWAIT_FNAME); 4410 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4411 4412 validate_status_exited(status, exitval); 4413 4414 DPRINTF("Before calling %s() for the child - expected no process\n", 4415 TWAIT_FNAME); 4416 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4417} 4418 4419ATF_TC(signal9); 4420ATF_TC_HEAD(signal9, tc) 4421{ 4422 atf_tc_set_md_var(tc, "descr", 4423 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4424 "catching PTRACE_LWP_CREATE breakpoint"); 4425} 4426 4427ATF_TC_BODY(signal9, tc) 4428{ 4429 const int exitval = 5; 4430 const int sigval = SIGSTOP; 4431 const int sigmasked = SIGTRAP; 4432 pid_t child, wpid; 4433#if defined(TWAIT_HAVE_STATUS) 4434 int status; 4435#endif 4436 sigset_t intmask; 4437 ptrace_state_t state; 4438 const int slen = sizeof(state); 4439 ptrace_event_t event; 4440 const int elen = sizeof(event); 4441 ucontext_t uc; 4442 lwpid_t lid; 4443 static const size_t ssize = 16*1024; 4444 void *stack; 4445 4446 atf_tc_expect_fail("PR kern/51918"); 4447 4448 DPRINTF("Before forking process PID=%d\n", getpid()); 4449 SYSCALL_REQUIRE((child = fork()) != -1); 4450 if (child == 0) { 4451 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4452 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4453 4454 sigemptyset(&intmask); 4455 sigaddset(&intmask, sigmasked); 4456 sigprocmask(SIG_BLOCK, &intmask, NULL); 4457 4458 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4459 FORKEE_ASSERT(raise(sigval) == 0); 4460 4461 DPRINTF("Before allocating memory for stack in child\n"); 4462 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4463 4464 DPRINTF("Before making context for new lwp in child\n"); 4465 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 4466 4467 DPRINTF("Before creating new in child\n"); 4468 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4469 4470 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4471 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4472 4473 DPRINTF("Before verifying that reported %d and running lid %d " 4474 "are the same\n", lid, the_lwp_id); 4475 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4476 4477 DPRINTF("Before exiting of the child process\n"); 4478 _exit(exitval); 4479 } 4480 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4481 4482 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4483 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4484 4485 validate_status_stopped(status, sigval); 4486 4487 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 4488 event.pe_set_event = PTRACE_LWP_CREATE; 4489 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4490 4491 DPRINTF("Before resuming the child process where it left off and " 4492 "without signal to be sent\n"); 4493 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4494 4495 DPRINTF("Before calling %s() for the child - expected stopped " 4496 "SIGTRAP\n", TWAIT_FNAME); 4497 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4498 4499 validate_status_stopped(status, sigmasked); 4500 4501 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4502 4503 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 4504 4505 lid = state.pe_lwp; 4506 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 4507 4508 DPRINTF("Before resuming the child process where it left off and " 4509 "without signal to be sent\n"); 4510 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4511 4512 DPRINTF("Before calling %s() for the child - expected exited\n", 4513 TWAIT_FNAME); 4514 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4515 4516 validate_status_exited(status, exitval); 4517 4518 DPRINTF("Before calling %s() for the child - expected no process\n", 4519 TWAIT_FNAME); 4520 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4521} 4522 4523ATF_TC(signal10); 4524ATF_TC_HEAD(signal10, tc) 4525{ 4526 atf_tc_set_md_var(tc, "descr", 4527 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4528 "catching PTRACE_LWP_EXIT breakpoint"); 4529} 4530 4531ATF_TC_BODY(signal10, tc) 4532{ 4533 const int exitval = 5; 4534 const int sigval = SIGSTOP; 4535 const int sigmasked = SIGTRAP; 4536 pid_t child, wpid; 4537#if defined(TWAIT_HAVE_STATUS) 4538 int status; 4539#endif 4540 sigset_t intmask; 4541 ptrace_state_t state; 4542 const int slen = sizeof(state); 4543 ptrace_event_t event; 4544 const int elen = sizeof(event); 4545 ucontext_t uc; 4546 lwpid_t lid; 4547 static const size_t ssize = 16*1024; 4548 void *stack; 4549 4550 atf_tc_expect_fail("PR kern/51918"); 4551 4552 DPRINTF("Before forking process PID=%d\n", getpid()); 4553 SYSCALL_REQUIRE((child = fork()) != -1); 4554 if (child == 0) { 4555 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4556 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4557 4558 sigemptyset(&intmask); 4559 sigaddset(&intmask, sigmasked); 4560 sigprocmask(SIG_BLOCK, &intmask, NULL); 4561 4562 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4563 FORKEE_ASSERT(raise(sigval) == 0); 4564 4565 DPRINTF("Before allocating memory for stack in child\n"); 4566 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4567 4568 DPRINTF("Before making context for new lwp in child\n"); 4569 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 4570 4571 DPRINTF("Before creating new in child\n"); 4572 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4573 4574 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4575 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4576 4577 DPRINTF("Before verifying that reported %d and running lid %d " 4578 "are the same\n", lid, the_lwp_id); 4579 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4580 4581 DPRINTF("Before exiting of the child process\n"); 4582 _exit(exitval); 4583 } 4584 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4585 4586 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4587 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4588 4589 validate_status_stopped(status, sigval); 4590 4591 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 4592 event.pe_set_event = PTRACE_LWP_EXIT; 4593 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4594 4595 DPRINTF("Before resuming the child process where it left off and " 4596 "without signal to be sent\n"); 4597 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4598 4599 DPRINTF("Before calling %s() for the child - expected stopped " 4600 "SIGTRAP\n", TWAIT_FNAME); 4601 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4602 4603 validate_status_stopped(status, sigmasked); 4604 4605 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4606 4607 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 4608 4609 lid = state.pe_lwp; 4610 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 4611 4612 DPRINTF("Before resuming the child process where it left off and " 4613 "without signal to be sent\n"); 4614 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4615 4616 DPRINTF("Before calling %s() for the child - expected exited\n", 4617 TWAIT_FNAME); 4618 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4619 4620 validate_status_exited(status, exitval); 4621 4622 DPRINTF("Before calling %s() for the child - expected no process\n", 4623 TWAIT_FNAME); 4624 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4625} 4626 4627static void 4628lwp_main_stop(void *arg) 4629{ 4630 the_lwp_id = _lwp_self(); 4631 4632 raise(SIGTRAP); 4633 4634 _lwp_exit(); 4635} 4636 4637ATF_TC(suspend1); 4638ATF_TC_HEAD(suspend1, tc) 4639{ 4640 atf_tc_set_md_var(tc, "descr", 4641 "Verify that a thread can be suspended by a debugger and later " 4642 "resumed by a tracee"); 4643} 4644 4645ATF_TC_BODY(suspend1, tc) 4646{ 4647 const int exitval = 5; 4648 const int sigval = SIGSTOP; 4649 pid_t child, wpid; 4650#if defined(TWAIT_HAVE_STATUS) 4651 int status; 4652#endif 4653 ucontext_t uc; 4654 lwpid_t lid; 4655 static const size_t ssize = 16*1024; 4656 void *stack; 4657 struct ptrace_lwpinfo pl; 4658 struct ptrace_siginfo psi; 4659 volatile int go = 0; 4660 4661 // Feature pending for refactoring 4662 atf_tc_expect_fail("PR kern/51995"); 4663 4664 // Hangs with qemu 4665 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 4666 4667 DPRINTF("Before forking process PID=%d\n", getpid()); 4668 SYSCALL_REQUIRE((child = fork()) != -1); 4669 if (child == 0) { 4670 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4671 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4672 4673 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4674 FORKEE_ASSERT(raise(sigval) == 0); 4675 4676 DPRINTF("Before allocating memory for stack in child\n"); 4677 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4678 4679 DPRINTF("Before making context for new lwp in child\n"); 4680 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 4681 4682 DPRINTF("Before creating new in child\n"); 4683 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4684 4685 while (go == 0) 4686 continue; 4687 4688 raise(SIGINT); 4689 4690 FORKEE_ASSERT(_lwp_continue(lid) == 0); 4691 4692 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4693 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4694 4695 DPRINTF("Before verifying that reported %d and running lid %d " 4696 "are the same\n", lid, the_lwp_id); 4697 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4698 4699 DPRINTF("Before exiting of the child process\n"); 4700 _exit(exitval); 4701 } 4702 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4703 4704 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4705 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4706 4707 validate_status_stopped(status, sigval); 4708 4709 DPRINTF("Before resuming the child process where it left off and " 4710 "without signal to be sent\n"); 4711 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4712 4713 DPRINTF("Before calling %s() for the child - expected stopped " 4714 "SIGTRAP\n", TWAIT_FNAME); 4715 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4716 4717 validate_status_stopped(status, SIGTRAP); 4718 4719 DPRINTF("Before reading siginfo and lwpid_t\n"); 4720 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 4721 4722 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 4723 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 4724 4725 DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 4726 child, getpid()); 4727 SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 4728 4729 DPRINTF("Before resuming the child process where it left off and " 4730 "without signal to be sent\n"); 4731 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4732 4733 DPRINTF("Before calling %s() for the child - expected stopped " 4734 "SIGINT\n", TWAIT_FNAME); 4735 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4736 4737 validate_status_stopped(status, SIGINT); 4738 4739 pl.pl_lwpid = 0; 4740 4741 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4742 while (pl.pl_lwpid != 0) { 4743 4744 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4745 switch (pl.pl_lwpid) { 4746 case 1: 4747 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 4748 break; 4749 case 2: 4750 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 4751 break; 4752 } 4753 } 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 exited\n", 4760 TWAIT_FNAME); 4761 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4762 4763 validate_status_exited(status, exitval); 4764 4765 DPRINTF("Before calling %s() for the child - expected no process\n", 4766 TWAIT_FNAME); 4767 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4768} 4769 4770ATF_TC(suspend2); 4771ATF_TC_HEAD(suspend2, tc) 4772{ 4773 atf_tc_set_md_var(tc, "descr", 4774 "Verify that the while the only thread within a process is " 4775 "suspended, the whole process cannot be unstopped"); 4776} 4777 4778ATF_TC_BODY(suspend2, tc) 4779{ 4780 const int exitval = 5; 4781 const int sigval = SIGSTOP; 4782 pid_t child, wpid; 4783#if defined(TWAIT_HAVE_STATUS) 4784 int status; 4785#endif 4786 struct ptrace_siginfo psi; 4787 4788 // Feature pending for refactoring 4789 atf_tc_expect_fail("PR kern/51995"); 4790 4791 // Hangs with qemu 4792 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 4793 4794 DPRINTF("Before forking process PID=%d\n", getpid()); 4795 SYSCALL_REQUIRE((child = fork()) != -1); 4796 if (child == 0) { 4797 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4798 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4799 4800 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4801 FORKEE_ASSERT(raise(sigval) == 0); 4802 4803 DPRINTF("Before exiting of the child process\n"); 4804 _exit(exitval); 4805 } 4806 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4807 4808 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4809 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4810 4811 validate_status_stopped(status, sigval); 4812 4813 DPRINTF("Before reading siginfo and lwpid_t\n"); 4814 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 4815 4816 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 4817 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 4818 4819 DPRINTF("Before resuming the child process where it left off and " 4820 "without signal to be sent\n"); 4821 ATF_REQUIRE_ERRNO(EDEADLK, 4822 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 4823 4824 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 4825 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 4826 4827 DPRINTF("Before resuming the child process where it left off and " 4828 "without signal to be sent\n"); 4829 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4830 4831 DPRINTF("Before calling %s() for the child - expected exited\n", 4832 TWAIT_FNAME); 4833 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4834 4835 validate_status_exited(status, exitval); 4836 4837 DPRINTF("Before calling %s() for the child - expected no process\n", 4838 TWAIT_FNAME); 4839 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4840} 4841 4842ATF_TC(resume1); 4843ATF_TC_HEAD(resume1, tc) 4844{ 4845 atf_tc_set_md_var(tc, "timeout", "5"); 4846 atf_tc_set_md_var(tc, "descr", 4847 "Verify that a thread can be suspended by a debugger and later " 4848 "resumed by the debugger"); 4849} 4850 4851ATF_TC_BODY(resume1, tc) 4852{ 4853 struct msg_fds fds; 4854 const int exitval = 5; 4855 const int sigval = SIGSTOP; 4856 pid_t child, wpid; 4857 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 4858#if defined(TWAIT_HAVE_STATUS) 4859 int status; 4860#endif 4861 ucontext_t uc; 4862 lwpid_t lid; 4863 static const size_t ssize = 16*1024; 4864 void *stack; 4865 struct ptrace_lwpinfo pl; 4866 struct ptrace_siginfo psi; 4867 4868 // Feature pending for refactoring 4869 atf_tc_expect_fail("PR kern/51995"); 4870 4871 // Hangs with qemu 4872 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 4873 4874 SYSCALL_REQUIRE(msg_open(&fds) == 0); 4875 4876 DPRINTF("Before forking process PID=%d\n", getpid()); 4877 SYSCALL_REQUIRE((child = fork()) != -1); 4878 if (child == 0) { 4879 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4880 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4881 4882 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4883 FORKEE_ASSERT(raise(sigval) == 0); 4884 4885 DPRINTF("Before allocating memory for stack in child\n"); 4886 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4887 4888 DPRINTF("Before making context for new lwp in child\n"); 4889 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 4890 4891 DPRINTF("Before creating new in child\n"); 4892 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4893 4894 CHILD_TO_PARENT("Message", fds, msg); 4895 4896 raise(SIGINT); 4897 4898 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4899 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4900 4901 DPRINTF("Before verifying that reported %d and running lid %d " 4902 "are the same\n", lid, the_lwp_id); 4903 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4904 4905 DPRINTF("Before exiting of the child process\n"); 4906 _exit(exitval); 4907 } 4908 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4909 4910 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4911 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4912 4913 validate_status_stopped(status, sigval); 4914 4915 DPRINTF("Before resuming the child process where it left off and " 4916 "without signal to be sent\n"); 4917 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4918 4919 DPRINTF("Before calling %s() for the child - expected stopped " 4920 "SIGTRAP\n", TWAIT_FNAME); 4921 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4922 4923 validate_status_stopped(status, SIGTRAP); 4924 4925 DPRINTF("Before reading siginfo and lwpid_t\n"); 4926 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 4927 4928 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 4929 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 4930 4931 PARENT_FROM_CHILD("Message", fds, msg); 4932 4933 DPRINTF("Before resuming the child process where it left off and " 4934 "without signal to be sent\n"); 4935 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4936 4937 DPRINTF("Before calling %s() for the child - expected stopped " 4938 "SIGINT\n", TWAIT_FNAME); 4939 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4940 4941 validate_status_stopped(status, SIGINT); 4942 4943 pl.pl_lwpid = 0; 4944 4945 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4946 while (pl.pl_lwpid != 0) { 4947 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4948 switch (pl.pl_lwpid) { 4949 case 1: 4950 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 4951 break; 4952 case 2: 4953 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 4954 break; 4955 } 4956 } 4957 4958 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 4959 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 4960 4961 DPRINTF("Before resuming the child process where it left off and " 4962 "without signal to be sent\n"); 4963 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4964 4965 DPRINTF("Before calling %s() for the child - expected exited\n", 4966 TWAIT_FNAME); 4967 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4968 4969 validate_status_exited(status, exitval); 4970 4971 DPRINTF("Before calling %s() for the child - expected no process\n", 4972 TWAIT_FNAME); 4973 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4974 4975 msg_close(&fds); 4976 4977 DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 4978 sleep(10); 4979} 4980 4981ATF_TC(syscall1); 4982ATF_TC_HEAD(syscall1, tc) 4983{ 4984 atf_tc_set_md_var(tc, "descr", 4985 "Verify that getpid(2) can be traced with PT_SYSCALL"); 4986} 4987 4988ATF_TC_BODY(syscall1, tc) 4989{ 4990 const int exitval = 5; 4991 const int sigval = SIGSTOP; 4992 pid_t child, wpid; 4993#if defined(TWAIT_HAVE_STATUS) 4994 int status; 4995#endif 4996 struct ptrace_siginfo info; 4997 memset(&info, 0, sizeof(info)); 4998 4999 DPRINTF("Before forking process PID=%d\n", getpid()); 5000 SYSCALL_REQUIRE((child = fork()) != -1); 5001 if (child == 0) { 5002 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5003 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5004 5005 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5006 FORKEE_ASSERT(raise(sigval) == 0); 5007 5008 syscall(SYS_getpid); 5009 5010 DPRINTF("Before exiting of the child process\n"); 5011 _exit(exitval); 5012 } 5013 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5014 5015 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5016 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5017 5018 validate_status_stopped(status, sigval); 5019 5020 DPRINTF("Before resuming the child process where it left off and " 5021 "without signal to be sent\n"); 5022 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5023 5024 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5025 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5026 5027 validate_status_stopped(status, SIGTRAP); 5028 5029 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5030 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5031 5032 DPRINTF("Before checking siginfo_t and lwpid\n"); 5033 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5034 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5035 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 5036 5037 DPRINTF("Before resuming the child process where it left off and " 5038 "without signal to be sent\n"); 5039 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 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, SIGTRAP); 5045 5046 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5047 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5048 5049 DPRINTF("Before checking siginfo_t and lwpid\n"); 5050 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5051 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5052 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 5053 5054 DPRINTF("Before resuming the child process where it left off and " 5055 "without signal to be sent\n"); 5056 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5057 5058 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5059 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5060 5061 validate_status_exited(status, exitval); 5062 5063 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5064 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5065} 5066 5067ATF_TC(syscallemu1); 5068ATF_TC_HEAD(syscallemu1, tc) 5069{ 5070 atf_tc_set_md_var(tc, "descr", 5071 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 5072} 5073 5074ATF_TC_BODY(syscallemu1, tc) 5075{ 5076 const int exitval = 5; 5077 const int sigval = SIGSTOP; 5078 pid_t child, wpid; 5079#if defined(TWAIT_HAVE_STATUS) 5080 int status; 5081#endif 5082 5083#if defined(__sparc__) && !defined(__sparc64__) 5084 /* syscallemu does not work on sparc (32-bit) */ 5085 atf_tc_expect_fail("PR kern/52166"); 5086#endif 5087 5088 DPRINTF("Before forking process PID=%d\n", getpid()); 5089 SYSCALL_REQUIRE((child = fork()) != -1); 5090 if (child == 0) { 5091 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5092 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5093 5094 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5095 FORKEE_ASSERT(raise(sigval) == 0); 5096 5097 syscall(SYS_exit, 100); 5098 5099 DPRINTF("Before exiting of the child process\n"); 5100 _exit(exitval); 5101 } 5102 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5103 5104 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5105 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5106 5107 validate_status_stopped(status, sigval); 5108 5109 DPRINTF("Before resuming the child process where it left off and " 5110 "without signal to be sent\n"); 5111 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5112 5113 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5114 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5115 5116 validate_status_stopped(status, SIGTRAP); 5117 5118 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 5119 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 5120 5121 DPRINTF("Before resuming the child process where it left off and " 5122 "without signal to be sent\n"); 5123 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5124 5125 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5126 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5127 5128 validate_status_stopped(status, SIGTRAP); 5129 5130 DPRINTF("Before resuming the child process where it left off and " 5131 "without signal to be sent\n"); 5132 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5133 5134 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5135 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5136 5137 validate_status_exited(status, exitval); 5138 5139 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5140 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5141} 5142 5143#include "t_ptrace_amd64_wait.h" 5144#include "t_ptrace_i386_wait.h" 5145#include "t_ptrace_x86_wait.h" 5146 5147ATF_TP_ADD_TCS(tp) 5148{ 5149 setvbuf(stdout, NULL, _IONBF, 0); 5150 setvbuf(stderr, NULL, _IONBF, 0); 5151 5152 ATF_TP_ADD_TC(tp, traceme_raise1); 5153 ATF_TP_ADD_TC(tp, traceme_raise2); 5154 ATF_TP_ADD_TC(tp, traceme_raise3); 5155 ATF_TP_ADD_TC(tp, traceme_raise4); 5156 ATF_TP_ADD_TC(tp, traceme_raise5); 5157 5158 ATF_TP_ADD_TC(tp, traceme_crash_trap); 5159 ATF_TP_ADD_TC(tp, traceme_crash_segv); 5160 ATF_TP_ADD_TC(tp, traceme_crash_ill); 5161 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 5162 ATF_TP_ADD_TC(tp, traceme_crash_bus); 5163 5164 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 5165 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 5166 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 5167 5168 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 5169 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 5170 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 5171 5172 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 5173 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 5174 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 5175 5176 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 5177 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 5178 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 5179 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 5180 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 5181 5182 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 5183 5184 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 5185 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 5186 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 5187 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 5188 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 5189 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 5190 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 5191 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 5192 5193 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 5194 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 5195 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 5196 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 5197 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 5198 5199 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 5200 5201 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 5202 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 5203 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 5204 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 5205 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 5206 5207 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 5208 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 5209 ATF_TP_ADD_TC_HAVE_PID(tp, 5210 unrelated_tracer_sees_terminaton_before_the_parent); 5211 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 5212 5213 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 5214 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 5215 5216 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 5217 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 5218 5219 ATF_TP_ADD_TC_HAVE_PID(tp, 5220 tracee_sees_its_original_parent_getppid); 5221 ATF_TP_ADD_TC_HAVE_PID(tp, 5222 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 5223 ATF_TP_ADD_TC_HAVE_PID(tp, 5224 tracee_sees_its_original_parent_procfs_status); 5225 5226 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 5227 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 5228 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 5229 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 5230 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 5231 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 5232 5233 ATF_TP_ADD_TC(tp, fork1); 5234 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 5235 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 5236 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 5237 ATF_TP_ADD_TC(tp, fork5); 5238 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 5239 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 5240 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 5241 5242 ATF_TP_ADD_TC(tp, vfork1); 5243 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 5244 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 5245 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 5246 ATF_TP_ADD_TC(tp, vfork5); 5247 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 5248// thes tests hang on SMP machines, disable them for now 5249// ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 5250// ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 5251 5252 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 5253 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 5254 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 5255 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 5256 5257 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 5258 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 5259 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 5260 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 5261 5262 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 5263 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 5264 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 5265 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 5266 5267 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 5268 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 5269 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 5270 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 5271 5272 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 5273 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 5274 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 5275 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 5276 5277 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 5278 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 5279 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 5280 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 5281 5282 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 5283 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 5284 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 5285 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 5286 5287 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 5288 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 5289 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 5290 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 5291 5292 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 5293 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 5294 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 5295 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 5296 5297 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 5298 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 5299 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 5300 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 5301 5302 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 5303 5304 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 5305 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 5306 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 5307 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 5308 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 5309 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 5310 5311 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 5312 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 5313 5314 ATF_TP_ADD_TC_PT_STEP(tp, step1); 5315 ATF_TP_ADD_TC_PT_STEP(tp, step2); 5316 ATF_TP_ADD_TC_PT_STEP(tp, step3); 5317 ATF_TP_ADD_TC_PT_STEP(tp, step4); 5318 5319 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 5320 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 5321 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 5322 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 5323 5324 ATF_TP_ADD_TC(tp, kill1); 5325 ATF_TP_ADD_TC(tp, kill2); 5326 ATF_TP_ADD_TC(tp, kill3); 5327 5328 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 5329 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 5330 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 5331 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 5332 5333 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 5334 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 5335 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 5336 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 5337 5338 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 5339 ATF_TP_ADD_TC(tp, siginfo_set_faked); 5340 5341 ATF_TP_ADD_TC(tp, siginfo4); 5342 5343 ATF_TP_ADD_TC(tp, lwp_create1); 5344 5345 ATF_TP_ADD_TC(tp, lwp_exit1); 5346 5347 ATF_TP_ADD_TC(tp, signal1); 5348 ATF_TP_ADD_TC(tp, signal2); 5349 ATF_TP_ADD_TC(tp, signal3); 5350 ATF_TP_ADD_TC_PT_STEP(tp, signal4); 5351 ATF_TP_ADD_TC(tp, signal5); 5352 ATF_TP_ADD_TC_HAVE_PID(tp, signal6); 5353 ATF_TP_ADD_TC_HAVE_PID(tp, signal7); 5354 ATF_TP_ADD_TC(tp, signal8); 5355 ATF_TP_ADD_TC(tp, signal9); 5356 ATF_TP_ADD_TC(tp, signal10); 5357 5358 ATF_TP_ADD_TC(tp, suspend1); 5359 ATF_TP_ADD_TC(tp, suspend2); 5360 5361 ATF_TP_ADD_TC(tp, resume1); 5362 5363 ATF_TP_ADD_TC(tp, syscall1); 5364 5365 ATF_TP_ADD_TC(tp, syscallemu1); 5366 5367 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 5368 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 5369 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 5370 5371 return atf_no_error(); 5372} 5373