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