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