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