t_ptrace_wait.c revision 1.143
1/* $NetBSD: t_ptrace_wait.c,v 1.143 2019/12/24 14:50:59 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.143 2019/12/24 14:50:59 kamil Exp $"); 31 32#define __LEGACY_PT_LWPINFO 33 34#include <sys/param.h> 35#include <sys/types.h> 36#include <sys/exec_elf.h> 37#include <sys/mman.h> 38#include <sys/ptrace.h> 39#include <sys/resource.h> 40#include <sys/stat.h> 41#include <sys/syscall.h> 42#include <sys/sysctl.h> 43#include <sys/uio.h> 44#include <sys/wait.h> 45#include <machine/reg.h> 46#include <assert.h> 47#include <elf.h> 48#include <err.h> 49#include <errno.h> 50#include <fcntl.h> 51#include <lwp.h> 52#include <pthread.h> 53#include <sched.h> 54#include <signal.h> 55#include <spawn.h> 56#include <stdint.h> 57#include <stdio.h> 58#include <stdlib.h> 59#include <strings.h> 60#include <time.h> 61#include <unistd.h> 62 63#include <fenv.h> 64#if (__arm__ && !__SOFTFP__) || __aarch64__ 65#include <ieeefp.h> /* only need for ARM Cortex/Neon hack */ 66#endif 67 68#if defined(__i386__) || defined(__x86_64__) 69#include <cpuid.h> 70#include <x86/cpu_extended_state.h> 71#include <x86/specialreg.h> 72#endif 73 74#include <libelf.h> 75#include <gelf.h> 76 77#include <atf-c.h> 78 79/* Assumptions in the kernel code that must be kept. */ 80static_assert(sizeof(((struct ptrace_state *)0)->pe_report_event) == 81 sizeof(((siginfo_t *)0)->si_pe_report_event), 82 "pe_report_event and si_pe_report_event must be of the same size"); 83static_assert(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 84 sizeof(((siginfo_t *)0)->si_pe_other_pid), 85 "pe_other_pid and si_pe_other_pid must be of the same size"); 86static_assert(sizeof(((struct ptrace_state *)0)->pe_lwp) == 87 sizeof(((siginfo_t *)0)->si_pe_lwp), 88 "pe_lwp and si_pe_lwp must be of the same size"); 89static_assert(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 90 sizeof(((struct ptrace_state *)0)->pe_lwp), 91 "pe_other_pid and pe_lwp must be of the same size"); 92 93#include "h_macros.h" 94 95#include "t_ptrace_wait.h" 96#include "msg.h" 97 98#define PARENT_TO_CHILD(info, fds, msg) \ 99 SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, \ 100 sizeof(msg)) == 0) 101 102#define CHILD_FROM_PARENT(info, fds, msg) \ 103 FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, \ 104 sizeof(msg)) == 0) 105 106#define CHILD_TO_PARENT(info, fds, msg) \ 107 FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, \ 108 sizeof(msg)) == 0) 109 110#define PARENT_FROM_CHILD(info, fds, msg) \ 111 SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, \ 112 sizeof(msg)) == 0) 113 114#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 115 strerror(errno)) 116#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 117 "%d(%s) != %d", res, strerror(res), exp) 118 119static int debug = 0; 120 121#define DPRINTF(a, ...) do \ 122 if (debug) \ 123 printf("%s() %d.%d %s:%d " a, \ 124 __func__, getpid(), _lwp_self(), __FILE__, __LINE__, ##__VA_ARGS__); \ 125 while (/*CONSTCOND*/0) 126 127/// ---------------------------------------------------------------------------- 128 129static void 130traceme_raise(int sigval) 131{ 132 const int exitval = 5; 133 pid_t child, wpid; 134#if defined(TWAIT_HAVE_STATUS) 135 int status; 136#endif 137 138 ptrace_state_t state, zero_state; 139 const int slen = sizeof(state); 140 struct ptrace_siginfo info; 141 memset(&zero_state, 0, sizeof(zero_state)); 142 memset(&info, 0, sizeof(info)); 143 144 DPRINTF("Before forking process PID=%d\n", getpid()); 145 SYSCALL_REQUIRE((child = fork()) != -1); 146 if (child == 0) { 147 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 148 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 149 150 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 151 FORKEE_ASSERT(raise(sigval) == 0); 152 153 switch (sigval) { 154 case SIGKILL: 155 /* NOTREACHED */ 156 FORKEE_ASSERTX(0 && "This shall not be reached"); 157 __unreachable(); 158 default: 159 DPRINTF("Before exiting of the child process\n"); 160 _exit(exitval); 161 } 162 } 163 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 164 165 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 166 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 167 168 switch (sigval) { 169 case SIGKILL: 170 validate_status_signaled(status, sigval, 0); 171 SYSCALL_REQUIRE( 172 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) == -1); 173 174 break; 175 default: 176 validate_status_stopped(status, sigval); 177 178 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 179 "child\n"); 180 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 181 sizeof(info)) != -1); 182 183 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 184 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 185 "si_errno=%#x\n", 186 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 187 info.psi_siginfo.si_errno); 188 189 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 190 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 191 192 DPRINTF("Assert that PT_GET_PROCESS_STATE returns non-error"); 193 SYSCALL_REQUIRE( 194 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 195 ATF_REQUIRE(memcmp(&state, &zero_state, slen) == 0); 196 197 DPRINTF("Before resuming the child process where it left off " 198 "and without signal to be sent\n"); 199 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 200 201 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 202 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 203 child); 204 break; 205 } 206 207 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 208 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 209} 210 211#define TRACEME_RAISE(test, sig) \ 212ATF_TC(test); \ 213ATF_TC_HEAD(test, tc) \ 214{ \ 215 atf_tc_set_md_var(tc, "descr", \ 216 "Verify " #sig " followed by _exit(2) in a child"); \ 217} \ 218 \ 219ATF_TC_BODY(test, tc) \ 220{ \ 221 \ 222 traceme_raise(sig); \ 223} 224 225TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ 226TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */ 227TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */ 228TRACEME_RAISE(traceme_raise4, SIGHUP) /* hangup */ 229TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */ 230TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */ 231TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */ 232TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */ 233TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */ 234TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */ 235 236/// ---------------------------------------------------------------------------- 237 238static void 239traceme_raisesignal_ignored(int sigignored) 240{ 241 const int exitval = 5; 242 const int sigval = SIGSTOP; 243 pid_t child, wpid; 244 struct sigaction sa; 245#if defined(TWAIT_HAVE_STATUS) 246 int status; 247#endif 248 struct ptrace_siginfo info; 249 250 memset(&info, 0, sizeof(info)); 251 252 DPRINTF("Before forking process PID=%d\n", getpid()); 253 SYSCALL_REQUIRE((child = fork()) != -1); 254 if (child == 0) { 255 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 256 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 257 258 memset(&sa, 0, sizeof(sa)); 259 sa.sa_handler = SIG_IGN; 260 sigemptyset(&sa.sa_mask); 261 FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1); 262 263 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 264 FORKEE_ASSERT(raise(sigval) == 0); 265 266 DPRINTF("Before raising %s from child\n", 267 strsignal(sigignored)); 268 FORKEE_ASSERT(raise(sigignored) == 0); 269 270 DPRINTF("Before exiting of the child process\n"); 271 _exit(exitval); 272 } 273 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 274 275 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 276 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 277 278 validate_status_stopped(status, sigval); 279 280 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 281 SYSCALL_REQUIRE( 282 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 283 284 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 285 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 286 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 287 info.psi_siginfo.si_errno); 288 289 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 290 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 291 292 DPRINTF("Before resuming the child process where it left off and " 293 "without signal to be sent\n"); 294 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 295 296 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 297 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 298 299 validate_status_stopped(status, sigignored); 300 301 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 302 SYSCALL_REQUIRE( 303 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 304 305 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 306 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 307 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 308 info.psi_siginfo.si_errno); 309 310 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored); 311 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 312 313 DPRINTF("Before resuming the child process where it left off and " 314 "without signal to be sent\n"); 315 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 316 317 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 318 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 319 320 validate_status_exited(status, exitval); 321 322 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 323 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 324} 325 326#define TRACEME_RAISESIGNAL_IGNORED(test, sig) \ 327ATF_TC(test); \ 328ATF_TC_HEAD(test, tc) \ 329{ \ 330 atf_tc_set_md_var(tc, "descr", \ 331 "Verify that ignoring (with SIG_IGN) " #sig " in tracee " \ 332 "does not stop tracer from catching this raised signal"); \ 333} \ 334 \ 335ATF_TC_BODY(test, tc) \ 336{ \ 337 \ 338 traceme_raisesignal_ignored(sig); \ 339} 340 341// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 342TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */ 343TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP) /* hangup */ 344TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */ 345TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */ 346TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */ 347TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */ 348TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */ 349TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */ 350 351/// ---------------------------------------------------------------------------- 352 353static void 354traceme_raisesignal_masked(int sigmasked) 355{ 356 const int exitval = 5; 357 const int sigval = SIGSTOP; 358 pid_t child, wpid; 359#if defined(TWAIT_HAVE_STATUS) 360 int status; 361#endif 362 sigset_t intmask; 363 struct ptrace_siginfo info; 364 365 memset(&info, 0, sizeof(info)); 366 367 DPRINTF("Before forking process PID=%d\n", getpid()); 368 SYSCALL_REQUIRE((child = fork()) != -1); 369 if (child == 0) { 370 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 371 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 372 373 sigemptyset(&intmask); 374 sigaddset(&intmask, sigmasked); 375 sigprocmask(SIG_BLOCK, &intmask, NULL); 376 377 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 378 FORKEE_ASSERT(raise(sigval) == 0); 379 380 DPRINTF("Before raising %s breakpoint from child\n", 381 strsignal(sigmasked)); 382 FORKEE_ASSERT(raise(sigmasked) == 0); 383 384 DPRINTF("Before exiting of the child process\n"); 385 _exit(exitval); 386 } 387 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 388 389 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 390 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 391 392 validate_status_stopped(status, sigval); 393 394 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 395 SYSCALL_REQUIRE( 396 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 397 398 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 399 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 400 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 401 info.psi_siginfo.si_errno); 402 403 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 404 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 405 406 DPRINTF("Before resuming the child process where it left off and " 407 "without signal to be sent\n"); 408 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 409 410 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 411 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 412 413 validate_status_exited(status, exitval); 414 415 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 416 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 417} 418 419#define TRACEME_RAISESIGNAL_MASKED(test, sig) \ 420ATF_TC(test); \ 421ATF_TC_HEAD(test, tc) \ 422{ \ 423 atf_tc_set_md_var(tc, "descr", \ 424 "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \ 425 "stops tracer from catching this raised signal"); \ 426} \ 427 \ 428ATF_TC_BODY(test, tc) \ 429{ \ 430 \ 431 traceme_raisesignal_masked(sig); \ 432} 433 434// A signal handler for SIGKILL and SIGSTOP cannot be masked. 435TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */ 436TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */ 437TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */ 438TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */ 439TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */ 440TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */ 441TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */ 442TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */ 443 444/// ---------------------------------------------------------------------------- 445 446static void 447traceme_crash(int sig) 448{ 449 pid_t child, wpid; 450#if defined(TWAIT_HAVE_STATUS) 451 int status; 452#endif 453 struct ptrace_siginfo info; 454 455#ifndef PTRACE_ILLEGAL_ASM 456 if (sig == SIGILL) 457 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 458#endif 459 460 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 461 atf_tc_skip("FP exceptions are not supported"); 462 463 memset(&info, 0, sizeof(info)); 464 465 DPRINTF("Before forking process PID=%d\n", getpid()); 466 SYSCALL_REQUIRE((child = fork()) != -1); 467 if (child == 0) { 468 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 469 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 470 471 DPRINTF("Before executing a trap\n"); 472 switch (sig) { 473 case SIGTRAP: 474 trigger_trap(); 475 break; 476 case SIGSEGV: 477 trigger_segv(); 478 break; 479 case SIGILL: 480 trigger_ill(); 481 break; 482 case SIGFPE: 483 trigger_fpe(); 484 break; 485 case SIGBUS: 486 trigger_bus(); 487 break; 488 default: 489 /* NOTREACHED */ 490 FORKEE_ASSERTX(0 && "This shall not be reached"); 491 } 492 493 /* NOTREACHED */ 494 FORKEE_ASSERTX(0 && "This shall not be reached"); 495 } 496 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 497 498 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 499 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 500 501 validate_status_stopped(status, sig); 502 503 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 504 SYSCALL_REQUIRE( 505 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 506 507 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 508 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 509 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 510 info.psi_siginfo.si_errno); 511 512 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 513 switch (sig) { 514 case SIGTRAP: 515 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 516 break; 517 case SIGSEGV: 518 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 519 break; 520 case SIGILL: 521 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 522 info.psi_siginfo.si_code <= ILL_BADSTK); 523 break; 524 case SIGFPE: 525 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 526 break; 527 case SIGBUS: 528 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 529 break; 530 } 531 532 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 533 534 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 535 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 536 537 validate_status_signaled(status, SIGKILL, 0); 538 539 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 540 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 541} 542 543#define TRACEME_CRASH(test, sig) \ 544ATF_TC(test); \ 545ATF_TC_HEAD(test, tc) \ 546{ \ 547 atf_tc_set_md_var(tc, "descr", \ 548 "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \ 549} \ 550 \ 551ATF_TC_BODY(test, tc) \ 552{ \ 553 \ 554 traceme_crash(sig); \ 555} 556 557TRACEME_CRASH(traceme_crash_trap, SIGTRAP) 558TRACEME_CRASH(traceme_crash_segv, SIGSEGV) 559TRACEME_CRASH(traceme_crash_ill, SIGILL) 560TRACEME_CRASH(traceme_crash_fpe, SIGFPE) 561TRACEME_CRASH(traceme_crash_bus, SIGBUS) 562 563/// ---------------------------------------------------------------------------- 564 565static void 566traceme_signalmasked_crash(int sig) 567{ 568 const int sigval = SIGSTOP; 569 pid_t child, wpid; 570#if defined(TWAIT_HAVE_STATUS) 571 int status; 572#endif 573 struct ptrace_siginfo info; 574 sigset_t intmask; 575 struct kinfo_proc2 kp; 576 size_t len = sizeof(kp); 577 578 int name[6]; 579 const size_t namelen = __arraycount(name); 580 ki_sigset_t kp_sigmask; 581 582#ifndef PTRACE_ILLEGAL_ASM 583 if (sig == SIGILL) 584 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 585#endif 586 587 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 588 atf_tc_skip("FP exceptions are not supported"); 589 590 memset(&info, 0, sizeof(info)); 591 592 DPRINTF("Before forking process PID=%d\n", getpid()); 593 SYSCALL_REQUIRE((child = fork()) != -1); 594 if (child == 0) { 595 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 596 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 597 598 sigemptyset(&intmask); 599 sigaddset(&intmask, sig); 600 sigprocmask(SIG_BLOCK, &intmask, NULL); 601 602 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 603 FORKEE_ASSERT(raise(sigval) == 0); 604 605 DPRINTF("Before executing a trap\n"); 606 switch (sig) { 607 case SIGTRAP: 608 trigger_trap(); 609 break; 610 case SIGSEGV: 611 trigger_segv(); 612 break; 613 case SIGILL: 614 trigger_ill(); 615 break; 616 case SIGFPE: 617 trigger_fpe(); 618 break; 619 case SIGBUS: 620 trigger_bus(); 621 break; 622 default: 623 /* NOTREACHED */ 624 FORKEE_ASSERTX(0 && "This shall not be reached"); 625 } 626 627 /* NOTREACHED */ 628 FORKEE_ASSERTX(0 && "This shall not be reached"); 629 } 630 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 631 632 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 633 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 634 635 validate_status_stopped(status, sigval); 636 637 name[0] = CTL_KERN, 638 name[1] = KERN_PROC2, 639 name[2] = KERN_PROC_PID; 640 name[3] = child; 641 name[4] = sizeof(kp); 642 name[5] = 1; 643 644 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 645 646 kp_sigmask = kp.p_sigmask; 647 648 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 649 SYSCALL_REQUIRE( 650 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 651 652 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 653 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 654 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 655 info.psi_siginfo.si_errno); 656 657 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 658 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 659 660 DPRINTF("Before resuming the child process where it left off and " 661 "without signal to be sent\n"); 662 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 663 664 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 665 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 666 667 validate_status_stopped(status, sig); 668 669 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 670 SYSCALL_REQUIRE( 671 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 672 673 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 674 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 675 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 676 info.psi_siginfo.si_errno); 677 678 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 679 680 DPRINTF("kp_sigmask=" 681 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 682 kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2], 683 kp_sigmask.__bits[3]); 684 685 DPRINTF("kp.p_sigmask=" 686 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 687 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 688 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 689 690 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask))); 691 692 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 693 switch (sig) { 694 case SIGTRAP: 695 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 696 break; 697 case SIGSEGV: 698 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 699 break; 700 case SIGILL: 701 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 702 info.psi_siginfo.si_code <= ILL_BADSTK); 703 break; 704 case SIGFPE: 705 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 706 break; 707 case SIGBUS: 708 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 709 break; 710 } 711 712 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 713 714 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 715 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 716 717 validate_status_signaled(status, SIGKILL, 0); 718 719 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 720 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 721} 722 723#define TRACEME_SIGNALMASKED_CRASH(test, sig) \ 724ATF_TC(test); \ 725ATF_TC_HEAD(test, tc) \ 726{ \ 727 atf_tc_set_md_var(tc, "descr", \ 728 "Verify masked crash signal " #sig " in a child after " \ 729 "PT_TRACE_ME is delivered to its tracer"); \ 730} \ 731 \ 732ATF_TC_BODY(test, tc) \ 733{ \ 734 \ 735 traceme_signalmasked_crash(sig); \ 736} 737 738TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP) 739TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV) 740TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL) 741TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE) 742TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS) 743 744/// ---------------------------------------------------------------------------- 745 746static void 747traceme_signalignored_crash(int sig) 748{ 749 const int sigval = SIGSTOP; 750 pid_t child, wpid; 751#if defined(TWAIT_HAVE_STATUS) 752 int status; 753#endif 754 struct sigaction sa; 755 struct ptrace_siginfo info; 756 struct kinfo_proc2 kp; 757 size_t len = sizeof(kp); 758 759 int name[6]; 760 const size_t namelen = __arraycount(name); 761 ki_sigset_t kp_sigignore; 762 763#ifndef PTRACE_ILLEGAL_ASM 764 if (sig == SIGILL) 765 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 766#endif 767 768 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 769 atf_tc_skip("FP exceptions are not supported"); 770 771 memset(&info, 0, sizeof(info)); 772 773 DPRINTF("Before forking process PID=%d\n", getpid()); 774 SYSCALL_REQUIRE((child = fork()) != -1); 775 if (child == 0) { 776 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 777 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 778 779 memset(&sa, 0, sizeof(sa)); 780 sa.sa_handler = SIG_IGN; 781 sigemptyset(&sa.sa_mask); 782 783 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 784 785 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 786 FORKEE_ASSERT(raise(sigval) == 0); 787 788 DPRINTF("Before executing a trap\n"); 789 switch (sig) { 790 case SIGTRAP: 791 trigger_trap(); 792 break; 793 case SIGSEGV: 794 trigger_segv(); 795 break; 796 case SIGILL: 797 trigger_ill(); 798 break; 799 case SIGFPE: 800 trigger_fpe(); 801 break; 802 case SIGBUS: 803 trigger_bus(); 804 break; 805 default: 806 /* NOTREACHED */ 807 FORKEE_ASSERTX(0 && "This shall not be reached"); 808 } 809 810 /* NOTREACHED */ 811 FORKEE_ASSERTX(0 && "This shall not be reached"); 812 } 813 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 814 815 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 816 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 817 818 validate_status_stopped(status, sigval); 819 820 name[0] = CTL_KERN, 821 name[1] = KERN_PROC2, 822 name[2] = KERN_PROC_PID; 823 name[3] = child; 824 name[4] = sizeof(kp); 825 name[5] = 1; 826 827 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 828 829 kp_sigignore = kp.p_sigignore; 830 831 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 832 SYSCALL_REQUIRE( 833 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 834 835 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 836 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 837 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 838 info.psi_siginfo.si_errno); 839 840 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 841 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 842 843 DPRINTF("Before resuming the child process where it left off and " 844 "without signal to be sent\n"); 845 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 846 847 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 848 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 849 850 validate_status_stopped(status, sig); 851 852 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 853 SYSCALL_REQUIRE( 854 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 855 856 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 857 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 858 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 859 info.psi_siginfo.si_errno); 860 861 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 862 863 DPRINTF("kp_sigignore=" 864 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 865 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 866 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 867 868 DPRINTF("kp.p_sigignore=" 869 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 870 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 871 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 872 873 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore))); 874 875 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 876 switch (sig) { 877 case SIGTRAP: 878 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 879 break; 880 case SIGSEGV: 881 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 882 break; 883 case SIGILL: 884 ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC && 885 info.psi_siginfo.si_code <= ILL_BADSTK); 886 break; 887 case SIGFPE: 888 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 889 break; 890 case SIGBUS: 891 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 892 break; 893 } 894 895 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 896 897 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 898 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 899 900 validate_status_signaled(status, SIGKILL, 0); 901 902 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 903 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 904} 905 906#define TRACEME_SIGNALIGNORED_CRASH(test, sig) \ 907ATF_TC(test); \ 908ATF_TC_HEAD(test, tc) \ 909{ \ 910 atf_tc_set_md_var(tc, "descr", \ 911 "Verify ignored crash signal " #sig " in a child after " \ 912 "PT_TRACE_ME is delivered to its tracer"); \ 913} \ 914 \ 915ATF_TC_BODY(test, tc) \ 916{ \ 917 \ 918 traceme_signalignored_crash(sig); \ 919} 920 921TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP) 922TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV) 923TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL) 924TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE) 925TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS) 926 927/// ---------------------------------------------------------------------------- 928 929static void 930traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 931{ 932 const int exitval = 5; 933 const int sigval = SIGSTOP; 934 pid_t child, wpid; 935 struct sigaction sa; 936#if defined(TWAIT_HAVE_STATUS) 937 int status; 938#endif 939 struct ptrace_siginfo info; 940 941 memset(&info, 0, sizeof(info)); 942 943 DPRINTF("Before forking process PID=%d\n", getpid()); 944 SYSCALL_REQUIRE((child = fork()) != -1); 945 if (child == 0) { 946 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 947 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 948 949 sa.sa_handler = sah; 950 sa.sa_flags = SA_SIGINFO; 951 sigemptyset(&sa.sa_mask); 952 953 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 954 955 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 956 FORKEE_ASSERT(raise(sigval) == 0); 957 958 FORKEE_ASSERT_EQ(*traceme_caught, 1); 959 960 DPRINTF("Before exiting of the child process\n"); 961 _exit(exitval); 962 } 963 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 964 965 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 966 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 967 968 validate_status_stopped(status, sigval); 969 970 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 971 SYSCALL_REQUIRE( 972 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 973 974 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 975 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 976 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 977 info.psi_siginfo.si_errno); 978 979 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 980 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 981 982 DPRINTF("Before resuming the child process where it left off and with " 983 "signal %s to be sent\n", strsignal(sigsent)); 984 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 985 986 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 987 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 988 989 validate_status_exited(status, exitval); 990 991 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 992 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 993} 994 995#define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 996ATF_TC(test); \ 997ATF_TC_HEAD(test, tc) \ 998{ \ 999 atf_tc_set_md_var(tc, "descr", \ 1000 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1001 "handled correctly and caught by a signal handler"); \ 1002} \ 1003 \ 1004static int test##_caught = 0; \ 1005 \ 1006static void \ 1007test##_sighandler(int arg) \ 1008{ \ 1009 FORKEE_ASSERT_EQ(arg, sig); \ 1010 \ 1011 ++ test##_caught; \ 1012} \ 1013 \ 1014ATF_TC_BODY(test, tc) \ 1015{ \ 1016 \ 1017 traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 1018} 1019 1020// A signal handler for SIGKILL and SIGSTOP cannot be registered. 1021TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 1022TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 1023TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 1024TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 1025TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 1026TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 1027TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 1028TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 1029 1030/// ---------------------------------------------------------------------------- 1031 1032static void 1033traceme_sendsignal_masked(int sigsent) 1034{ 1035 const int exitval = 5; 1036 const int sigval = SIGSTOP; 1037 pid_t child, wpid; 1038 sigset_t set; 1039#if defined(TWAIT_HAVE_STATUS) 1040 int status; 1041#endif 1042 struct ptrace_siginfo info; 1043 1044 memset(&info, 0, sizeof(info)); 1045 1046 DPRINTF("Before forking process PID=%d\n", getpid()); 1047 SYSCALL_REQUIRE((child = fork()) != -1); 1048 if (child == 0) { 1049 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1050 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1051 1052 sigemptyset(&set); 1053 sigaddset(&set, sigsent); 1054 FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 1055 1056 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1057 FORKEE_ASSERT(raise(sigval) == 0); 1058 1059 _exit(exitval); 1060 } 1061 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1062 1063 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1064 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1065 1066 validate_status_stopped(status, sigval); 1067 1068 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1069 SYSCALL_REQUIRE( 1070 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1071 1072 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1073 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1074 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1075 info.psi_siginfo.si_errno); 1076 1077 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1078 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1079 1080 DPRINTF("Before resuming the child process where it left off and with " 1081 "signal %s to be sent\n", strsignal(sigsent)); 1082 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1083 1084 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1085 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1086 1087 validate_status_exited(status, exitval); 1088 1089 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1090 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1091} 1092 1093#define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 1094ATF_TC(test); \ 1095ATF_TC_HEAD(test, tc) \ 1096{ \ 1097 atf_tc_set_md_var(tc, "descr", \ 1098 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1099 "handled correctly and the signal is masked by SIG_BLOCK"); \ 1100} \ 1101 \ 1102ATF_TC_BODY(test, tc) \ 1103{ \ 1104 \ 1105 traceme_sendsignal_masked(sig); \ 1106} 1107 1108// A signal handler for SIGKILL and SIGSTOP cannot be masked. 1109TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 1110TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 1111TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 1112TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 1113TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 1114TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 1115TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 1116TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 1117 1118/// ---------------------------------------------------------------------------- 1119 1120static void 1121traceme_sendsignal_ignored(int sigsent) 1122{ 1123 const int exitval = 5; 1124 const int sigval = SIGSTOP; 1125 pid_t child, wpid; 1126 struct sigaction sa; 1127#if defined(TWAIT_HAVE_STATUS) 1128 int status; 1129#endif 1130 struct ptrace_siginfo info; 1131 1132 memset(&info, 0, sizeof(info)); 1133 1134 DPRINTF("Before forking process PID=%d\n", getpid()); 1135 SYSCALL_REQUIRE((child = fork()) != -1); 1136 if (child == 0) { 1137 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1138 1139 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1140 1141 memset(&sa, 0, sizeof(sa)); 1142 sa.sa_handler = SIG_IGN; 1143 sigemptyset(&sa.sa_mask); 1144 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 1145 1146 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1147 FORKEE_ASSERT(raise(sigval) == 0); 1148 1149 _exit(exitval); 1150 } 1151 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1152 1153 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1154 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1155 1156 validate_status_stopped(status, sigval); 1157 1158 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1159 SYSCALL_REQUIRE( 1160 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1161 1162 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1163 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1164 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1165 info.psi_siginfo.si_errno); 1166 1167 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1168 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1169 1170 DPRINTF("Before resuming the child process where it left off and with " 1171 "signal %s to be sent\n", strsignal(sigsent)); 1172 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1173 1174 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1175 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1176 1177 validate_status_exited(status, exitval); 1178 1179 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1180 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1181} 1182 1183#define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 1184ATF_TC(test); \ 1185ATF_TC_HEAD(test, tc) \ 1186{ \ 1187 atf_tc_set_md_var(tc, "descr", \ 1188 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1189 "handled correctly and the signal is masked by SIG_IGN"); \ 1190} \ 1191 \ 1192ATF_TC_BODY(test, tc) \ 1193{ \ 1194 \ 1195 traceme_sendsignal_ignored(sig); \ 1196} 1197 1198// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 1199TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 1200TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 1201TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 1202TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 1203TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 1204TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 1205TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 1206TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 1207 1208/// ---------------------------------------------------------------------------- 1209 1210static void 1211traceme_sendsignal_simple(int sigsent) 1212{ 1213 const int sigval = SIGSTOP; 1214 int exitval = 0; 1215 pid_t child, wpid; 1216#if defined(TWAIT_HAVE_STATUS) 1217 int status; 1218 int expect_core; 1219 1220 switch (sigsent) { 1221 case SIGABRT: 1222 case SIGTRAP: 1223 case SIGBUS: 1224 case SIGILL: 1225 case SIGFPE: 1226 case SIGSEGV: 1227 expect_core = 1; 1228 break; 1229 default: 1230 expect_core = 0; 1231 break; 1232 } 1233#endif 1234 struct ptrace_siginfo info; 1235 1236 memset(&info, 0, sizeof(info)); 1237 1238 DPRINTF("Before forking process PID=%d\n", getpid()); 1239 SYSCALL_REQUIRE((child = fork()) != -1); 1240 if (child == 0) { 1241 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1242 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1243 1244 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1245 FORKEE_ASSERT(raise(sigval) == 0); 1246 1247 switch (sigsent) { 1248 case SIGCONT: 1249 case SIGSTOP: 1250 _exit(exitval); 1251 default: 1252 /* NOTREACHED */ 1253 FORKEE_ASSERTX(0 && "This shall not be reached"); 1254 } 1255 } 1256 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1257 1258 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1259 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1260 1261 validate_status_stopped(status, sigval); 1262 1263 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1264 SYSCALL_REQUIRE( 1265 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1266 1267 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1268 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1269 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1270 info.psi_siginfo.si_errno); 1271 1272 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1273 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1274 1275 DPRINTF("Before resuming the child process where it left off and with " 1276 "signal %s to be sent\n", strsignal(sigsent)); 1277 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 1278 1279 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1280 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1281 1282 switch (sigsent) { 1283 case SIGSTOP: 1284 validate_status_stopped(status, sigsent); 1285 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1286 "child\n"); 1287 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1288 sizeof(info)) != -1); 1289 1290 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1291 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1292 "si_errno=%#x\n", 1293 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1294 info.psi_siginfo.si_errno); 1295 1296 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1297 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1298 1299 DPRINTF("Before resuming the child process where it left off " 1300 "and with signal %s to be sent\n", strsignal(sigsent)); 1301 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1302 1303 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1304 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1305 child); 1306 /* FALLTHROUGH */ 1307 case SIGCONT: 1308 validate_status_exited(status, exitval); 1309 break; 1310 default: 1311 validate_status_signaled(status, sigsent, expect_core); 1312 break; 1313 } 1314 1315 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1316 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1317} 1318 1319#define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 1320ATF_TC(test); \ 1321ATF_TC_HEAD(test, tc) \ 1322{ \ 1323 atf_tc_set_md_var(tc, "descr", \ 1324 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 1325 "handled correctly in a child without a signal handler"); \ 1326} \ 1327 \ 1328ATF_TC_BODY(test, tc) \ 1329{ \ 1330 \ 1331 traceme_sendsignal_simple(sig); \ 1332} 1333 1334TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 1335TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 1336TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 1337TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 1338TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 1339TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 1340TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 1341TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 1342TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 1343TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 1344 1345/// ---------------------------------------------------------------------------- 1346 1347ATF_TC(traceme_pid1_parent); 1348ATF_TC_HEAD(traceme_pid1_parent, tc) 1349{ 1350 atf_tc_set_md_var(tc, "descr", 1351 "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 1352} 1353 1354ATF_TC_BODY(traceme_pid1_parent, tc) 1355{ 1356 struct msg_fds parent_child; 1357 int exitval_child1 = 1, exitval_child2 = 2; 1358 pid_t child1, child2, wpid; 1359 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1360#if defined(TWAIT_HAVE_STATUS) 1361 int status; 1362#endif 1363 1364 SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 1365 1366 DPRINTF("Before forking process PID=%d\n", getpid()); 1367 SYSCALL_REQUIRE((child1 = fork()) != -1); 1368 if (child1 == 0) { 1369 DPRINTF("Before forking process PID=%d\n", getpid()); 1370 SYSCALL_REQUIRE((child2 = fork()) != -1); 1371 if (child2 != 0) { 1372 DPRINTF("Parent process PID=%d, child2's PID=%d\n", 1373 getpid(), child2); 1374 _exit(exitval_child1); 1375 } 1376 CHILD_FROM_PARENT("exit child1", parent_child, msg); 1377 1378 DPRINTF("Assert that our parent is PID1 (initproc)\n"); 1379 FORKEE_ASSERT_EQ(getppid(), 1); 1380 1381 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1382 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 1383 SYSCALL_REQUIRE_ERRNO(errno, EPERM); 1384 1385 CHILD_TO_PARENT("child2 exiting", parent_child, msg); 1386 1387 _exit(exitval_child2); 1388 } 1389 DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 1390 1391 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1392 TWAIT_REQUIRE_SUCCESS( 1393 wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 1394 1395 validate_status_exited(status, exitval_child1); 1396 1397 DPRINTF("Notify that child1 is dead\n"); 1398 PARENT_TO_CHILD("exit child1", parent_child, msg); 1399 1400 DPRINTF("Wait for exiting of child2\n"); 1401 PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 1402} 1403 1404/// ---------------------------------------------------------------------------- 1405 1406static void 1407traceme_vfork_raise(int sigval) 1408{ 1409 const int exitval = 5, exitval_watcher = 10; 1410 pid_t child, parent, watcher, wpid; 1411 int rv; 1412#if defined(TWAIT_HAVE_STATUS) 1413 int status; 1414 1415 /* volatile workarounds GCC -Werror=clobbered */ 1416 volatile int expect_core; 1417 1418 switch (sigval) { 1419 case SIGABRT: 1420 case SIGTRAP: 1421 case SIGBUS: 1422 case SIGILL: 1423 case SIGFPE: 1424 case SIGSEGV: 1425 expect_core = 1; 1426 break; 1427 default: 1428 expect_core = 0; 1429 break; 1430 } 1431#endif 1432 1433 /* 1434 * Spawn a dedicated thread to watch for a stopped child and emit 1435 * the SIGKILL signal to it. 1436 * 1437 * vfork(2) might clobber watcher, this means that it's safer and 1438 * simpler to reparent this process to initproc and forget about it. 1439 */ 1440 if (sigval == SIGSTOP) { 1441 parent = getpid(); 1442 1443 watcher = fork(); 1444 ATF_REQUIRE(watcher != 1); 1445 if (watcher == 0) { 1446 /* Double fork(2) trick to reparent to initproc */ 1447 watcher = fork(); 1448 FORKEE_ASSERT_NEQ(watcher, -1); 1449 if (watcher != 0) 1450 _exit(exitval_watcher); 1451 1452 child = await_stopped_child(parent); 1453 1454 errno = 0; 1455 rv = kill(child, SIGKILL); 1456 FORKEE_ASSERT_EQ(rv, 0); 1457 FORKEE_ASSERT_EQ(errno, 0); 1458 1459 /* This exit value will be collected by initproc */ 1460 _exit(0); 1461 } 1462 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1463 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 1464 watcher); 1465 1466 validate_status_exited(status, exitval_watcher); 1467 1468 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1469 TWAIT_REQUIRE_FAILURE(ECHILD, 1470 wpid = TWAIT_GENERIC(watcher, &status, 0)); 1471 } 1472 1473 DPRINTF("Before forking process PID=%d\n", getpid()); 1474 SYSCALL_REQUIRE((child = vfork()) != -1); 1475 if (child == 0) { 1476 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1477 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1478 1479 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1480 FORKEE_ASSERT(raise(sigval) == 0); 1481 1482 switch (sigval) { 1483 case SIGSTOP: 1484 case SIGKILL: 1485 case SIGABRT: 1486 case SIGHUP: 1487 case SIGTRAP: 1488 case SIGBUS: 1489 case SIGILL: 1490 case SIGFPE: 1491 case SIGSEGV: 1492 /* NOTREACHED */ 1493 FORKEE_ASSERTX(0 && "This shall not be reached"); 1494 __unreachable(); 1495 default: 1496 DPRINTF("Before exiting of the child process\n"); 1497 _exit(exitval); 1498 } 1499 } 1500 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1501 1502 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1503 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1504 1505 switch (sigval) { 1506 case SIGKILL: 1507 case SIGABRT: 1508 case SIGHUP: 1509 case SIGTRAP: 1510 case SIGBUS: 1511 case SIGILL: 1512 case SIGFPE: 1513 case SIGSEGV: 1514 validate_status_signaled(status, sigval, expect_core); 1515 break; 1516 case SIGSTOP: 1517 validate_status_signaled(status, SIGKILL, 0); 1518 break; 1519 case SIGCONT: 1520 case SIGTSTP: 1521 case SIGTTIN: 1522 case SIGTTOU: 1523 validate_status_exited(status, exitval); 1524 break; 1525 default: 1526 /* NOTREACHED */ 1527 ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 1528 break; 1529 } 1530 1531 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1532 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1533} 1534 1535#define TRACEME_VFORK_RAISE(test, sig) \ 1536ATF_TC(test); \ 1537ATF_TC_HEAD(test, tc) \ 1538{ \ 1539 atf_tc_set_md_var(tc, "descr", \ 1540 "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 1541 "vfork(2)ed child"); \ 1542} \ 1543 \ 1544ATF_TC_BODY(test, tc) \ 1545{ \ 1546 \ 1547 traceme_vfork_raise(sig); \ 1548} 1549 1550TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 1551TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 1552TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 1553TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 1554TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 1555TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 1556TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 1557TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 1558TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 1559TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 1560TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 1561TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 1562TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 1563 1564/// ---------------------------------------------------------------------------- 1565 1566static void 1567traceme_vfork_crash(int sig) 1568{ 1569 pid_t child, wpid; 1570#if defined(TWAIT_HAVE_STATUS) 1571 int status; 1572#endif 1573 1574#ifndef PTRACE_ILLEGAL_ASM 1575 if (sig == SIGILL) 1576 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1577#endif 1578 1579 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1580 atf_tc_skip("FP exceptions are not supported"); 1581 1582 DPRINTF("Before forking process PID=%d\n", getpid()); 1583 SYSCALL_REQUIRE((child = vfork()) != -1); 1584 if (child == 0) { 1585 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1586 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1587 1588 DPRINTF("Before executing a trap\n"); 1589 switch (sig) { 1590 case SIGTRAP: 1591 trigger_trap(); 1592 break; 1593 case SIGSEGV: 1594 trigger_segv(); 1595 break; 1596 case SIGILL: 1597 trigger_ill(); 1598 break; 1599 case SIGFPE: 1600 trigger_fpe(); 1601 break; 1602 case SIGBUS: 1603 trigger_bus(); 1604 break; 1605 default: 1606 /* NOTREACHED */ 1607 FORKEE_ASSERTX(0 && "This shall not be reached"); 1608 } 1609 1610 /* NOTREACHED */ 1611 FORKEE_ASSERTX(0 && "This shall not be reached"); 1612 } 1613 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1614 1615 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1616 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1617 1618 validate_status_signaled(status, sig, 1); 1619 1620 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1621 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1622} 1623 1624#define TRACEME_VFORK_CRASH(test, sig) \ 1625ATF_TC(test); \ 1626ATF_TC_HEAD(test, tc) \ 1627{ \ 1628 atf_tc_set_md_var(tc, "descr", \ 1629 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1630 "vfork(2)ed child"); \ 1631} \ 1632 \ 1633ATF_TC_BODY(test, tc) \ 1634{ \ 1635 \ 1636 traceme_vfork_crash(sig); \ 1637} 1638 1639TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 1640TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 1641TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 1642TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 1643TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 1644 1645/// ---------------------------------------------------------------------------- 1646 1647static void 1648traceme_vfork_signalmasked_crash(int sig) 1649{ 1650 pid_t child, wpid; 1651#if defined(TWAIT_HAVE_STATUS) 1652 int status; 1653#endif 1654 sigset_t intmask; 1655 1656#ifndef PTRACE_ILLEGAL_ASM 1657 if (sig == SIGILL) 1658 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1659#endif 1660 1661 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1662 atf_tc_skip("FP exceptions are not supported"); 1663 1664 DPRINTF("Before forking process PID=%d\n", getpid()); 1665 SYSCALL_REQUIRE((child = vfork()) != -1); 1666 if (child == 0) { 1667 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1668 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1669 1670 sigemptyset(&intmask); 1671 sigaddset(&intmask, sig); 1672 sigprocmask(SIG_BLOCK, &intmask, NULL); 1673 1674 DPRINTF("Before executing a trap\n"); 1675 switch (sig) { 1676 case SIGTRAP: 1677 trigger_trap(); 1678 break; 1679 case SIGSEGV: 1680 trigger_segv(); 1681 break; 1682 case SIGILL: 1683 trigger_ill(); 1684 break; 1685 case SIGFPE: 1686 trigger_fpe(); 1687 break; 1688 case SIGBUS: 1689 trigger_bus(); 1690 break; 1691 default: 1692 /* NOTREACHED */ 1693 FORKEE_ASSERTX(0 && "This shall not be reached"); 1694 } 1695 1696 /* NOTREACHED */ 1697 FORKEE_ASSERTX(0 && "This shall not be reached"); 1698 } 1699 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1700 1701 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1702 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1703 1704 validate_status_signaled(status, sig, 1); 1705 1706 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1707 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1708} 1709 1710#define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig) \ 1711ATF_TC(test); \ 1712ATF_TC_HEAD(test, tc) \ 1713{ \ 1714 atf_tc_set_md_var(tc, "descr", \ 1715 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1716 "vfork(2)ed child with a masked signal"); \ 1717} \ 1718 \ 1719ATF_TC_BODY(test, tc) \ 1720{ \ 1721 \ 1722 traceme_vfork_signalmasked_crash(sig); \ 1723} 1724 1725TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP) 1726TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV) 1727TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL) 1728TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE) 1729TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS) 1730 1731/// ---------------------------------------------------------------------------- 1732 1733static void 1734traceme_vfork_signalignored_crash(int sig) 1735{ 1736 pid_t child, wpid; 1737#if defined(TWAIT_HAVE_STATUS) 1738 int status; 1739#endif 1740 struct sigaction sa; 1741 1742#ifndef PTRACE_ILLEGAL_ASM 1743 if (sig == SIGILL) 1744 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1745#endif 1746 1747 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 1748 atf_tc_skip("FP exceptions are not supported"); 1749 1750 DPRINTF("Before forking process PID=%d\n", getpid()); 1751 SYSCALL_REQUIRE((child = vfork()) != -1); 1752 if (child == 0) { 1753 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1754 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1755 1756 memset(&sa, 0, sizeof(sa)); 1757 sa.sa_handler = SIG_IGN; 1758 sigemptyset(&sa.sa_mask); 1759 1760 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 1761 1762 DPRINTF("Before executing a trap\n"); 1763 switch (sig) { 1764 case SIGTRAP: 1765 trigger_trap(); 1766 break; 1767 case SIGSEGV: 1768 trigger_segv(); 1769 break; 1770 case SIGILL: 1771 trigger_ill(); 1772 break; 1773 case SIGFPE: 1774 trigger_fpe(); 1775 break; 1776 case SIGBUS: 1777 trigger_bus(); 1778 break; 1779 default: 1780 /* NOTREACHED */ 1781 FORKEE_ASSERTX(0 && "This shall not be reached"); 1782 } 1783 1784 /* NOTREACHED */ 1785 FORKEE_ASSERTX(0 && "This shall not be reached"); 1786 } 1787 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1788 1789 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1790 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1791 1792 validate_status_signaled(status, sig, 1); 1793 1794 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1795 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1796} 1797 1798#define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig) \ 1799ATF_TC(test); \ 1800ATF_TC_HEAD(test, tc) \ 1801{ \ 1802 atf_tc_set_md_var(tc, "descr", \ 1803 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1804 "vfork(2)ed child with ignored signal"); \ 1805} \ 1806 \ 1807ATF_TC_BODY(test, tc) \ 1808{ \ 1809 \ 1810 traceme_vfork_signalignored_crash(sig); \ 1811} 1812 1813TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap, 1814 SIGTRAP) 1815TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv, 1816 SIGSEGV) 1817TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill, 1818 SIGILL) 1819TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe, 1820 SIGFPE) 1821TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus, 1822 SIGBUS) 1823 1824/// ---------------------------------------------------------------------------- 1825 1826static void 1827traceme_vfork_exec(bool masked, bool ignored) 1828{ 1829 const int sigval = SIGTRAP; 1830 pid_t child, wpid; 1831#if defined(TWAIT_HAVE_STATUS) 1832 int status; 1833#endif 1834 struct sigaction sa; 1835 struct ptrace_siginfo info; 1836 sigset_t intmask; 1837 struct kinfo_proc2 kp; 1838 size_t len = sizeof(kp); 1839 1840 int name[6]; 1841 const size_t namelen = __arraycount(name); 1842 ki_sigset_t kp_sigmask; 1843 ki_sigset_t kp_sigignore; 1844 1845 memset(&info, 0, sizeof(info)); 1846 1847 DPRINTF("Before forking process PID=%d\n", getpid()); 1848 SYSCALL_REQUIRE((child = vfork()) != -1); 1849 if (child == 0) { 1850 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1851 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1852 1853 if (masked) { 1854 sigemptyset(&intmask); 1855 sigaddset(&intmask, sigval); 1856 sigprocmask(SIG_BLOCK, &intmask, NULL); 1857 } 1858 1859 if (ignored) { 1860 memset(&sa, 0, sizeof(sa)); 1861 sa.sa_handler = SIG_IGN; 1862 sigemptyset(&sa.sa_mask); 1863 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 1864 } 1865 1866 DPRINTF("Before calling execve(2) from child\n"); 1867 execlp("/bin/echo", "/bin/echo", NULL); 1868 1869 /* NOTREACHED */ 1870 FORKEE_ASSERTX(0 && "Not reached"); 1871 } 1872 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1873 1874 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1875 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1876 1877 validate_status_stopped(status, sigval); 1878 1879 name[0] = CTL_KERN, 1880 name[1] = KERN_PROC2, 1881 name[2] = KERN_PROC_PID; 1882 name[3] = getpid(); 1883 name[4] = sizeof(kp); 1884 name[5] = 1; 1885 1886 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1887 1888 if (masked) 1889 kp_sigmask = kp.p_sigmask; 1890 1891 if (ignored) 1892 kp_sigignore = kp.p_sigignore; 1893 1894 name[3] = getpid(); 1895 1896 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1897 1898 if (masked) { 1899 DPRINTF("kp_sigmask=" 1900 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1901 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1902 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1903 1904 DPRINTF("kp.p_sigmask=" 1905 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1906 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1907 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1908 1909 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 1910 sizeof(kp_sigmask))); 1911 } 1912 1913 if (ignored) { 1914 DPRINTF("kp_sigignore=" 1915 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1916 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1917 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1918 1919 DPRINTF("kp.p_sigignore=" 1920 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1921 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1922 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1923 1924 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 1925 sizeof(kp_sigignore))); 1926 } 1927 1928 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1929 SYSCALL_REQUIRE( 1930 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1931 1932 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1933 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1934 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1935 info.psi_siginfo.si_errno); 1936 1937 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1938 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1939 1940 DPRINTF("Before resuming the child process where it left off and " 1941 "without signal to be sent\n"); 1942 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1943 1944 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1945 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1946 1947 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1948 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1949} 1950 1951#define TRACEME_VFORK_EXEC(test, masked, ignored) \ 1952ATF_TC(test); \ 1953ATF_TC_HEAD(test, tc) \ 1954{ \ 1955 atf_tc_set_md_var(tc, "descr", \ 1956 "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed " \ 1957 "child%s%s", masked ? " with masked signal" : "", \ 1958 masked ? " with ignored signal" : ""); \ 1959} \ 1960 \ 1961ATF_TC_BODY(test, tc) \ 1962{ \ 1963 \ 1964 traceme_vfork_exec(masked, ignored); \ 1965} 1966 1967TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false) 1968TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false) 1969TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true) 1970 1971/// ---------------------------------------------------------------------------- 1972 1973#if defined(TWAIT_HAVE_PID) 1974static void 1975unrelated_tracer_sees_crash(int sig, bool masked, bool ignored) 1976{ 1977 const int sigval = SIGSTOP; 1978 struct msg_fds parent_tracee, parent_tracer; 1979 const int exitval = 10; 1980 pid_t tracee, tracer, wpid; 1981 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1982#if defined(TWAIT_HAVE_STATUS) 1983 int status; 1984#endif 1985 struct sigaction sa; 1986 struct ptrace_siginfo info; 1987 sigset_t intmask; 1988 struct kinfo_proc2 kp; 1989 size_t len = sizeof(kp); 1990 1991 int name[6]; 1992 const size_t namelen = __arraycount(name); 1993 ki_sigset_t kp_sigmask; 1994 ki_sigset_t kp_sigignore; 1995 1996#ifndef PTRACE_ILLEGAL_ASM 1997 if (sig == SIGILL) 1998 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1999#endif 2000 2001 if (sig == SIGFPE && !are_fpu_exceptions_supported()) 2002 atf_tc_skip("FP exceptions are not supported"); 2003 2004 memset(&info, 0, sizeof(info)); 2005 2006 DPRINTF("Spawn tracee\n"); 2007 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2008 tracee = atf_utils_fork(); 2009 if (tracee == 0) { 2010 // Wait for parent to let us crash 2011 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2012 2013 if (masked) { 2014 sigemptyset(&intmask); 2015 sigaddset(&intmask, sig); 2016 sigprocmask(SIG_BLOCK, &intmask, NULL); 2017 } 2018 2019 if (ignored) { 2020 memset(&sa, 0, sizeof(sa)); 2021 sa.sa_handler = SIG_IGN; 2022 sigemptyset(&sa.sa_mask); 2023 FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 2024 } 2025 2026 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2027 FORKEE_ASSERT(raise(sigval) == 0); 2028 2029 DPRINTF("Before executing a trap\n"); 2030 switch (sig) { 2031 case SIGTRAP: 2032 trigger_trap(); 2033 break; 2034 case SIGSEGV: 2035 trigger_segv(); 2036 break; 2037 case SIGILL: 2038 trigger_ill(); 2039 break; 2040 case SIGFPE: 2041 trigger_fpe(); 2042 break; 2043 case SIGBUS: 2044 trigger_bus(); 2045 break; 2046 default: 2047 /* NOTREACHED */ 2048 FORKEE_ASSERTX(0 && "This shall not be reached"); 2049 } 2050 2051 /* NOTREACHED */ 2052 FORKEE_ASSERTX(0 && "This shall not be reached"); 2053 } 2054 2055 DPRINTF("Spawn debugger\n"); 2056 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2057 tracer = atf_utils_fork(); 2058 if (tracer == 0) { 2059 /* Fork again and drop parent to reattach to PID 1 */ 2060 tracer = atf_utils_fork(); 2061 if (tracer != 0) 2062 _exit(exitval); 2063 2064 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2065 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2066 2067 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2068 FORKEE_REQUIRE_SUCCESS( 2069 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2070 2071 forkee_status_stopped(status, SIGSTOP); 2072 2073 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2074 "traced process\n"); 2075 SYSCALL_REQUIRE( 2076 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2077 2078 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2079 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2080 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2081 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2082 2083 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 2084 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 2085 2086 /* Resume tracee with PT_CONTINUE */ 2087 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2088 2089 /* Inform parent that tracer has attached to tracee */ 2090 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2091 2092 /* Wait for parent to tell use that tracee should have exited */ 2093 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2094 2095 /* Wait for tracee and assert that it exited */ 2096 FORKEE_REQUIRE_SUCCESS( 2097 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2098 2099 forkee_status_stopped(status, sigval); 2100 2101 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2102 "traced process\n"); 2103 SYSCALL_REQUIRE( 2104 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2105 2106 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2107 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2108 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2109 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2110 2111 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 2112 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 2113 2114 name[0] = CTL_KERN, 2115 name[1] = KERN_PROC2, 2116 name[2] = KERN_PROC_PID; 2117 name[3] = tracee; 2118 name[4] = sizeof(kp); 2119 name[5] = 1; 2120 2121 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2122 2123 if (masked) 2124 kp_sigmask = kp.p_sigmask; 2125 2126 if (ignored) 2127 kp_sigignore = kp.p_sigignore; 2128 2129 /* Resume tracee with PT_CONTINUE */ 2130 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2131 2132 /* Wait for tracee and assert that it exited */ 2133 FORKEE_REQUIRE_SUCCESS( 2134 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2135 2136 forkee_status_stopped(status, sig); 2137 2138 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 2139 "traced process\n"); 2140 SYSCALL_REQUIRE( 2141 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 2142 2143 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2144 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2145 "si_errno=%#x\n", info.psi_siginfo.si_signo, 2146 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 2147 2148 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig); 2149 2150 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2151 2152 if (masked) { 2153 DPRINTF("kp_sigmask=" 2154 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2155 PRIx32 "\n", 2156 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 2157 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 2158 2159 DPRINTF("kp.p_sigmask=" 2160 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2161 PRIx32 "\n", 2162 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 2163 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 2164 2165 FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask, 2166 sizeof(kp_sigmask))); 2167 } 2168 2169 if (ignored) { 2170 DPRINTF("kp_sigignore=" 2171 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2172 PRIx32 "\n", 2173 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 2174 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 2175 2176 DPRINTF("kp.p_sigignore=" 2177 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 2178 PRIx32 "\n", 2179 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 2180 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 2181 2182 FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore, 2183 sizeof(kp_sigignore))); 2184 } 2185 2186 switch (sig) { 2187 case SIGTRAP: 2188 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 2189 break; 2190 case SIGSEGV: 2191 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 2192 break; 2193 case SIGILL: 2194 FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC && 2195 info.psi_siginfo.si_code <= ILL_BADSTK); 2196 break; 2197 case SIGFPE: 2198 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 2199 break; 2200 case SIGBUS: 2201 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 2202 break; 2203 } 2204 2205 FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 2206 DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 2207 FORKEE_REQUIRE_SUCCESS( 2208 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2209 2210 forkee_status_signaled(status, SIGKILL, 0); 2211 2212 /* Inform parent that tracer is exiting normally */ 2213 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 2214 2215 DPRINTF("Before exiting of the tracer process\n"); 2216 _exit(0 /* collect by initproc */); 2217 } 2218 2219 DPRINTF("Wait for the tracer process (direct child) to exit " 2220 "calling %s()\n", TWAIT_FNAME); 2221 TWAIT_REQUIRE_SUCCESS( 2222 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2223 2224 validate_status_exited(status, exitval); 2225 2226 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2227 TWAIT_FNAME); 2228 TWAIT_REQUIRE_SUCCESS( 2229 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2230 2231 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2232 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2233 2234 DPRINTF("Resume the tracee and let it crash\n"); 2235 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2236 2237 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 2238 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2239 2240 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2241 TWAIT_FNAME); 2242 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2243 2244 validate_status_signaled(status, SIGKILL, 0); 2245 2246 DPRINTF("Await normal exit of tracer\n"); 2247 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 2248 2249 msg_close(&parent_tracer); 2250 msg_close(&parent_tracee); 2251} 2252 2253#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 2254ATF_TC(test); \ 2255ATF_TC_HEAD(test, tc) \ 2256{ \ 2257 atf_tc_set_md_var(tc, "descr", \ 2258 "Assert that an unrelated tracer sees crash signal from " \ 2259 "the debuggee"); \ 2260} \ 2261 \ 2262ATF_TC_BODY(test, tc) \ 2263{ \ 2264 \ 2265 unrelated_tracer_sees_crash(sig, false, false); \ 2266} 2267 2268UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 2269UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 2270UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 2271UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 2272UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 2273 2274#define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig) \ 2275ATF_TC(test); \ 2276ATF_TC_HEAD(test, tc) \ 2277{ \ 2278 atf_tc_set_md_var(tc, "descr", \ 2279 "Assert that an unrelated tracer sees crash signal from " \ 2280 "the debuggee with masked signal"); \ 2281} \ 2282 \ 2283ATF_TC_BODY(test, tc) \ 2284{ \ 2285 \ 2286 unrelated_tracer_sees_crash(sig, true, false); \ 2287} 2288 2289UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2290 unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP) 2291UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2292 unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV) 2293UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2294 unrelated_tracer_sees_signalmasked_crash_ill, SIGILL) 2295UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2296 unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE) 2297UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH( 2298 unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS) 2299 2300#define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig) \ 2301ATF_TC(test); \ 2302ATF_TC_HEAD(test, tc) \ 2303{ \ 2304 atf_tc_set_md_var(tc, "descr", \ 2305 "Assert that an unrelated tracer sees crash signal from " \ 2306 "the debuggee with signal ignored"); \ 2307} \ 2308 \ 2309ATF_TC_BODY(test, tc) \ 2310{ \ 2311 \ 2312 unrelated_tracer_sees_crash(sig, false, true); \ 2313} 2314 2315UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2316 unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP) 2317UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2318 unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV) 2319UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2320 unrelated_tracer_sees_signalignored_crash_ill, SIGILL) 2321UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2322 unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE) 2323UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH( 2324 unrelated_tracer_sees_signalignored_crash_bus, SIGBUS) 2325#endif 2326 2327/// ---------------------------------------------------------------------------- 2328 2329#if defined(TWAIT_HAVE_PID) 2330static void 2331tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 2332 bool stopped) 2333{ 2334 /* 2335 * notimeout - disable timeout in await zombie function 2336 * unrelated - attach from unrelated tracer reparented to initproc 2337 * stopped - attach to a stopped process 2338 */ 2339 2340 struct msg_fds parent_tracee, parent_tracer; 2341 const int exitval_tracee = 5; 2342 const int exitval_tracer = 10; 2343 pid_t tracee, tracer, wpid; 2344 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2345#if defined(TWAIT_HAVE_STATUS) 2346 int status; 2347#endif 2348 2349 /* 2350 * Only a subset of options are supported. 2351 */ 2352 ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 2353 (!notimeout && unrelated && !stopped) || 2354 (notimeout && !unrelated && !stopped) || 2355 (!notimeout && unrelated && stopped)); 2356 2357 DPRINTF("Spawn tracee\n"); 2358 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2359 tracee = atf_utils_fork(); 2360 if (tracee == 0) { 2361 if (stopped) { 2362 DPRINTF("Stop self PID %d\n", getpid()); 2363 raise(SIGSTOP); 2364 } 2365 2366 // Wait for parent to let us exit 2367 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2368 _exit(exitval_tracee); 2369 } 2370 2371 DPRINTF("Spawn debugger\n"); 2372 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2373 tracer = atf_utils_fork(); 2374 if (tracer == 0) { 2375 if(unrelated) { 2376 /* Fork again and drop parent to reattach to PID 1 */ 2377 tracer = atf_utils_fork(); 2378 if (tracer != 0) 2379 _exit(exitval_tracer); 2380 } 2381 2382 if (stopped) { 2383 DPRINTF("Await for a stopped parent PID %d\n", tracee); 2384 await_stopped(tracee); 2385 } 2386 2387 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2388 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2389 2390 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2391 FORKEE_REQUIRE_SUCCESS( 2392 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2393 2394 forkee_status_stopped(status, SIGSTOP); 2395 2396 /* Resume tracee with PT_CONTINUE */ 2397 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2398 2399 /* Inform parent that tracer has attached to tracee */ 2400 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2401 2402 /* Wait for parent to tell use that tracee should have exited */ 2403 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2404 2405 /* Wait for tracee and assert that it exited */ 2406 FORKEE_REQUIRE_SUCCESS( 2407 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2408 2409 forkee_status_exited(status, exitval_tracee); 2410 DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 2411 2412 DPRINTF("Before exiting of the tracer process\n"); 2413 _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 2414 } 2415 2416 if (unrelated) { 2417 DPRINTF("Wait for the tracer process (direct child) to exit " 2418 "calling %s()\n", TWAIT_FNAME); 2419 TWAIT_REQUIRE_SUCCESS( 2420 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2421 2422 validate_status_exited(status, exitval_tracer); 2423 2424 DPRINTF("Wait for the non-exited tracee process with %s()\n", 2425 TWAIT_FNAME); 2426 TWAIT_REQUIRE_SUCCESS( 2427 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 2428 } 2429 2430 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2431 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2432 2433 DPRINTF("Resume the tracee and let it exit\n"); 2434 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2435 2436 DPRINTF("Detect that tracee is zombie\n"); 2437 if (notimeout) 2438 await_zombie_raw(tracee, 0); 2439 else 2440 await_zombie(tracee); 2441 2442 DPRINTF("Assert that there is no status about tracee %d - " 2443 "Tracer must detect zombie first - calling %s()\n", tracee, 2444 TWAIT_FNAME); 2445 TWAIT_REQUIRE_SUCCESS( 2446 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2447 2448 if (unrelated) { 2449 DPRINTF("Resume the tracer and let it detect exited tracee\n"); 2450 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 2451 } else { 2452 DPRINTF("Tell the tracer child should have exited\n"); 2453 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2454 DPRINTF("Wait for tracer to finish its job and exit - calling " 2455 "%s()\n", TWAIT_FNAME); 2456 2457 DPRINTF("Wait from tracer child to complete waiting for " 2458 "tracee\n"); 2459 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2460 tracer); 2461 2462 validate_status_exited(status, exitval_tracer); 2463 } 2464 2465 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2466 TWAIT_FNAME); 2467 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2468 2469 validate_status_exited(status, exitval_tracee); 2470 2471 msg_close(&parent_tracer); 2472 msg_close(&parent_tracee); 2473} 2474 2475ATF_TC(tracer_sees_terminaton_before_the_parent); 2476ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 2477{ 2478 atf_tc_set_md_var(tc, "descr", 2479 "Assert that tracer sees process termination before the parent"); 2480} 2481 2482ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 2483{ 2484 2485 tracer_sees_terminaton_before_the_parent_raw(false, false, false); 2486} 2487 2488ATF_TC(tracer_sysctl_lookup_without_duplicates); 2489ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 2490{ 2491 atf_tc_set_md_var(tc, "descr", 2492 "Assert that await_zombie() in attach1 always finds a single " 2493 "process and no other error is reported"); 2494} 2495 2496ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 2497{ 2498 time_t start, end; 2499 double diff; 2500 unsigned long N = 0; 2501 2502 /* 2503 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 2504 * This test body isn't specific to this race, however it's just good 2505 * enough for this purposes, no need to invent a dedicated code flow. 2506 */ 2507 2508 start = time(NULL); 2509 while (true) { 2510 DPRINTF("Step: %lu\n", N); 2511 tracer_sees_terminaton_before_the_parent_raw(true, false, 2512 false); 2513 end = time(NULL); 2514 diff = difftime(end, start); 2515 if (diff >= 5.0) 2516 break; 2517 ++N; 2518 } 2519 DPRINTF("Iterations: %lu\n", N); 2520} 2521 2522ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 2523ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2524{ 2525 atf_tc_set_md_var(tc, "descr", 2526 "Assert that tracer sees process termination before the parent"); 2527} 2528 2529ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 2530{ 2531 2532 tracer_sees_terminaton_before_the_parent_raw(false, true, false); 2533} 2534 2535ATF_TC(tracer_attach_to_unrelated_stopped_process); 2536ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 2537{ 2538 atf_tc_set_md_var(tc, "descr", 2539 "Assert that tracer can attach to an unrelated stopped process"); 2540} 2541 2542ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 2543{ 2544 2545 tracer_sees_terminaton_before_the_parent_raw(false, true, true); 2546} 2547#endif 2548 2549/// ---------------------------------------------------------------------------- 2550 2551static void 2552parent_attach_to_its_child(bool stopped) 2553{ 2554 struct msg_fds parent_tracee; 2555 const int exitval_tracee = 5; 2556 pid_t tracee, wpid; 2557 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2558#if defined(TWAIT_HAVE_STATUS) 2559 int status; 2560#endif 2561 2562 DPRINTF("Spawn tracee\n"); 2563 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2564 tracee = atf_utils_fork(); 2565 if (tracee == 0) { 2566 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2567 DPRINTF("Parent should now attach to tracee\n"); 2568 2569 if (stopped) { 2570 DPRINTF("Stop self PID %d\n", getpid()); 2571 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2572 } 2573 2574 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 2575 /* Wait for message from the parent */ 2576 _exit(exitval_tracee); 2577 } 2578 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2579 2580 if (stopped) { 2581 DPRINTF("Await for a stopped tracee PID %d\n", tracee); 2582 await_stopped(tracee); 2583 } 2584 2585 DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 2586 SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2587 2588 DPRINTF("Wait for the stopped tracee process with %s()\n", 2589 TWAIT_FNAME); 2590 TWAIT_REQUIRE_SUCCESS( 2591 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2592 2593 validate_status_stopped(status, SIGSTOP); 2594 2595 DPRINTF("Resume tracee with PT_CONTINUE\n"); 2596 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2597 2598 DPRINTF("Let the tracee exit now\n"); 2599 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 2600 2601 DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 2602 TWAIT_REQUIRE_SUCCESS( 2603 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2604 2605 validate_status_exited(status, exitval_tracee); 2606 2607 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 2608 TWAIT_REQUIRE_FAILURE(ECHILD, 2609 wpid = TWAIT_GENERIC(tracee, &status, 0)); 2610 2611 msg_close(&parent_tracee); 2612} 2613 2614ATF_TC(parent_attach_to_its_child); 2615ATF_TC_HEAD(parent_attach_to_its_child, tc) 2616{ 2617 atf_tc_set_md_var(tc, "descr", 2618 "Assert that tracer parent can PT_ATTACH to its child"); 2619} 2620 2621ATF_TC_BODY(parent_attach_to_its_child, tc) 2622{ 2623 2624 parent_attach_to_its_child(false); 2625} 2626 2627ATF_TC(parent_attach_to_its_stopped_child); 2628ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 2629{ 2630 atf_tc_set_md_var(tc, "descr", 2631 "Assert that tracer parent can PT_ATTACH to its stopped child"); 2632} 2633 2634ATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 2635{ 2636 2637 parent_attach_to_its_child(true); 2638} 2639 2640/// ---------------------------------------------------------------------------- 2641 2642static void 2643child_attach_to_its_parent(bool stopped) 2644{ 2645 struct msg_fds parent_tracee; 2646 const int exitval_tracer = 5; 2647 pid_t tracer, wpid; 2648 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2649#if defined(TWAIT_HAVE_STATUS) 2650 int status; 2651#endif 2652 2653 DPRINTF("Spawn tracer\n"); 2654 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2655 tracer = atf_utils_fork(); 2656 if (tracer == 0) { 2657 /* Wait for message from the parent */ 2658 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 2659 2660 if (stopped) { 2661 DPRINTF("Await for a stopped parent PID %d\n", 2662 getppid()); 2663 await_stopped(getppid()); 2664 } 2665 2666 DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 2667 getppid()); 2668 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 2669 2670 DPRINTF("Wait for the stopped parent process with %s()\n", 2671 TWAIT_FNAME); 2672 FORKEE_REQUIRE_SUCCESS( 2673 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 2674 2675 forkee_status_stopped(status, SIGSTOP); 2676 2677 DPRINTF("Resume parent with PT_DETACH\n"); 2678 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 2679 != -1); 2680 2681 /* Tell parent we are ready */ 2682 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 2683 2684 _exit(exitval_tracer); 2685 } 2686 2687 DPRINTF("Wait for the tracer to become ready\n"); 2688 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 2689 2690 if (stopped) { 2691 DPRINTF("Stop self PID %d\n", getpid()); 2692 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 2693 } 2694 2695 DPRINTF("Allow the tracer to exit now\n"); 2696 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 2697 2698 DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 2699 TWAIT_REQUIRE_SUCCESS( 2700 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 2701 2702 validate_status_exited(status, exitval_tracer); 2703 2704 DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 2705 TWAIT_REQUIRE_FAILURE(ECHILD, 2706 wpid = TWAIT_GENERIC(tracer, &status, 0)); 2707 2708 msg_close(&parent_tracee); 2709} 2710 2711ATF_TC(child_attach_to_its_parent); 2712ATF_TC_HEAD(child_attach_to_its_parent, tc) 2713{ 2714 atf_tc_set_md_var(tc, "descr", 2715 "Assert that tracer child can PT_ATTACH to its parent"); 2716} 2717 2718ATF_TC_BODY(child_attach_to_its_parent, tc) 2719{ 2720 2721 child_attach_to_its_parent(false); 2722} 2723 2724ATF_TC(child_attach_to_its_stopped_parent); 2725ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 2726{ 2727 atf_tc_set_md_var(tc, "descr", 2728 "Assert that tracer child can PT_ATTACH to its stopped parent"); 2729} 2730 2731ATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 2732{ 2733 /* 2734 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 2735 * this causes a pipe (established from atf-run) to be broken. 2736 * atf-run uses this mechanism to monitor whether a test is alive. 2737 * 2738 * As a workaround spawn this test as a subprocess. 2739 */ 2740 2741 const int exitval = 15; 2742 pid_t child, wpid; 2743#if defined(TWAIT_HAVE_STATUS) 2744 int status; 2745#endif 2746 2747 SYSCALL_REQUIRE((child = fork()) != -1); 2748 if (child == 0) { 2749 child_attach_to_its_parent(true); 2750 _exit(exitval); 2751 } else { 2752 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2753 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2754 2755 validate_status_exited(status, exitval); 2756 2757 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 2758 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2759 } 2760} 2761 2762/// ---------------------------------------------------------------------------- 2763 2764#if defined(TWAIT_HAVE_PID) 2765 2766enum tracee_sees_its_original_parent_type { 2767 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2768 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2769 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 2770}; 2771 2772static void 2773tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 2774{ 2775 struct msg_fds parent_tracer, parent_tracee; 2776 const int exitval_tracee = 5; 2777 const int exitval_tracer = 10; 2778 pid_t parent, tracee, tracer, wpid; 2779 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 2780#if defined(TWAIT_HAVE_STATUS) 2781 int status; 2782#endif 2783 /* sysctl(3) - kinfo_proc2 */ 2784 int name[CTL_MAXNAME]; 2785 struct kinfo_proc2 kp; 2786 size_t len = sizeof(kp); 2787 unsigned int namelen; 2788 2789 /* procfs - status */ 2790 FILE *fp; 2791 struct stat st; 2792 const char *fname = "/proc/curproc/status"; 2793 char s_executable[MAXPATHLEN]; 2794 int s_pid, s_ppid; 2795 int rv; 2796 2797 if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 2798 SYSCALL_REQUIRE( 2799 (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 2800 if (rv != 0) 2801 atf_tc_skip("/proc/curproc/status not found"); 2802 } 2803 2804 DPRINTF("Spawn tracee\n"); 2805 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 2806 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 2807 tracee = atf_utils_fork(); 2808 if (tracee == 0) { 2809 parent = getppid(); 2810 2811 /* Emit message to the parent */ 2812 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 2813 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 2814 2815 switch (type) { 2816 case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 2817 FORKEE_ASSERT_EQ(parent, getppid()); 2818 break; 2819 case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 2820 namelen = 0; 2821 name[namelen++] = CTL_KERN; 2822 name[namelen++] = KERN_PROC2; 2823 name[namelen++] = KERN_PROC_PID; 2824 name[namelen++] = getpid(); 2825 name[namelen++] = len; 2826 name[namelen++] = 1; 2827 2828 FORKEE_ASSERT_EQ( 2829 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 2830 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 2831 break; 2832 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 2833 /* 2834 * Format: 2835 * EXECUTABLE PID PPID ... 2836 */ 2837 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 2838 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 2839 FORKEE_ASSERT_EQ(fclose(fp), 0); 2840 FORKEE_ASSERT_EQ(parent, s_ppid); 2841 break; 2842 } 2843 2844 _exit(exitval_tracee); 2845 } 2846 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 2847 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 2848 2849 DPRINTF("Spawn debugger\n"); 2850 tracer = atf_utils_fork(); 2851 if (tracer == 0) { 2852 /* No IPC to communicate with the child */ 2853 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2854 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2855 2856 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2857 FORKEE_REQUIRE_SUCCESS( 2858 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2859 2860 forkee_status_stopped(status, SIGSTOP); 2861 2862 /* Resume tracee with PT_CONTINUE */ 2863 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2864 2865 /* Inform parent that tracer has attached to tracee */ 2866 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2867 2868 /* Wait for parent to tell use that tracee should have exited */ 2869 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2870 2871 /* Wait for tracee and assert that it exited */ 2872 FORKEE_REQUIRE_SUCCESS( 2873 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2874 2875 forkee_status_exited(status, exitval_tracee); 2876 2877 DPRINTF("Before exiting of the tracer process\n"); 2878 _exit(exitval_tracer); 2879 } 2880 2881 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2882 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2883 2884 DPRINTF("Resume the tracee and let it exit\n"); 2885 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2886 2887 DPRINTF("Detect that tracee is zombie\n"); 2888 await_zombie(tracee); 2889 2890 DPRINTF("Assert that there is no status about tracee - " 2891 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 2892 TWAIT_REQUIRE_SUCCESS( 2893 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2894 2895 DPRINTF("Tell the tracer child should have exited\n"); 2896 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2897 2898 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 2899 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2900 tracer); 2901 2902 validate_status_exited(status, exitval_tracer); 2903 2904 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2905 TWAIT_FNAME); 2906 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 2907 tracee); 2908 2909 validate_status_exited(status, exitval_tracee); 2910 2911 msg_close(&parent_tracer); 2912 msg_close(&parent_tracee); 2913} 2914 2915#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 2916ATF_TC(test); \ 2917ATF_TC_HEAD(test, tc) \ 2918{ \ 2919 atf_tc_set_md_var(tc, "descr", \ 2920 "Assert that tracee sees its original parent when being traced " \ 2921 "(check " descr ")"); \ 2922} \ 2923 \ 2924ATF_TC_BODY(test, tc) \ 2925{ \ 2926 \ 2927 tracee_sees_its_original_parent(type); \ 2928} 2929 2930TRACEE_SEES_ITS_ORIGINAL_PARENT( 2931 tracee_sees_its_original_parent_getppid, 2932 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2933 "getppid(2)"); 2934TRACEE_SEES_ITS_ORIGINAL_PARENT( 2935 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 2936 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2937 "sysctl(3) and kinfo_proc2"); 2938TRACEE_SEES_ITS_ORIGINAL_PARENT( 2939 tracee_sees_its_original_parent_procfs_status, 2940 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 2941 "the status file in procfs"); 2942#endif 2943 2944/// ---------------------------------------------------------------------------- 2945 2946static void 2947eventmask_preserved(int event) 2948{ 2949 const int exitval = 5; 2950 const int sigval = SIGSTOP; 2951 pid_t child, wpid; 2952#if defined(TWAIT_HAVE_STATUS) 2953 int status; 2954#endif 2955 ptrace_event_t set_event, get_event; 2956 const int len = sizeof(ptrace_event_t); 2957 2958 DPRINTF("Before forking process PID=%d\n", getpid()); 2959 SYSCALL_REQUIRE((child = fork()) != -1); 2960 if (child == 0) { 2961 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2962 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2963 2964 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2965 FORKEE_ASSERT(raise(sigval) == 0); 2966 2967 DPRINTF("Before exiting of the child process\n"); 2968 _exit(exitval); 2969 } 2970 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2971 2972 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2973 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2974 2975 validate_status_stopped(status, sigval); 2976 2977 set_event.pe_set_event = event; 2978 SYSCALL_REQUIRE( 2979 ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 2980 SYSCALL_REQUIRE( 2981 ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 2982 DPRINTF("set_event=%#x get_event=%#x\n", set_event.pe_set_event, 2983 get_event.pe_set_event); 2984 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 2985 2986 DPRINTF("Before resuming the child process where it left off and " 2987 "without signal to be sent\n"); 2988 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2989 2990 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2991 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2992 2993 validate_status_exited(status, exitval); 2994 2995 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2996 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2997} 2998 2999#define EVENTMASK_PRESERVED(test, event) \ 3000ATF_TC(test); \ 3001ATF_TC_HEAD(test, tc) \ 3002{ \ 3003 atf_tc_set_md_var(tc, "descr", \ 3004 "Verify that eventmask " #event " is preserved"); \ 3005} \ 3006 \ 3007ATF_TC_BODY(test, tc) \ 3008{ \ 3009 \ 3010 eventmask_preserved(event); \ 3011} 3012 3013EVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 3014EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 3015EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 3016EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 3017EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 3018EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 3019EVENTMASK_PRESERVED(eventmask_preserved_posix_spawn, PTRACE_POSIX_SPAWN) 3020 3021/// ---------------------------------------------------------------------------- 3022 3023static void 3024fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork, 3025 bool trackvforkdone) 3026{ 3027 const int exitval = 5; 3028 const int exitval2 = 0; /* This matched exit status from /bin/echo */ 3029 const int sigval = SIGSTOP; 3030 pid_t child, child2 = 0, wpid; 3031#if defined(TWAIT_HAVE_STATUS) 3032 int status; 3033#endif 3034 ptrace_state_t state; 3035 const int slen = sizeof(state); 3036 ptrace_event_t event; 3037 const int elen = sizeof(event); 3038 3039 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 3040 3041 DPRINTF("Before forking process PID=%d\n", getpid()); 3042 SYSCALL_REQUIRE((child = fork()) != -1); 3043 if (child == 0) { 3044 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3045 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3046 3047 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3048 FORKEE_ASSERT(raise(sigval) == 0); 3049 3050 if (strcmp(fn, "spawn") == 0) { 3051 FORKEE_ASSERT_EQ(posix_spawn(&child2, 3052 arg[0], NULL, NULL, arg, NULL), 0); 3053 } else { 3054 if (strcmp(fn, "fork") == 0) { 3055 FORKEE_ASSERT((child2 = fork()) != -1); 3056 } else if (strcmp(fn, "vfork") == 0) { 3057 FORKEE_ASSERT((child2 = vfork()) != -1); 3058 } 3059 3060 if (child2 == 0) 3061 _exit(exitval2); 3062 } 3063 FORKEE_REQUIRE_SUCCESS 3064 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3065 3066 forkee_status_exited(status, exitval2); 3067 3068 DPRINTF("Before exiting of the child process\n"); 3069 _exit(exitval); 3070 } 3071 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3072 3073 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3074 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3075 3076 validate_status_stopped(status, sigval); 3077 3078 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 3079 trackspawn ? "|PTRACE_POSIX_SPAWN" : "", 3080 trackfork ? "|PTRACE_FORK" : "", 3081 trackvfork ? "|PTRACE_VFORK" : "", 3082 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 3083 event.pe_set_event = 0; 3084 if (trackspawn) 3085 event.pe_set_event |= PTRACE_POSIX_SPAWN; 3086 if (trackfork) 3087 event.pe_set_event |= PTRACE_FORK; 3088 if (trackvfork) 3089 event.pe_set_event |= PTRACE_VFORK; 3090 if (trackvforkdone) 3091 event.pe_set_event |= PTRACE_VFORK_DONE; 3092 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3093 3094 DPRINTF("Before resuming the child process where it left off and " 3095 "without signal to be sent\n"); 3096 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3097 3098#if defined(TWAIT_HAVE_PID) 3099 if ((trackspawn && strcmp(fn, "spawn") == 0) || 3100 (trackfork && strcmp(fn, "fork") == 0) || 3101 (trackvfork && strcmp(fn, "vfork") == 0)) { 3102 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 3103 child); 3104 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3105 child); 3106 3107 validate_status_stopped(status, SIGTRAP); 3108 3109 SYSCALL_REQUIRE( 3110 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3111 if (trackspawn && strcmp(fn, "spawn") == 0) { 3112 ATF_REQUIRE_EQ( 3113 state.pe_report_event & PTRACE_POSIX_SPAWN, 3114 PTRACE_POSIX_SPAWN); 3115 } 3116 if (trackfork && strcmp(fn, "fork") == 0) { 3117 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 3118 PTRACE_FORK); 3119 } 3120 if (trackvfork && strcmp(fn, "vfork") == 0) { 3121 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 3122 PTRACE_VFORK); 3123 } 3124 3125 child2 = state.pe_other_pid; 3126 DPRINTF("Reported ptrace event with forkee %d\n", child2); 3127 3128 DPRINTF("Before calling %s() for the forkee %d of the child " 3129 "%d\n", TWAIT_FNAME, child2, child); 3130 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 3131 child2); 3132 3133 validate_status_stopped(status, SIGTRAP); 3134 3135 SYSCALL_REQUIRE( 3136 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 3137 if (trackspawn && strcmp(fn, "spawn") == 0) { 3138 ATF_REQUIRE_EQ( 3139 state.pe_report_event & PTRACE_POSIX_SPAWN, 3140 PTRACE_POSIX_SPAWN); 3141 } 3142 if (trackfork && strcmp(fn, "fork") == 0) { 3143 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 3144 PTRACE_FORK); 3145 } 3146 if (trackvfork && strcmp(fn, "vfork") == 0) { 3147 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 3148 PTRACE_VFORK); 3149 } 3150 3151 ATF_REQUIRE_EQ(state.pe_other_pid, child); 3152 3153 DPRINTF("Before resuming the forkee process where it left off " 3154 "and without signal to be sent\n"); 3155 SYSCALL_REQUIRE( 3156 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 3157 3158 DPRINTF("Before resuming the child process where it left off " 3159 "and without signal to be sent\n"); 3160 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3161 } 3162#endif 3163 3164 if (trackvforkdone && strcmp(fn, "vfork") == 0) { 3165 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 3166 child); 3167 TWAIT_REQUIRE_SUCCESS( 3168 wpid = TWAIT_GENERIC(child, &status, 0), child); 3169 3170 validate_status_stopped(status, SIGTRAP); 3171 3172 SYSCALL_REQUIRE( 3173 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3174 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 3175 3176 child2 = state.pe_other_pid; 3177 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 3178 child2); 3179 3180 DPRINTF("Before resuming the child process where it left off " 3181 "and without signal to be sent\n"); 3182 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3183 } 3184 3185#if defined(TWAIT_HAVE_PID) 3186 if ((trackspawn && strcmp(fn, "spawn") == 0) || 3187 (trackfork && strcmp(fn, "fork") == 0) || 3188 (trackvfork && strcmp(fn, "vfork") == 0)) { 3189 DPRINTF("Before calling %s() for the forkee - expected exited" 3190 "\n", TWAIT_FNAME); 3191 TWAIT_REQUIRE_SUCCESS( 3192 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3193 3194 validate_status_exited(status, exitval2); 3195 3196 DPRINTF("Before calling %s() for the forkee - expected no " 3197 "process\n", TWAIT_FNAME); 3198 TWAIT_REQUIRE_FAILURE(ECHILD, 3199 wpid = TWAIT_GENERIC(child2, &status, 0)); 3200 } 3201#endif 3202 3203 DPRINTF("Before calling %s() for the child - expected stopped " 3204 "SIGCHLD\n", TWAIT_FNAME); 3205 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3206 3207 validate_status_stopped(status, SIGCHLD); 3208 3209 DPRINTF("Before resuming the child process where it left off and " 3210 "without signal to be sent\n"); 3211 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3212 3213 DPRINTF("Before calling %s() for the child - expected exited\n", 3214 TWAIT_FNAME); 3215 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3216 3217 validate_status_exited(status, exitval); 3218 3219 DPRINTF("Before calling %s() for the child - expected no process\n", 3220 TWAIT_FNAME); 3221 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3222} 3223 3224#define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone) \ 3225ATF_TC(name); \ 3226ATF_TC_HEAD(name, tc) \ 3227{ \ 3228 atf_tc_set_md_var(tc, "descr", "Verify " fun "() " \ 3229 "called with 0%s%s%s%s in EVENT_MASK", \ 3230 tspawn ? "|PTRACE_POSIX_SPAWN" : "", \ 3231 tfork ? "|PTRACE_FORK" : "", \ 3232 tvfork ? "|PTRACE_VFORK" : "", \ 3233 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 3234} \ 3235 \ 3236ATF_TC_BODY(name, tc) \ 3237{ \ 3238 \ 3239 fork_body(fun, tspawn, tfork, tvfork, tvforkdone); \ 3240} 3241 3242FORK_TEST(fork1, "fork", false, false, false, false) 3243#if defined(TWAIT_HAVE_PID) 3244FORK_TEST(fork2, "fork", false, true, false, false) 3245FORK_TEST(fork3, "fork", false, false, true, false) 3246FORK_TEST(fork4, "fork", false, true, true, false) 3247#endif 3248FORK_TEST(fork5, "fork", false, false, false, true) 3249#if defined(TWAIT_HAVE_PID) 3250FORK_TEST(fork6, "fork", false, true, false, true) 3251FORK_TEST(fork7, "fork", false, false, true, true) 3252FORK_TEST(fork8, "fork", false, true, true, true) 3253#endif 3254FORK_TEST(fork9, "fork", true, false, false, false) 3255#if defined(TWAIT_HAVE_PID) 3256FORK_TEST(fork10, "fork", true, true, false, false) 3257FORK_TEST(fork11, "fork", true, false, true, false) 3258FORK_TEST(fork12, "fork", true, true, true, false) 3259#endif 3260FORK_TEST(fork13, "fork", true, false, false, true) 3261#if defined(TWAIT_HAVE_PID) 3262FORK_TEST(fork14, "fork", true, true, false, true) 3263FORK_TEST(fork15, "fork", true, false, true, true) 3264FORK_TEST(fork16, "fork", true, true, true, true) 3265#endif 3266 3267FORK_TEST(vfork1, "vfork", false, false, false, false) 3268#if defined(TWAIT_HAVE_PID) 3269FORK_TEST(vfork2, "vfork", false, true, false, false) 3270FORK_TEST(vfork3, "vfork", false, false, true, false) 3271FORK_TEST(vfork4, "vfork", false, true, true, false) 3272#endif 3273FORK_TEST(vfork5, "vfork", false, false, false, true) 3274#if defined(TWAIT_HAVE_PID) 3275FORK_TEST(vfork6, "vfork", false, true, false, true) 3276FORK_TEST(vfork7, "vfork", false, false, true, true) 3277FORK_TEST(vfork8, "vfork", false, true, true, true) 3278#endif 3279FORK_TEST(vfork9, "vfork", true, false, false, false) 3280#if defined(TWAIT_HAVE_PID) 3281FORK_TEST(vfork10, "vfork", true, true, false, false) 3282FORK_TEST(vfork11, "vfork", true, false, true, false) 3283FORK_TEST(vfork12, "vfork", true, true, true, false) 3284#endif 3285FORK_TEST(vfork13, "vfork", true, false, false, true) 3286#if defined(TWAIT_HAVE_PID) 3287FORK_TEST(vfork14, "vfork", true, true, false, true) 3288FORK_TEST(vfork15, "vfork", true, false, true, true) 3289FORK_TEST(vfork16, "vfork", true, true, true, true) 3290#endif 3291 3292FORK_TEST(posix_spawn1, "spawn", false, false, false, false) 3293FORK_TEST(posix_spawn2, "spawn", false, true, false, false) 3294FORK_TEST(posix_spawn3, "spawn", false, false, true, false) 3295FORK_TEST(posix_spawn4, "spawn", false, true, true, false) 3296FORK_TEST(posix_spawn5, "spawn", false, false, false, true) 3297FORK_TEST(posix_spawn6, "spawn", false, true, false, true) 3298FORK_TEST(posix_spawn7, "spawn", false, false, true, true) 3299FORK_TEST(posix_spawn8, "spawn", false, true, true, true) 3300#if defined(TWAIT_HAVE_PID) 3301FORK_TEST(posix_spawn9, "spawn", true, false, false, false) 3302FORK_TEST(posix_spawn10, "spawn", true, true, false, false) 3303FORK_TEST(posix_spawn11, "spawn", true, false, true, false) 3304FORK_TEST(posix_spawn12, "spawn", true, true, true, false) 3305FORK_TEST(posix_spawn13, "spawn", true, false, false, true) 3306FORK_TEST(posix_spawn14, "spawn", true, true, false, true) 3307FORK_TEST(posix_spawn15, "spawn", true, false, true, true) 3308FORK_TEST(posix_spawn16, "spawn", true, true, true, true) 3309#endif 3310 3311/// ---------------------------------------------------------------------------- 3312 3313#if defined(TWAIT_HAVE_PID) 3314static void 3315fork_detach_forker_body(const char *fn, bool kill_process) 3316{ 3317 const int exitval = 5; 3318 const int exitval2 = 0; /* Matches exit value from /bin/echo */ 3319 const int sigval = SIGSTOP; 3320 pid_t child, child2 = 0, wpid; 3321#if defined(TWAIT_HAVE_STATUS) 3322 int status; 3323#endif 3324 ptrace_state_t state; 3325 const int slen = sizeof(state); 3326 ptrace_event_t event; 3327 const int elen = sizeof(event); 3328 3329 int op; 3330 3331 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 3332 3333 DPRINTF("Before forking process PID=%d\n", getpid()); 3334 SYSCALL_REQUIRE((child = fork()) != -1); 3335 if (child == 0) { 3336 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3337 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3338 3339 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3340 FORKEE_ASSERT(raise(sigval) == 0); 3341 3342 if (strcmp(fn, "spawn") == 0) { 3343 FORKEE_ASSERT_EQ(posix_spawn(&child2, 3344 arg[0], NULL, NULL, arg, NULL), 0); 3345 } else { 3346 if (strcmp(fn, "fork") == 0) { 3347 FORKEE_ASSERT((child2 = fork()) != -1); 3348 } else { 3349 FORKEE_ASSERT((child2 = vfork()) != -1); 3350 } 3351 3352 if (child2 == 0) 3353 _exit(exitval2); 3354 } 3355 3356 FORKEE_REQUIRE_SUCCESS 3357 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3358 3359 forkee_status_exited(status, exitval2); 3360 3361 DPRINTF("Before exiting of the child process\n"); 3362 _exit(exitval); 3363 } 3364 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3365 3366 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3367 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3368 3369 validate_status_stopped(status, sigval); 3370 3371 DPRINTF("Set EVENT_MASK for the child %d\n", child); 3372 event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK 3373 | PTRACE_VFORK_DONE; 3374 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3375 3376 DPRINTF("Before resuming the child process where it left off and " 3377 "without signal to be sent\n"); 3378 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3379 3380 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child); 3381 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3382 3383 validate_status_stopped(status, SIGTRAP); 3384 3385 SYSCALL_REQUIRE( 3386 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3387 3388 if (strcmp(fn, "spawn") == 0) 3389 op = PTRACE_POSIX_SPAWN; 3390 else if (strcmp(fn, "fork") == 0) 3391 op = PTRACE_FORK; 3392 else 3393 op = PTRACE_VFORK; 3394 3395 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 3396 3397 child2 = state.pe_other_pid; 3398 DPRINTF("Reported ptrace event with forkee %d\n", child2); 3399 3400 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 3401 strcmp(fn, "vfork") == 0) 3402 op = kill_process ? PT_KILL : PT_DETACH; 3403 else 3404 op = PT_CONTINUE; 3405 SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1); 3406 3407 DPRINTF("Before calling %s() for the forkee %d of the child %d\n", 3408 TWAIT_FNAME, child2, child); 3409 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3410 3411 validate_status_stopped(status, SIGTRAP); 3412 3413 SYSCALL_REQUIRE( 3414 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 3415 if (strcmp(fn, "spawn") == 0) 3416 op = PTRACE_POSIX_SPAWN; 3417 else if (strcmp(fn, "fork") == 0) 3418 op = PTRACE_FORK; 3419 else 3420 op = PTRACE_VFORK; 3421 3422 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 3423 ATF_REQUIRE_EQ(state.pe_other_pid, child); 3424 3425 DPRINTF("Before resuming the forkee process where it left off " 3426 "and without signal to be sent\n"); 3427 SYSCALL_REQUIRE( 3428 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 3429 3430 if (strcmp(fn, "vforkdone") == 0) { 3431 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 3432 child); 3433 TWAIT_REQUIRE_SUCCESS( 3434 wpid = TWAIT_GENERIC(child, &status, 0), child); 3435 3436 validate_status_stopped(status, SIGTRAP); 3437 3438 SYSCALL_REQUIRE( 3439 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3440 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 3441 3442 child2 = state.pe_other_pid; 3443 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 3444 child2); 3445 3446 op = kill_process ? PT_KILL : PT_DETACH; 3447 DPRINTF("Before resuming the child process where it left off " 3448 "and without signal to be sent\n"); 3449 SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1); 3450 } 3451 3452 DPRINTF("Before calling %s() for the forkee - expected exited\n", 3453 TWAIT_FNAME); 3454 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3455 3456 validate_status_exited(status, exitval2); 3457 3458 DPRINTF("Before calling %s() for the forkee - expected no process\n", 3459 TWAIT_FNAME); 3460 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0)); 3461 3462 DPRINTF("Before calling %s() for the forkee - expected exited\n", 3463 TWAIT_FNAME); 3464 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3465 3466 if (kill_process) { 3467 validate_status_signaled(status, SIGKILL, 0); 3468 } else { 3469 validate_status_exited(status, exitval); 3470 } 3471 3472 DPRINTF("Before calling %s() for the child - expected no process\n", 3473 TWAIT_FNAME); 3474 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3475} 3476 3477#define FORK_DETACH_FORKER(name,event,kprocess) \ 3478ATF_TC(name); \ 3479ATF_TC_HEAD(name, tc) \ 3480{ \ 3481 atf_tc_set_md_var(tc, "descr", "Verify %s " event, \ 3482 kprocess ? "killed" : "detached"); \ 3483} \ 3484 \ 3485ATF_TC_BODY(name, tc) \ 3486{ \ 3487 \ 3488 fork_detach_forker_body(event, kprocess); \ 3489} 3490 3491FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false) 3492FORK_DETACH_FORKER(fork_detach_forker, "fork", false) 3493FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false) 3494FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false) 3495 3496FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true) 3497FORK_DETACH_FORKER(fork_kill_forker, "fork", true) 3498FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true) 3499FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true) 3500#endif 3501 3502/// ---------------------------------------------------------------------------- 3503 3504static void 3505traceme_vfork_fork_body(pid_t (*fn)(void)) 3506{ 3507 const int exitval = 5; 3508 const int exitval2 = 15; 3509 pid_t child, child2 = 0, wpid; 3510#if defined(TWAIT_HAVE_STATUS) 3511 int status; 3512#endif 3513 3514 DPRINTF("Before forking process PID=%d\n", getpid()); 3515 SYSCALL_REQUIRE((child = vfork()) != -1); 3516 if (child == 0) { 3517 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3518 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3519 3520 FORKEE_ASSERT((child2 = (fn)()) != -1); 3521 3522 if (child2 == 0) 3523 _exit(exitval2); 3524 3525 FORKEE_REQUIRE_SUCCESS 3526 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 3527 3528 forkee_status_exited(status, exitval2); 3529 3530 DPRINTF("Before exiting of the child process\n"); 3531 _exit(exitval); 3532 } 3533 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3534 3535 DPRINTF("Before calling %s() for the child - expected exited\n", 3536 TWAIT_FNAME); 3537 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3538 3539 validate_status_exited(status, exitval); 3540 3541 DPRINTF("Before calling %s() for the child - expected no process\n", 3542 TWAIT_FNAME); 3543 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3544} 3545 3546#define TRACEME_VFORK_FORK_TEST(name,fun) \ 3547ATF_TC(name); \ 3548ATF_TC_HEAD(name, tc) \ 3549{ \ 3550 atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) " \ 3551 "called from vfork(2)ed child"); \ 3552} \ 3553 \ 3554ATF_TC_BODY(name, tc) \ 3555{ \ 3556 \ 3557 traceme_vfork_fork_body(fun); \ 3558} 3559 3560TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork) 3561TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork) 3562 3563/// ---------------------------------------------------------------------------- 3564 3565enum bytes_transfer_type { 3566 BYTES_TRANSFER_DATA, 3567 BYTES_TRANSFER_DATAIO, 3568 BYTES_TRANSFER_TEXT, 3569 BYTES_TRANSFER_TEXTIO, 3570 BYTES_TRANSFER_AUXV 3571}; 3572 3573static int __used 3574bytes_transfer_dummy(int a, int b, int c, int d) 3575{ 3576 int e, f, g, h; 3577 3578 a *= 4; 3579 b += 3; 3580 c -= 2; 3581 d /= 1; 3582 3583 e = strtol("10", NULL, 10); 3584 f = strtol("20", NULL, 10); 3585 g = strtol("30", NULL, 10); 3586 h = strtol("40", NULL, 10); 3587 3588 return (a + b * c - d) + (e * f - g / h); 3589} 3590 3591static void 3592bytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 3593{ 3594 const int exitval = 5; 3595 const int sigval = SIGSTOP; 3596 pid_t child, wpid; 3597 bool skip = false; 3598 3599 int lookup_me = 0; 3600 uint8_t lookup_me8 = 0; 3601 uint16_t lookup_me16 = 0; 3602 uint32_t lookup_me32 = 0; 3603 uint64_t lookup_me64 = 0; 3604 3605 int magic = 0x13579246; 3606 uint8_t magic8 = 0xab; 3607 uint16_t magic16 = 0x1234; 3608 uint32_t magic32 = 0x98765432; 3609 uint64_t magic64 = 0xabcdef0123456789; 3610 3611 struct ptrace_io_desc io; 3612#if defined(TWAIT_HAVE_STATUS) 3613 int status; 3614#endif 3615 /* 513 is just enough, for the purposes of ATF it's good enough */ 3616 AuxInfo ai[513], *aip; 3617 3618 ATF_REQUIRE(size < sizeof(ai)); 3619 3620 /* Prepare variables for .TEXT transfers */ 3621 switch (type) { 3622 case BYTES_TRANSFER_TEXT: 3623 memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 3624 break; 3625 case BYTES_TRANSFER_TEXTIO: 3626 switch (size) { 3627 case 8: 3628 memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 3629 break; 3630 case 16: 3631 memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 3632 break; 3633 case 32: 3634 memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 3635 break; 3636 case 64: 3637 memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 3638 break; 3639 } 3640 break; 3641 default: 3642 break; 3643 } 3644 3645 /* Prepare variables for PIOD and AUXV transfers */ 3646 switch (type) { 3647 case BYTES_TRANSFER_TEXTIO: 3648 case BYTES_TRANSFER_DATAIO: 3649 io.piod_op = operation; 3650 switch (size) { 3651 case 8: 3652 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3653 (void *)bytes_transfer_dummy : 3654 &lookup_me8; 3655 io.piod_addr = &lookup_me8; 3656 io.piod_len = sizeof(lookup_me8); 3657 break; 3658 case 16: 3659 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3660 (void *)bytes_transfer_dummy : 3661 &lookup_me16; 3662 io.piod_addr = &lookup_me16; 3663 io.piod_len = sizeof(lookup_me16); 3664 break; 3665 case 32: 3666 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3667 (void *)bytes_transfer_dummy : 3668 &lookup_me32; 3669 io.piod_addr = &lookup_me32; 3670 io.piod_len = sizeof(lookup_me32); 3671 break; 3672 case 64: 3673 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 3674 (void *)bytes_transfer_dummy : 3675 &lookup_me64; 3676 io.piod_addr = &lookup_me64; 3677 io.piod_len = sizeof(lookup_me64); 3678 break; 3679 default: 3680 break; 3681 } 3682 break; 3683 case BYTES_TRANSFER_AUXV: 3684 io.piod_op = operation; 3685 io.piod_offs = 0; 3686 io.piod_addr = ai; 3687 io.piod_len = size; 3688 break; 3689 default: 3690 break; 3691 } 3692 3693 DPRINTF("Before forking process PID=%d\n", getpid()); 3694 SYSCALL_REQUIRE((child = fork()) != -1); 3695 if (child == 0) { 3696 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3697 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3698 3699 switch (type) { 3700 case BYTES_TRANSFER_DATA: 3701 switch (operation) { 3702 case PT_READ_D: 3703 case PT_READ_I: 3704 lookup_me = magic; 3705 break; 3706 default: 3707 break; 3708 } 3709 break; 3710 case BYTES_TRANSFER_DATAIO: 3711 switch (operation) { 3712 case PIOD_READ_D: 3713 case PIOD_READ_I: 3714 switch (size) { 3715 case 8: 3716 lookup_me8 = magic8; 3717 break; 3718 case 16: 3719 lookup_me16 = magic16; 3720 break; 3721 case 32: 3722 lookup_me32 = magic32; 3723 break; 3724 case 64: 3725 lookup_me64 = magic64; 3726 break; 3727 default: 3728 break; 3729 } 3730 break; 3731 default: 3732 break; 3733 } 3734 default: 3735 break; 3736 } 3737 3738 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3739 FORKEE_ASSERT(raise(sigval) == 0); 3740 3741 /* Handle PIOD and PT separately as operation values overlap */ 3742 switch (type) { 3743 case BYTES_TRANSFER_DATA: 3744 switch (operation) { 3745 case PT_WRITE_D: 3746 case PT_WRITE_I: 3747 FORKEE_ASSERT_EQ(lookup_me, magic); 3748 break; 3749 default: 3750 break; 3751 } 3752 break; 3753 case BYTES_TRANSFER_DATAIO: 3754 switch (operation) { 3755 case PIOD_WRITE_D: 3756 case PIOD_WRITE_I: 3757 switch (size) { 3758 case 8: 3759 FORKEE_ASSERT_EQ(lookup_me8, magic8); 3760 break; 3761 case 16: 3762 FORKEE_ASSERT_EQ(lookup_me16, magic16); 3763 break; 3764 case 32: 3765 FORKEE_ASSERT_EQ(lookup_me32, magic32); 3766 break; 3767 case 64: 3768 FORKEE_ASSERT_EQ(lookup_me64, magic64); 3769 break; 3770 default: 3771 break; 3772 } 3773 break; 3774 default: 3775 break; 3776 } 3777 break; 3778 case BYTES_TRANSFER_TEXT: 3779 FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 3780 sizeof(magic)) == 0); 3781 break; 3782 case BYTES_TRANSFER_TEXTIO: 3783 switch (size) { 3784 case 8: 3785 FORKEE_ASSERT(memcmp(&magic8, 3786 bytes_transfer_dummy, 3787 sizeof(magic8)) == 0); 3788 break; 3789 case 16: 3790 FORKEE_ASSERT(memcmp(&magic16, 3791 bytes_transfer_dummy, 3792 sizeof(magic16)) == 0); 3793 break; 3794 case 32: 3795 FORKEE_ASSERT(memcmp(&magic32, 3796 bytes_transfer_dummy, 3797 sizeof(magic32)) == 0); 3798 break; 3799 case 64: 3800 FORKEE_ASSERT(memcmp(&magic64, 3801 bytes_transfer_dummy, 3802 sizeof(magic64)) == 0); 3803 break; 3804 } 3805 break; 3806 default: 3807 break; 3808 } 3809 3810 DPRINTF("Before exiting of the child process\n"); 3811 _exit(exitval); 3812 } 3813 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3814 3815 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3816 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3817 3818 validate_status_stopped(status, sigval); 3819 3820 /* Check PaX MPROTECT */ 3821 if (!can_we_write_to_text(child)) { 3822 switch (type) { 3823 case BYTES_TRANSFER_TEXTIO: 3824 switch (operation) { 3825 case PIOD_WRITE_D: 3826 case PIOD_WRITE_I: 3827 skip = true; 3828 break; 3829 default: 3830 break; 3831 } 3832 break; 3833 case BYTES_TRANSFER_TEXT: 3834 switch (operation) { 3835 case PT_WRITE_D: 3836 case PT_WRITE_I: 3837 skip = true; 3838 break; 3839 default: 3840 break; 3841 } 3842 break; 3843 default: 3844 break; 3845 } 3846 } 3847 3848 /* Bailout cleanly killing the child process */ 3849 if (skip) { 3850 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 3851 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3852 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3853 child); 3854 3855 validate_status_signaled(status, SIGKILL, 0); 3856 3857 atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 3858 } 3859 3860 DPRINTF("Calling operation to transfer bytes between child=%d and " 3861 "parent=%d\n", child, getpid()); 3862 3863 switch (type) { 3864 case BYTES_TRANSFER_TEXTIO: 3865 case BYTES_TRANSFER_DATAIO: 3866 case BYTES_TRANSFER_AUXV: 3867 switch (operation) { 3868 case PIOD_WRITE_D: 3869 case PIOD_WRITE_I: 3870 switch (size) { 3871 case 8: 3872 lookup_me8 = magic8; 3873 break; 3874 case 16: 3875 lookup_me16 = magic16; 3876 break; 3877 case 32: 3878 lookup_me32 = magic32; 3879 break; 3880 case 64: 3881 lookup_me64 = magic64; 3882 break; 3883 default: 3884 break; 3885 } 3886 break; 3887 default: 3888 break; 3889 } 3890 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 3891 switch (operation) { 3892 case PIOD_READ_D: 3893 case PIOD_READ_I: 3894 switch (size) { 3895 case 8: 3896 ATF_REQUIRE_EQ(lookup_me8, magic8); 3897 break; 3898 case 16: 3899 ATF_REQUIRE_EQ(lookup_me16, magic16); 3900 break; 3901 case 32: 3902 ATF_REQUIRE_EQ(lookup_me32, magic32); 3903 break; 3904 case 64: 3905 ATF_REQUIRE_EQ(lookup_me64, magic64); 3906 break; 3907 default: 3908 break; 3909 } 3910 break; 3911 case PIOD_READ_AUXV: 3912 DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 3913 io.piod_len); 3914 ATF_REQUIRE(io.piod_len > 0); 3915 for (aip = ai; aip->a_type != AT_NULL; aip++) 3916 DPRINTF("a_type=%#llx a_v=%#llx\n", 3917 (long long int)aip->a_type, 3918 (long long int)aip->a_v); 3919 break; 3920 default: 3921 break; 3922 } 3923 break; 3924 case BYTES_TRANSFER_TEXT: 3925 switch (operation) { 3926 case PT_READ_D: 3927 case PT_READ_I: 3928 errno = 0; 3929 lookup_me = ptrace(operation, child, 3930 bytes_transfer_dummy, 0); 3931 ATF_REQUIRE_EQ(lookup_me, magic); 3932 SYSCALL_REQUIRE_ERRNO(errno, 0); 3933 break; 3934 case PT_WRITE_D: 3935 case PT_WRITE_I: 3936 SYSCALL_REQUIRE(ptrace(operation, child, 3937 bytes_transfer_dummy, magic) 3938 != -1); 3939 break; 3940 default: 3941 break; 3942 } 3943 break; 3944 case BYTES_TRANSFER_DATA: 3945 switch (operation) { 3946 case PT_READ_D: 3947 case PT_READ_I: 3948 errno = 0; 3949 lookup_me = ptrace(operation, child, &lookup_me, 0); 3950 ATF_REQUIRE_EQ(lookup_me, magic); 3951 SYSCALL_REQUIRE_ERRNO(errno, 0); 3952 break; 3953 case PT_WRITE_D: 3954 case PT_WRITE_I: 3955 lookup_me = magic; 3956 SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 3957 magic) != -1); 3958 break; 3959 default: 3960 break; 3961 } 3962 break; 3963 default: 3964 break; 3965 } 3966 3967 DPRINTF("Before resuming the child process where it left off and " 3968 "without signal to be sent\n"); 3969 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3970 3971 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3972 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3973 3974 validate_status_exited(status, exitval); 3975 3976 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3977 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3978} 3979 3980#define BYTES_TRANSFER(test, operation, size, type) \ 3981ATF_TC(test); \ 3982ATF_TC_HEAD(test, tc) \ 3983{ \ 3984 atf_tc_set_md_var(tc, "descr", \ 3985 "Verify bytes transfer operation" #operation " and size " #size \ 3986 " of type " #type); \ 3987} \ 3988 \ 3989ATF_TC_BODY(test, tc) \ 3990{ \ 3991 \ 3992 bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 3993} 3994 3995// DATA 3996 3997BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 3998BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 3999BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 4000BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 4001 4002BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 4003BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 4004BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 4005BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 4006 4007BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 4008BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 4009BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 4010BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 4011 4012BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 4013BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 4014BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 4015BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 4016 4017BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 4018BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 4019BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 4020BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 4021 4022// TEXT 4023 4024BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 4025BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 4026BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 4027BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 4028 4029BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 4030BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 4031BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 4032BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 4033 4034BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 4035BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 4036BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 4037BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 4038 4039BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 4040BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 4041BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 4042BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 4043 4044BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 4045BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 4046BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 4047BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 4048 4049// AUXV 4050 4051BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 4052 4053/// ---------------------------------------------------------------------------- 4054 4055static void 4056bytes_transfer_alignment(const char *operation) 4057{ 4058 const int exitval = 5; 4059 const int sigval = SIGSTOP; 4060 pid_t child, wpid; 4061#if defined(TWAIT_HAVE_STATUS) 4062 int status; 4063#endif 4064 char *buffer; 4065 int vector; 4066 size_t len; 4067 size_t i; 4068 int op; 4069 4070 struct ptrace_io_desc io; 4071 struct ptrace_siginfo info; 4072 4073 memset(&io, 0, sizeof(io)); 4074 memset(&info, 0, sizeof(info)); 4075 4076 /* Testing misaligned byte transfer crossing page boundaries */ 4077 len = sysconf(_SC_PAGESIZE) * 2; 4078 buffer = malloc(len); 4079 ATF_REQUIRE(buffer != NULL); 4080 4081 /* Initialize the buffer with random data */ 4082 for (i = 0; i < len; i++) 4083 buffer[i] = i & 0xff; 4084 4085 DPRINTF("Before forking process PID=%d\n", getpid()); 4086 SYSCALL_REQUIRE((child = fork()) != -1); 4087 if (child == 0) { 4088 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4089 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4090 4091 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4092 FORKEE_ASSERT(raise(sigval) == 0); 4093 4094 DPRINTF("Before exiting of the child process\n"); 4095 _exit(exitval); 4096 } 4097 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4098 4099 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4100 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4101 4102 validate_status_stopped(status, sigval); 4103 4104 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4105 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) 4106 != -1); 4107 4108 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4109 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4110 "si_errno=%#x\n", 4111 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4112 info.psi_siginfo.si_errno); 4113 4114 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4115 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4116 4117 if (strcmp(operation, "PT_READ_I") == 0 || 4118 strcmp(operation, "PT_READ_D") == 0) { 4119 if (strcmp(operation, "PT_READ_I")) 4120 op = PT_READ_I; 4121 else 4122 op = PT_READ_D; 4123 4124 for (i = 0; i <= (len - sizeof(int)); i++) { 4125 errno = 0; 4126 vector = ptrace(op, child, buffer + i, 0); 4127 ATF_REQUIRE_EQ(errno, 0); 4128 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int))); 4129 } 4130 } else if (strcmp(operation, "PT_WRITE_I") == 0 || 4131 strcmp(operation, "PT_WRITE_D") == 0) { 4132 if (strcmp(operation, "PT_WRITE_I")) 4133 op = PT_WRITE_I; 4134 else 4135 op = PT_WRITE_D; 4136 4137 for (i = 0; i <= (len - sizeof(int)); i++) { 4138 memcpy(&vector, buffer + i, sizeof(int)); 4139 SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector) 4140 != -1); 4141 } 4142 } else if (strcmp(operation, "PIOD_READ_I") == 0 || 4143 strcmp(operation, "PIOD_READ_D") == 0) { 4144 if (strcmp(operation, "PIOD_READ_I")) 4145 op = PIOD_READ_I; 4146 else 4147 op = PIOD_READ_D; 4148 4149 io.piod_op = op; 4150 io.piod_addr = &vector; 4151 io.piod_len = sizeof(int); 4152 4153 for (i = 0; i <= (len - sizeof(int)); i++) { 4154 io.piod_offs = buffer + i; 4155 4156 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 4157 != -1); 4158 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int))); 4159 } 4160 } else if (strcmp(operation, "PIOD_WRITE_I") == 0 || 4161 strcmp(operation, "PIOD_WRITE_D") == 0) { 4162 if (strcmp(operation, "PIOD_WRITE_I")) 4163 op = PIOD_WRITE_I; 4164 else 4165 op = PIOD_WRITE_D; 4166 4167 io.piod_op = op; 4168 io.piod_addr = &vector; 4169 io.piod_len = sizeof(int); 4170 4171 for (i = 0; i <= (len - sizeof(int)); i++) { 4172 io.piod_offs = buffer + i; 4173 4174 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 4175 != -1); 4176 } 4177 } else if (strcmp(operation, "PIOD_READ_AUXV") == 0) { 4178 io.piod_op = PIOD_READ_AUXV; 4179 io.piod_addr = &vector; 4180 io.piod_len = sizeof(int); 4181 4182 errno = 0; 4183 i = 0; 4184 /* Read the whole AUXV vector, it has no clear length */ 4185 while (io.piod_len > 0) { 4186 io.piod_offs = (void *)(intptr_t)i; 4187 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) 4188 != -1 || (io.piod_len == 0 && i > 0)); 4189 ++i; 4190 } 4191 } 4192 4193 DPRINTF("Before resuming the child process where it left off " 4194 "and without signal to be sent\n"); 4195 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4196 4197 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4198 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4199 child); 4200 4201 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4202 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4203} 4204 4205#define BYTES_TRANSFER_ALIGNMENT(test, operation) \ 4206ATF_TC(test); \ 4207ATF_TC_HEAD(test, tc) \ 4208{ \ 4209 atf_tc_set_md_var(tc, "descr", \ 4210 "Verify bytes transfer for potentially misaligned " \ 4211 "operation " operation); \ 4212} \ 4213 \ 4214ATF_TC_BODY(test, tc) \ 4215{ \ 4216 \ 4217 bytes_transfer_alignment(operation); \ 4218} 4219 4220BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I") 4221BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D") 4222BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I") 4223BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D") 4224 4225BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I") 4226BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D") 4227BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I") 4228BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D") 4229 4230BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV") 4231 4232/// ---------------------------------------------------------------------------- 4233 4234static void 4235bytes_transfer_eof(const char *operation) 4236{ 4237 const int exitval = 5; 4238 const int sigval = SIGSTOP; 4239 pid_t child, wpid; 4240#if defined(TWAIT_HAVE_STATUS) 4241 int status; 4242#endif 4243 FILE *fp; 4244 char *p; 4245 int vector; 4246 int op; 4247 4248 struct ptrace_io_desc io; 4249 struct ptrace_siginfo info; 4250 4251 memset(&io, 0, sizeof(io)); 4252 memset(&info, 0, sizeof(info)); 4253 4254 vector = 0; 4255 4256 fp = tmpfile(); 4257 ATF_REQUIRE(fp != NULL); 4258 4259 p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0); 4260 ATF_REQUIRE(p != MAP_FAILED); 4261 4262 DPRINTF("Before forking process PID=%d\n", getpid()); 4263 SYSCALL_REQUIRE((child = fork()) != -1); 4264 if (child == 0) { 4265 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4266 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4267 4268 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4269 FORKEE_ASSERT(raise(sigval) == 0); 4270 4271 DPRINTF("Before exiting of the child process\n"); 4272 _exit(exitval); 4273 } 4274 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4275 4276 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4277 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4278 4279 validate_status_stopped(status, sigval); 4280 4281 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4282 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) 4283 != -1); 4284 4285 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4286 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 4287 "si_errno=%#x\n", 4288 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4289 info.psi_siginfo.si_errno); 4290 4291 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4292 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4293 4294 if (strcmp(operation, "PT_READ_I") == 0 || 4295 strcmp(operation, "PT_READ_D") == 0) { 4296 if (strcmp(operation, "PT_READ_I")) 4297 op = PT_READ_I; 4298 else 4299 op = PT_READ_D; 4300 4301 errno = 0; 4302 SYSCALL_REQUIRE(ptrace(op, child, p, 0) == -1); 4303 ATF_REQUIRE_EQ(errno, EINVAL); 4304 } else if (strcmp(operation, "PT_WRITE_I") == 0 || 4305 strcmp(operation, "PT_WRITE_D") == 0) { 4306 if (strcmp(operation, "PT_WRITE_I")) 4307 op = PT_WRITE_I; 4308 else 4309 op = PT_WRITE_D; 4310 4311 errno = 0; 4312 SYSCALL_REQUIRE(ptrace(op, child, p, vector) == -1); 4313 ATF_REQUIRE_EQ(errno, EINVAL); 4314 } else if (strcmp(operation, "PIOD_READ_I") == 0 || 4315 strcmp(operation, "PIOD_READ_D") == 0) { 4316 if (strcmp(operation, "PIOD_READ_I")) 4317 op = PIOD_READ_I; 4318 else 4319 op = PIOD_READ_D; 4320 4321 io.piod_op = op; 4322 io.piod_addr = &vector; 4323 io.piod_len = sizeof(int); 4324 io.piod_offs = p; 4325 4326 errno = 0; 4327 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1); 4328 ATF_REQUIRE_EQ(errno, EINVAL); 4329 } else if (strcmp(operation, "PIOD_WRITE_I") == 0 || 4330 strcmp(operation, "PIOD_WRITE_D") == 0) { 4331 if (strcmp(operation, "PIOD_WRITE_I")) 4332 op = PIOD_WRITE_I; 4333 else 4334 op = PIOD_WRITE_D; 4335 4336 io.piod_op = op; 4337 io.piod_addr = &vector; 4338 io.piod_len = sizeof(int); 4339 io.piod_offs = p; 4340 4341 errno = 0; 4342 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1); 4343 ATF_REQUIRE_EQ(errno, EINVAL); 4344 } 4345 4346 DPRINTF("Before resuming the child process where it left off " 4347 "and without signal to be sent\n"); 4348 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4349 4350 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4351 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4352 child); 4353 4354 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4355 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4356} 4357 4358#define BYTES_TRANSFER_EOF(test, operation) \ 4359ATF_TC(test); \ 4360ATF_TC_HEAD(test, tc) \ 4361{ \ 4362 atf_tc_set_md_var(tc, "descr", \ 4363 "Verify bytes EOF byte transfer for the " operation \ 4364 " operation"); \ 4365} \ 4366 \ 4367ATF_TC_BODY(test, tc) \ 4368{ \ 4369 \ 4370 bytes_transfer_eof(operation); \ 4371} 4372 4373BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_i, "PT_READ_I") 4374BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_d, "PT_READ_D") 4375BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_i, "PT_WRITE_I") 4376BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_d, "PT_WRITE_D") 4377 4378BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_i, "PIOD_READ_I") 4379BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_d, "PIOD_READ_D") 4380BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_i, "PIOD_WRITE_I") 4381BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_d, "PIOD_WRITE_D") 4382 4383/// ---------------------------------------------------------------------------- 4384 4385#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 4386static void 4387access_regs(const char *regset, const char *aux) 4388{ 4389 const int exitval = 5; 4390 const int sigval = SIGSTOP; 4391 pid_t child, wpid; 4392#if defined(TWAIT_HAVE_STATUS) 4393 int status; 4394#endif 4395#if defined(HAVE_GPREGS) 4396 struct reg gpr; 4397 register_t rgstr; 4398#endif 4399#if defined(HAVE_FPREGS) 4400 struct fpreg fpr; 4401#endif 4402 4403#if !defined(HAVE_GPREGS) 4404 if (strcmp(regset, "regs") == 0) 4405 atf_tc_fail("Impossible test scenario!"); 4406#endif 4407 4408#if !defined(HAVE_FPREGS) 4409 if (strcmp(regset, "fpregs") == 0) 4410 atf_tc_fail("Impossible test scenario!"); 4411#endif 4412 4413 DPRINTF("Before forking process PID=%d\n", getpid()); 4414 SYSCALL_REQUIRE((child = fork()) != -1); 4415 if (child == 0) { 4416 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4417 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4418 4419 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4420 FORKEE_ASSERT(raise(sigval) == 0); 4421 4422 DPRINTF("Before exiting of the child process\n"); 4423 _exit(exitval); 4424 } 4425 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4426 4427 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4428 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4429 4430 validate_status_stopped(status, sigval); 4431 4432#if defined(HAVE_GPREGS) 4433 if (strcmp(regset, "regs") == 0) { 4434 DPRINTF("Call GETREGS for the child process\n"); 4435 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 4436 4437 if (strcmp(aux, "none") == 0) { 4438 DPRINTF("Retrieved registers\n"); 4439 } else if (strcmp(aux, "pc") == 0) { 4440 rgstr = PTRACE_REG_PC(&gpr); 4441 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 4442 } else if (strcmp(aux, "set_pc") == 0) { 4443 rgstr = PTRACE_REG_PC(&gpr); 4444 PTRACE_REG_SET_PC(&gpr, rgstr); 4445 } else if (strcmp(aux, "sp") == 0) { 4446 rgstr = PTRACE_REG_SP(&gpr); 4447 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 4448 } else if (strcmp(aux, "intrv") == 0) { 4449 rgstr = PTRACE_REG_INTRV(&gpr); 4450 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 4451 } else if (strcmp(aux, "setregs") == 0) { 4452 DPRINTF("Call SETREGS for the child process\n"); 4453 SYSCALL_REQUIRE( 4454 ptrace(PT_GETREGS, child, &gpr, 0) != -1); 4455 } 4456 } 4457#endif 4458 4459#if defined(HAVE_FPREGS) 4460 if (strcmp(regset, "fpregs") == 0) { 4461 DPRINTF("Call GETFPREGS for the child process\n"); 4462 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 4463 4464 if (strcmp(aux, "getfpregs") == 0) { 4465 DPRINTF("Retrieved FP registers\n"); 4466 } else if (strcmp(aux, "setfpregs") == 0) { 4467 DPRINTF("Call SETFPREGS for the child\n"); 4468 SYSCALL_REQUIRE( 4469 ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 4470 } 4471 } 4472#endif 4473 4474 DPRINTF("Before resuming the child process where it left off and " 4475 "without signal to be sent\n"); 4476 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4477 4478 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4479 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4480 4481 validate_status_exited(status, exitval); 4482 4483 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4484 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4485} 4486 4487#define ACCESS_REGS(test, regset, aux) \ 4488ATF_TC(test); \ 4489ATF_TC_HEAD(test, tc) \ 4490{ \ 4491 atf_tc_set_md_var(tc, "descr", \ 4492 "Verify " regset " with auxiliary operation: " aux); \ 4493} \ 4494 \ 4495ATF_TC_BODY(test, tc) \ 4496{ \ 4497 \ 4498 access_regs(regset, aux); \ 4499} 4500#endif 4501 4502#if defined(HAVE_GPREGS) 4503ACCESS_REGS(access_regs1, "regs", "none") 4504ACCESS_REGS(access_regs2, "regs", "pc") 4505ACCESS_REGS(access_regs3, "regs", "set_pc") 4506ACCESS_REGS(access_regs4, "regs", "sp") 4507ACCESS_REGS(access_regs5, "regs", "intrv") 4508ACCESS_REGS(access_regs6, "regs", "setregs") 4509#endif 4510#if defined(HAVE_FPREGS) 4511ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 4512ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 4513#endif 4514 4515/// ---------------------------------------------------------------------------- 4516 4517#if defined(PT_STEP) 4518static void 4519ptrace_step(int N, int setstep, bool masked, bool ignored) 4520{ 4521 const int exitval = 5; 4522 const int sigval = SIGSTOP; 4523 pid_t child, wpid; 4524#if defined(TWAIT_HAVE_STATUS) 4525 int status; 4526#endif 4527 int happy; 4528 struct sigaction sa; 4529 struct ptrace_siginfo info; 4530 sigset_t intmask; 4531 struct kinfo_proc2 kp; 4532 size_t len = sizeof(kp); 4533 4534 int name[6]; 4535 const size_t namelen = __arraycount(name); 4536 ki_sigset_t kp_sigmask; 4537 ki_sigset_t kp_sigignore; 4538 4539#if defined(__arm__) 4540 /* PT_STEP not supported on arm 32-bit */ 4541 atf_tc_expect_fail("PR kern/52119"); 4542#endif 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 if (masked) { 4551 sigemptyset(&intmask); 4552 sigaddset(&intmask, SIGTRAP); 4553 sigprocmask(SIG_BLOCK, &intmask, NULL); 4554 } 4555 4556 if (ignored) { 4557 memset(&sa, 0, sizeof(sa)); 4558 sa.sa_handler = SIG_IGN; 4559 sigemptyset(&sa.sa_mask); 4560 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 4561 } 4562 4563 happy = check_happy(999); 4564 4565 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4566 FORKEE_ASSERT(raise(sigval) == 0); 4567 4568 FORKEE_ASSERT_EQ(happy, check_happy(999)); 4569 4570 DPRINTF("Before exiting of the child process\n"); 4571 _exit(exitval); 4572 } 4573 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4574 4575 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4576 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4577 4578 validate_status_stopped(status, sigval); 4579 4580 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4581 SYSCALL_REQUIRE( 4582 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4583 4584 DPRINTF("Before checking siginfo_t\n"); 4585 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4586 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4587 4588 name[0] = CTL_KERN, 4589 name[1] = KERN_PROC2, 4590 name[2] = KERN_PROC_PID; 4591 name[3] = child; 4592 name[4] = sizeof(kp); 4593 name[5] = 1; 4594 4595 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 4596 4597 if (masked) 4598 kp_sigmask = kp.p_sigmask; 4599 4600 if (ignored) 4601 kp_sigignore = kp.p_sigignore; 4602 4603 while (N --> 0) { 4604 if (setstep) { 4605 DPRINTF("Before resuming the child process where it " 4606 "left off and without signal to be sent (use " 4607 "PT_SETSTEP and PT_CONTINUE)\n"); 4608 SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 4609 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 4610 != -1); 4611 } else { 4612 DPRINTF("Before resuming the child process where it " 4613 "left off and without signal to be sent (use " 4614 "PT_STEP)\n"); 4615 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 4616 != -1); 4617 } 4618 4619 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4620 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4621 child); 4622 4623 validate_status_stopped(status, SIGTRAP); 4624 4625 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4626 SYSCALL_REQUIRE( 4627 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4628 4629 DPRINTF("Before checking siginfo_t\n"); 4630 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4631 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 4632 4633 if (setstep) { 4634 SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 4635 } 4636 4637 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 4638 4639 if (masked) { 4640 DPRINTF("kp_sigmask=" 4641 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4642 PRIx32 "\n", 4643 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 4644 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 4645 4646 DPRINTF("kp.p_sigmask=" 4647 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4648 PRIx32 "\n", 4649 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 4650 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 4651 4652 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 4653 sizeof(kp_sigmask))); 4654 } 4655 4656 if (ignored) { 4657 DPRINTF("kp_sigignore=" 4658 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4659 PRIx32 "\n", 4660 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 4661 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 4662 4663 DPRINTF("kp.p_sigignore=" 4664 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 4665 PRIx32 "\n", 4666 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 4667 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 4668 4669 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 4670 sizeof(kp_sigignore))); 4671 } 4672 } 4673 4674 DPRINTF("Before resuming the child process where it left off and " 4675 "without signal to be sent\n"); 4676 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4677 4678 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4679 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4680 4681 validate_status_exited(status, exitval); 4682 4683 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4684 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4685} 4686 4687#define PTRACE_STEP(test, N, setstep) \ 4688ATF_TC(test); \ 4689ATF_TC_HEAD(test, tc) \ 4690{ \ 4691 atf_tc_set_md_var(tc, "descr", \ 4692 "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 4693} \ 4694 \ 4695ATF_TC_BODY(test, tc) \ 4696{ \ 4697 \ 4698 ptrace_step(N, setstep, false, false); \ 4699} 4700 4701PTRACE_STEP(step1, 1, 0) 4702PTRACE_STEP(step2, 2, 0) 4703PTRACE_STEP(step3, 3, 0) 4704PTRACE_STEP(step4, 4, 0) 4705PTRACE_STEP(setstep1, 1, 1) 4706PTRACE_STEP(setstep2, 2, 1) 4707PTRACE_STEP(setstep3, 3, 1) 4708PTRACE_STEP(setstep4, 4, 1) 4709 4710ATF_TC(step_signalmasked); 4711ATF_TC_HEAD(step_signalmasked, tc) 4712{ 4713 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with masked SIGTRAP"); 4714} 4715 4716ATF_TC_BODY(step_signalmasked, tc) 4717{ 4718 4719 ptrace_step(1, 0, true, false); 4720} 4721 4722ATF_TC(step_signalignored); 4723ATF_TC_HEAD(step_signalignored, tc) 4724{ 4725 atf_tc_set_md_var(tc, "descr", "Verify PT_STEP with ignored SIGTRAP"); 4726} 4727 4728ATF_TC_BODY(step_signalignored, tc) 4729{ 4730 4731 ptrace_step(1, 0, false, true); 4732} 4733#endif 4734 4735/// ---------------------------------------------------------------------------- 4736 4737static void 4738ptrace_kill(const char *type) 4739{ 4740 const int sigval = SIGSTOP; 4741 pid_t child, wpid; 4742#if defined(TWAIT_HAVE_STATUS) 4743 int status; 4744#endif 4745 4746 DPRINTF("Before forking process PID=%d\n", getpid()); 4747 SYSCALL_REQUIRE((child = fork()) != -1); 4748 if (child == 0) { 4749 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4750 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4751 4752 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4753 FORKEE_ASSERT(raise(sigval) == 0); 4754 4755 /* NOTREACHED */ 4756 FORKEE_ASSERTX(0 && 4757 "Child should be terminated by a signal from its parent"); 4758 } 4759 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4760 4761 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4762 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4763 4764 validate_status_stopped(status, sigval); 4765 4766 DPRINTF("Before killing the child process with %s\n", type); 4767 if (strcmp(type, "ptrace(PT_KILL)") == 0) { 4768 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 4769 } else if (strcmp(type, "kill(SIGKILL)") == 0) { 4770 kill(child, SIGKILL); 4771 } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 4772 setpgid(child, 0); 4773 killpg(getpgid(child), SIGKILL); 4774 } 4775 4776 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4777 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4778 4779 validate_status_signaled(status, SIGKILL, 0); 4780 4781 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4782 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4783} 4784 4785#define PTRACE_KILL(test, type) \ 4786ATF_TC(test); \ 4787ATF_TC_HEAD(test, tc) \ 4788{ \ 4789 atf_tc_set_md_var(tc, "descr", \ 4790 "Verify killing the child with " type); \ 4791} \ 4792 \ 4793ATF_TC_BODY(test, tc) \ 4794{ \ 4795 \ 4796 ptrace_kill(type); \ 4797} 4798 4799// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 4800PTRACE_KILL(kill1, "ptrace(PT_KILL)") 4801PTRACE_KILL(kill2, "kill(SIGKILL)") 4802PTRACE_KILL(kill3, "killpg(SIGKILL)") 4803 4804/// ---------------------------------------------------------------------------- 4805 4806static void * 4807get_private(void) 4808{ 4809 4810#ifdef __HAVE___LWP_GETTCB_FAST 4811 return __lwp_gettcb_fast(); 4812#elif defined(__HAVE___LWP_GETPRIVATE_FAST) 4813 return __lwp_getprivate_fast(); 4814#else 4815#error Unknown code path! 4816#endif 4817} 4818 4819static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG}; 4820 4821static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER; 4822static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER; 4823static volatile size_t lwpinfo_thread_done; 4824 4825static void * 4826lwpinfo_thread(void *arg) 4827{ 4828 sigset_t s; 4829 volatile void **tcb; 4830 4831 tcb = (volatile void **)arg; 4832 4833 *tcb = get_private(); 4834 DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self()); 4835 4836 pthread_setname_np(pthread_self(), "thread %d", 4837 (void *)(intptr_t)_lwp_self()); 4838 4839 sigemptyset(&s); 4840 pthread_mutex_lock(&lwpinfo_thread_mtx); 4841 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 4842 lwpinfo_thread_done++; 4843 pthread_sigmask(SIG_BLOCK, &s, NULL); 4844 pthread_cond_signal(&lwpinfo_thread_cnd); 4845 pthread_mutex_unlock(&lwpinfo_thread_mtx); 4846 4847 return infinite_thread(NULL); 4848} 4849 4850static void 4851traceme_lwpinfo(const size_t threads, const char *iter) 4852{ 4853 const int sigval = SIGSTOP; 4854 const int sigval2 = SIGINT; 4855 pid_t child, wpid; 4856#if defined(TWAIT_HAVE_STATUS) 4857 int status; 4858#endif 4859 struct ptrace_lwpinfo lwp = {0, 0}; 4860 struct ptrace_lwpstatus lwpstatus = {0}; 4861 struct ptrace_siginfo info; 4862 void *private; 4863 char *name; 4864 char namebuf[PL_LNAMELEN]; 4865 volatile void *tcb[4]; 4866 bool found; 4867 sigset_t s; 4868 4869 /* Maximum number of supported threads in this test */ 4870 pthread_t t[__arraycount(tcb) - 1]; 4871 size_t n, m; 4872 int rv; 4873 size_t bytes_read; 4874 4875 struct ptrace_io_desc io; 4876 sigset_t sigmask; 4877 4878 ATF_REQUIRE(__arraycount(t) >= threads); 4879 memset(tcb, 0, sizeof(tcb)); 4880 4881 DPRINTF("Before forking process PID=%d\n", getpid()); 4882 SYSCALL_REQUIRE((child = fork()) != -1); 4883 if (child == 0) { 4884 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4885 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4886 4887 tcb[0] = get_private(); 4888 DPRINTF("Storing tcb[0] = %p\n", tcb[0]); 4889 4890 pthread_setname_np(pthread_self(), "thread %d", 4891 (void *)(intptr_t)_lwp_self()); 4892 4893 sigemptyset(&s); 4894 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 4895 pthread_sigmask(SIG_BLOCK, &s, NULL); 4896 4897 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4898 FORKEE_ASSERT(raise(sigval) == 0); 4899 4900 for (n = 0; n < threads; n++) { 4901 rv = pthread_create(&t[n], NULL, lwpinfo_thread, 4902 &tcb[n + 1]); 4903 FORKEE_ASSERT(rv == 0); 4904 } 4905 4906 pthread_mutex_lock(&lwpinfo_thread_mtx); 4907 while (lwpinfo_thread_done < threads) { 4908 pthread_cond_wait(&lwpinfo_thread_cnd, 4909 &lwpinfo_thread_mtx); 4910 } 4911 pthread_mutex_unlock(&lwpinfo_thread_mtx); 4912 4913 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 4914 FORKEE_ASSERT(raise(sigval2) == 0); 4915 4916 /* NOTREACHED */ 4917 FORKEE_ASSERTX(0 && "Not reached"); 4918 } 4919 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4920 4921 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4922 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4923 4924 validate_status_stopped(status, sigval); 4925 4926 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4927 SYSCALL_REQUIRE( 4928 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4929 4930 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4931 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4932 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4933 info.psi_siginfo.si_errno); 4934 4935 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4936 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4937 4938 if (strstr(iter, "LWPINFO") != NULL) { 4939 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4940 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 4941 != -1); 4942 4943 DPRINTF("Assert that there exists a single thread only\n"); 4944 ATF_REQUIRE(lwp.pl_lwpid > 0); 4945 4946 DPRINTF("Assert that lwp thread %d received event " 4947 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 4948 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 4949 4950 if (strstr(iter, "LWPSTATUS") != NULL) { 4951 DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS " 4952 "for child\n"); 4953 lwpstatus.pl_lwpid = lwp.pl_lwpid; 4954 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus, 4955 sizeof(lwpstatus)) != -1); 4956 } 4957 4958 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4959 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 4960 != -1); 4961 4962 DPRINTF("Assert that there exists a single thread only\n"); 4963 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 4964 } else { 4965 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 4966 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 4967 sizeof(lwpstatus)) != -1); 4968 4969 DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid); 4970 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 4971 4972 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 4973 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 4974 sizeof(lwpstatus)) != -1); 4975 4976 DPRINTF("Assert that there exists a single thread only\n"); 4977 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 4978 } 4979 4980 DPRINTF("Before resuming the child process where it left off and " 4981 "without signal to be sent\n"); 4982 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4983 4984 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4985 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4986 4987 validate_status_stopped(status, sigval2); 4988 4989 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4990 SYSCALL_REQUIRE( 4991 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4992 4993 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4994 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4995 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4996 info.psi_siginfo.si_errno); 4997 4998 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 4999 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5000 5001 memset(&lwp, 0, sizeof(lwp)); 5002 memset(&lwpstatus, 0, sizeof(lwpstatus)); 5003 5004 memset(&io, 0, sizeof(io)); 5005 5006 bytes_read = 0; 5007 io.piod_op = PIOD_READ_D; 5008 io.piod_len = sizeof(tcb); 5009 5010 do { 5011 io.piod_addr = (char *)&tcb + bytes_read; 5012 io.piod_offs = io.piod_addr; 5013 5014 rv = ptrace(PT_IO, child, &io, sizeof(io)); 5015 ATF_REQUIRE(rv != -1 && io.piod_len != 0); 5016 5017 bytes_read += io.piod_len; 5018 io.piod_len = sizeof(tcb) - bytes_read; 5019 } while (bytes_read < sizeof(tcb)); 5020 5021 for (n = 0; n <= threads; n++) { 5022 if (strstr(iter, "LWPINFO") != NULL) { 5023 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5024 "child\n"); 5025 SYSCALL_REQUIRE( 5026 ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 5027 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5028 5029 DPRINTF("Assert that the thread exists\n"); 5030 ATF_REQUIRE(lwp.pl_lwpid > 0); 5031 5032 DPRINTF("Assert that lwp thread %d received expected " 5033 "event\n", lwp.pl_lwpid); 5034 FORKEE_ASSERT_EQ(lwp.pl_event, 5035 info.psi_lwpid == lwp.pl_lwpid ? 5036 PL_EVENT_SIGNAL : PL_EVENT_NONE); 5037 5038 if (strstr(iter, "LWPSTATUS") != NULL) { 5039 DPRINTF("Before calling ptrace(2) with " 5040 "PT_LWPSTATUS for child\n"); 5041 lwpstatus.pl_lwpid = lwp.pl_lwpid; 5042 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, 5043 &lwpstatus, sizeof(lwpstatus)) != -1); 5044 5045 goto check_lwpstatus; 5046 } 5047 } else { 5048 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for " 5049 "child\n"); 5050 SYSCALL_REQUIRE( 5051 ptrace(PT_LWPNEXT, child, &lwpstatus, 5052 sizeof(lwpstatus)) != -1); 5053 DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid); 5054 5055 DPRINTF("Assert that the thread exists\n"); 5056 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 5057 5058 check_lwpstatus: 5059 5060 if (strstr(iter, "pl_sigmask") != NULL) { 5061 sigmask = lwpstatus.pl_sigmask; 5062 5063 DPRINTF("Retrieved sigmask: " 5064 "%02x%02x%02x%02x\n", 5065 sigmask.__bits[0], sigmask.__bits[1], 5066 sigmask.__bits[2], sigmask.__bits[3]); 5067 5068 found = false; 5069 for (m = 0; 5070 m < __arraycount(lwpinfo_thread_sigmask); 5071 m++) { 5072 if (sigismember(&sigmask, 5073 lwpinfo_thread_sigmask[m])) { 5074 found = true; 5075 lwpinfo_thread_sigmask[m] = 0; 5076 break; 5077 } 5078 } 5079 ATF_REQUIRE(found == true); 5080 } else if (strstr(iter, "pl_name") != NULL) { 5081 name = lwpstatus.pl_name; 5082 5083 DPRINTF("Retrieved thread name: " 5084 "%s\n", name); 5085 5086 snprintf(namebuf, sizeof namebuf, "thread %d", 5087 lwpstatus.pl_lwpid); 5088 5089 ATF_REQUIRE(strcmp(name, namebuf) == 0); 5090 } else if (strstr(iter, "pl_private") != NULL) { 5091 private = lwpstatus.pl_private; 5092 5093 DPRINTF("Retrieved thread private pointer: " 5094 "%p\n", private); 5095 5096 found = false; 5097 for (m = 0; m < __arraycount(tcb); m++) { 5098 DPRINTF("Comparing %p and %p\n", 5099 private, tcb[m]); 5100 if (private == tcb[m]) { 5101 found = true; 5102 break; 5103 } 5104 } 5105 ATF_REQUIRE(found == true); 5106 } 5107 } 5108 } 5109 5110 if (strstr(iter, "LWPINFO") != NULL) { 5111 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5112 "child\n"); 5113 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5114 != -1); 5115 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5116 5117 DPRINTF("Assert that there are no more threads\n"); 5118 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 5119 } else { 5120 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5121 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5122 sizeof(lwpstatus)) != -1); 5123 5124 DPRINTF("Assert that there exists a single thread only\n"); 5125 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 5126 } 5127 5128 DPRINTF("Before resuming the child process where it left off and " 5129 "without signal to be sent\n"); 5130 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 5131 5132 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5133 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5134 5135 validate_status_signaled(status, SIGKILL, 0); 5136 5137 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5138 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5139} 5140 5141#define TRACEME_LWPINFO(test, threads, iter) \ 5142ATF_TC(test); \ 5143ATF_TC_HEAD(test, tc) \ 5144{ \ 5145 atf_tc_set_md_var(tc, "descr", \ 5146 "Verify " iter " with the child with " #threads \ 5147 " spawned extra threads"); \ 5148} \ 5149 \ 5150ATF_TC_BODY(test, tc) \ 5151{ \ 5152 \ 5153 traceme_lwpinfo(threads, iter); \ 5154} 5155 5156TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO") 5157TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO") 5158TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO") 5159TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO") 5160 5161TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS") 5162TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS") 5163TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS") 5164TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS") 5165 5166TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0, 5167 "LWPINFO+LWPSTATUS+pl_sigmask") 5168TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1, 5169 "LWPINFO+LWPSTATUS+pl_sigmask") 5170TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2, 5171 "LWPINFO+LWPSTATUS+pl_sigmask") 5172TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3, 5173 "LWPINFO+LWPSTATUS+pl_sigmask") 5174 5175TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0, 5176 "LWPINFO+LWPSTATUS+pl_name") 5177TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1, 5178 "LWPINFO+LWPSTATUS+pl_name") 5179TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2, 5180 "LWPINFO+LWPSTATUS+pl_name") 5181TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3, 5182 "LWPINFO+LWPSTATUS+pl_name") 5183 5184TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0, 5185 "LWPINFO+LWPSTATUS+pl_private") 5186TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1, 5187 "LWPINFO+LWPSTATUS+pl_private") 5188TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2, 5189 "LWPINFO+LWPSTATUS+pl_private") 5190TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3, 5191 "LWPINFO+LWPSTATUS+pl_private") 5192 5193TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT") 5194TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT") 5195TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT") 5196TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT") 5197 5198TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask") 5199TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask") 5200TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask") 5201TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask") 5202 5203TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name") 5204TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name") 5205TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name") 5206TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name") 5207 5208TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private") 5209TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private") 5210TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private") 5211TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private") 5212 5213/// ---------------------------------------------------------------------------- 5214 5215#if defined(TWAIT_HAVE_PID) 5216static void 5217attach_lwpinfo(const int threads) 5218{ 5219 const int sigval = SIGINT; 5220 struct msg_fds parent_tracee, parent_tracer; 5221 const int exitval_tracer = 10; 5222 pid_t tracee, tracer, wpid; 5223 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 5224#if defined(TWAIT_HAVE_STATUS) 5225 int status; 5226#endif 5227 struct ptrace_lwpinfo lwp = {0, 0}; 5228 struct ptrace_siginfo info; 5229 5230 /* Maximum number of supported threads in this test */ 5231 pthread_t t[3]; 5232 int n, rv; 5233 5234 DPRINTF("Spawn tracee\n"); 5235 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 5236 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 5237 tracee = atf_utils_fork(); 5238 if (tracee == 0) { 5239 /* Wait for message from the parent */ 5240 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 5241 5242 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 5243 5244 for (n = 0; n < threads; n++) { 5245 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 5246 FORKEE_ASSERT(rv == 0); 5247 } 5248 5249 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 5250 5251 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5252 FORKEE_ASSERT(raise(sigval) == 0); 5253 5254 /* NOTREACHED */ 5255 FORKEE_ASSERTX(0 && "Not reached"); 5256 } 5257 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 5258 5259 DPRINTF("Spawn debugger\n"); 5260 tracer = atf_utils_fork(); 5261 if (tracer == 0) { 5262 /* No IPC to communicate with the child */ 5263 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 5264 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 5265 5266 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 5267 FORKEE_REQUIRE_SUCCESS( 5268 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5269 5270 forkee_status_stopped(status, SIGSTOP); 5271 5272 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5273 "tracee"); 5274 FORKEE_ASSERT( 5275 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5276 5277 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5278 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5279 "si_errno=%#x\n", 5280 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5281 info.psi_siginfo.si_errno); 5282 5283 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 5284 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 5285 5286 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5287 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5288 != -1); 5289 5290 DPRINTF("Assert that there exists a thread\n"); 5291 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 5292 5293 DPRINTF("Assert that lwp thread %d received event " 5294 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 5295 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 5296 5297 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5298 "tracee\n"); 5299 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5300 != -1); 5301 5302 DPRINTF("Assert that there are no more lwp threads in " 5303 "tracee\n"); 5304 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 5305 5306 /* Resume tracee with PT_CONTINUE */ 5307 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 5308 5309 /* Inform parent that tracer has attached to tracee */ 5310 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 5311 5312 /* Wait for parent */ 5313 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 5314 5315 /* Wait for tracee and assert that it raised a signal */ 5316 FORKEE_REQUIRE_SUCCESS( 5317 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5318 5319 forkee_status_stopped(status, SIGINT); 5320 5321 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5322 "child"); 5323 FORKEE_ASSERT( 5324 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5325 5326 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5327 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5328 "si_errno=%#x\n", 5329 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5330 info.psi_siginfo.si_errno); 5331 5332 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 5333 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 5334 5335 memset(&lwp, 0, sizeof(lwp)); 5336 5337 for (n = 0; n <= threads; n++) { 5338 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5339 "child\n"); 5340 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 5341 sizeof(lwp)) != -1); 5342 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5343 5344 DPRINTF("Assert that the thread exists\n"); 5345 FORKEE_ASSERT(lwp.pl_lwpid > 0); 5346 5347 DPRINTF("Assert that lwp thread %d received expected " 5348 "event\n", lwp.pl_lwpid); 5349 FORKEE_ASSERT_EQ(lwp.pl_event, 5350 info.psi_lwpid == lwp.pl_lwpid ? 5351 PL_EVENT_SIGNAL : PL_EVENT_NONE); 5352 } 5353 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5354 "tracee\n"); 5355 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5356 != -1); 5357 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5358 5359 DPRINTF("Assert that there are no more threads\n"); 5360 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 5361 5362 DPRINTF("Before resuming the child process where it left off " 5363 "and without signal to be sent\n"); 5364 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 5365 != -1); 5366 5367 /* Wait for tracee and assert that it exited */ 5368 FORKEE_REQUIRE_SUCCESS( 5369 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5370 5371 forkee_status_signaled(status, SIGKILL, 0); 5372 5373 DPRINTF("Before exiting of the tracer process\n"); 5374 _exit(exitval_tracer); 5375 } 5376 5377 DPRINTF("Wait for the tracer to attach to the tracee\n"); 5378 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 5379 5380 DPRINTF("Resume the tracee and spawn threads\n"); 5381 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 5382 5383 DPRINTF("Resume the tracee and let it exit\n"); 5384 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 5385 5386 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 5387 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 5388 5389 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 5390 TWAIT_FNAME); 5391 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 5392 tracer); 5393 5394 validate_status_exited(status, exitval_tracer); 5395 5396 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 5397 TWAIT_FNAME); 5398 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 5399 tracee); 5400 5401 validate_status_signaled(status, SIGKILL, 0); 5402 5403 msg_close(&parent_tracer); 5404 msg_close(&parent_tracee); 5405} 5406 5407#define ATTACH_LWPINFO(test, threads) \ 5408ATF_TC(test); \ 5409ATF_TC_HEAD(test, tc) \ 5410{ \ 5411 atf_tc_set_md_var(tc, "descr", \ 5412 "Verify LWPINFO with the child with " #threads \ 5413 " spawned extra threads (tracer is not the original " \ 5414 "parent)"); \ 5415} \ 5416 \ 5417ATF_TC_BODY(test, tc) \ 5418{ \ 5419 \ 5420 attach_lwpinfo(threads); \ 5421} 5422 5423ATTACH_LWPINFO(attach_lwpinfo0, 0) 5424ATTACH_LWPINFO(attach_lwpinfo1, 1) 5425ATTACH_LWPINFO(attach_lwpinfo2, 2) 5426ATTACH_LWPINFO(attach_lwpinfo3, 3) 5427#endif 5428 5429/// ---------------------------------------------------------------------------- 5430 5431static void 5432ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 5433{ 5434 const int exitval = 5; 5435 const int sigval = SIGINT; 5436 const int sigfaked = SIGTRAP; 5437 const int sicodefaked = TRAP_BRKPT; 5438 pid_t child, wpid; 5439 struct sigaction sa; 5440#if defined(TWAIT_HAVE_STATUS) 5441 int status; 5442#endif 5443 struct ptrace_siginfo info; 5444 memset(&info, 0, sizeof(info)); 5445 5446 DPRINTF("Before forking process PID=%d\n", getpid()); 5447 SYSCALL_REQUIRE((child = fork()) != -1); 5448 if (child == 0) { 5449 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5450 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5451 5452 sa.sa_sigaction = sah; 5453 sa.sa_flags = SA_SIGINFO; 5454 sigemptyset(&sa.sa_mask); 5455 5456 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 5457 != -1); 5458 5459 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5460 FORKEE_ASSERT(raise(sigval) == 0); 5461 5462 FORKEE_ASSERT_EQ(*signal_caught, 1); 5463 5464 DPRINTF("Before exiting of the child process\n"); 5465 _exit(exitval); 5466 } 5467 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5468 5469 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5470 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5471 5472 validate_status_stopped(status, sigval); 5473 5474 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5475 SYSCALL_REQUIRE( 5476 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5477 5478 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5479 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5480 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5481 info.psi_siginfo.si_errno); 5482 5483 if (faked) { 5484 DPRINTF("Before setting new faked signal to signo=%d " 5485 "si_code=%d\n", sigfaked, sicodefaked); 5486 info.psi_siginfo.si_signo = sigfaked; 5487 info.psi_siginfo.si_code = sicodefaked; 5488 } 5489 5490 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 5491 SYSCALL_REQUIRE( 5492 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 5493 5494 if (faked) { 5495 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5496 "child\n"); 5497 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 5498 sizeof(info)) != -1); 5499 5500 DPRINTF("Before checking siginfo_t\n"); 5501 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 5502 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 5503 } 5504 5505 DPRINTF("Before resuming the child process where it left off and " 5506 "without signal to be sent\n"); 5507 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 5508 faked ? sigfaked : sigval) != -1); 5509 5510 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5511 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5512 5513 validate_status_exited(status, exitval); 5514 5515 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5516 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5517} 5518 5519#define PTRACE_SIGINFO(test, faked) \ 5520ATF_TC(test); \ 5521ATF_TC_HEAD(test, tc) \ 5522{ \ 5523 atf_tc_set_md_var(tc, "descr", \ 5524 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 5525 "with%s setting signal to new value", faked ? "" : "out"); \ 5526} \ 5527 \ 5528static int test##_caught = 0; \ 5529 \ 5530static void \ 5531test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 5532{ \ 5533 if (faked) { \ 5534 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 5535 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 5536 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 5537 } else { \ 5538 FORKEE_ASSERT_EQ(sig, SIGINT); \ 5539 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 5540 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 5541 } \ 5542 \ 5543 ++ test##_caught; \ 5544} \ 5545 \ 5546ATF_TC_BODY(test, tc) \ 5547{ \ 5548 \ 5549 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 5550} 5551 5552PTRACE_SIGINFO(siginfo_set_unmodified, false) 5553PTRACE_SIGINFO(siginfo_set_faked, true) 5554 5555/// ---------------------------------------------------------------------------- 5556 5557static void 5558traceme_exec(bool masked, bool ignored) 5559{ 5560 const int sigval = SIGTRAP; 5561 pid_t child, wpid; 5562#if defined(TWAIT_HAVE_STATUS) 5563 int status; 5564#endif 5565 struct sigaction sa; 5566 struct ptrace_siginfo info; 5567 sigset_t intmask; 5568 struct kinfo_proc2 kp; 5569 size_t len = sizeof(kp); 5570 5571 int name[6]; 5572 const size_t namelen = __arraycount(name); 5573 ki_sigset_t kp_sigmask; 5574 ki_sigset_t kp_sigignore; 5575 5576 memset(&info, 0, sizeof(info)); 5577 5578 DPRINTF("Before forking process PID=%d\n", getpid()); 5579 SYSCALL_REQUIRE((child = fork()) != -1); 5580 if (child == 0) { 5581 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5582 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5583 5584 if (masked) { 5585 sigemptyset(&intmask); 5586 sigaddset(&intmask, sigval); 5587 sigprocmask(SIG_BLOCK, &intmask, NULL); 5588 } 5589 5590 if (ignored) { 5591 memset(&sa, 0, sizeof(sa)); 5592 sa.sa_handler = SIG_IGN; 5593 sigemptyset(&sa.sa_mask); 5594 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 5595 } 5596 5597 DPRINTF("Before calling execve(2) from child\n"); 5598 execlp("/bin/echo", "/bin/echo", NULL); 5599 5600 FORKEE_ASSERT(0 && "Not reached"); 5601 } 5602 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5603 5604 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5605 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5606 5607 validate_status_stopped(status, sigval); 5608 5609 name[0] = CTL_KERN, 5610 name[1] = KERN_PROC2, 5611 name[2] = KERN_PROC_PID; 5612 name[3] = getpid(); 5613 name[4] = sizeof(kp); 5614 name[5] = 1; 5615 5616 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5617 5618 if (masked) 5619 kp_sigmask = kp.p_sigmask; 5620 5621 if (ignored) 5622 kp_sigignore = kp.p_sigignore; 5623 5624 name[3] = getpid(); 5625 5626 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5627 5628 if (masked) { 5629 DPRINTF("kp_sigmask=" 5630 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5631 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5632 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5633 5634 DPRINTF("kp.p_sigmask=" 5635 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5636 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5637 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5638 5639 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5640 sizeof(kp_sigmask))); 5641 } 5642 5643 if (ignored) { 5644 DPRINTF("kp_sigignore=" 5645 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5646 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5647 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5648 5649 DPRINTF("kp.p_sigignore=" 5650 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5651 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5652 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5653 5654 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5655 sizeof(kp_sigignore))); 5656 } 5657 5658 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5659 SYSCALL_REQUIRE( 5660 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5661 5662 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5663 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5664 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5665 info.psi_siginfo.si_errno); 5666 5667 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5668 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 5669 5670 DPRINTF("Before resuming the child process where it left off and " 5671 "without signal to be sent\n"); 5672 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5673 5674 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5675 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5676 5677 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5678 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5679} 5680 5681#define TRACEME_EXEC(test, masked, ignored) \ 5682ATF_TC(test); \ 5683ATF_TC_HEAD(test, tc) \ 5684{ \ 5685 atf_tc_set_md_var(tc, "descr", \ 5686 "Detect SIGTRAP TRAP_EXEC from " \ 5687 "child%s%s", masked ? " with masked signal" : "", \ 5688 masked ? " with ignored signal" : ""); \ 5689} \ 5690 \ 5691ATF_TC_BODY(test, tc) \ 5692{ \ 5693 \ 5694 traceme_exec(masked, ignored); \ 5695} 5696 5697TRACEME_EXEC(traceme_exec, false, false) 5698TRACEME_EXEC(traceme_signalmasked_exec, true, false) 5699TRACEME_EXEC(traceme_signalignored_exec, false, true) 5700 5701/// ---------------------------------------------------------------------------- 5702 5703#define TRACE_THREADS_NUM 100 5704 5705static volatile int done; 5706pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 5707 5708static void * 5709trace_threads_cb(void *arg __unused) 5710{ 5711 5712 pthread_mutex_lock(&trace_threads_mtx); 5713 done++; 5714 pthread_mutex_unlock(&trace_threads_mtx); 5715 5716 while (done < TRACE_THREADS_NUM) 5717 sched_yield(); 5718 5719 return NULL; 5720} 5721 5722static void 5723trace_threads(bool trace_create, bool trace_exit) 5724{ 5725 const int sigval = SIGSTOP; 5726 pid_t child, wpid; 5727#if defined(TWAIT_HAVE_STATUS) 5728 int status; 5729#endif 5730 ptrace_state_t state; 5731 const int slen = sizeof(state); 5732 ptrace_event_t event; 5733 const int elen = sizeof(event); 5734 struct ptrace_siginfo info; 5735 5736 pthread_t t[TRACE_THREADS_NUM]; 5737 int rv; 5738 size_t n; 5739 lwpid_t lid; 5740 5741 /* Track created and exited threads */ 5742 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 5743 5744 DPRINTF("Before forking process PID=%d\n", getpid()); 5745 SYSCALL_REQUIRE((child = fork()) != -1); 5746 if (child == 0) { 5747 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5748 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5749 5750 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5751 FORKEE_ASSERT(raise(sigval) == 0); 5752 5753 for (n = 0; n < __arraycount(t); n++) { 5754 rv = pthread_create(&t[n], NULL, trace_threads_cb, 5755 NULL); 5756 FORKEE_ASSERT(rv == 0); 5757 } 5758 5759 for (n = 0; n < __arraycount(t); n++) { 5760 rv = pthread_join(t[n], NULL); 5761 FORKEE_ASSERT(rv == 0); 5762 } 5763 5764 /* 5765 * There is race between _exit() and pthread_join() detaching 5766 * a thread. For simplicity kill the process after detecting 5767 * LWP events. 5768 */ 5769 while (true) 5770 continue; 5771 5772 FORKEE_ASSERT(0 && "Not reached"); 5773 } 5774 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5775 5776 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5777 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5778 5779 validate_status_stopped(status, sigval); 5780 5781 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5782 SYSCALL_REQUIRE( 5783 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5784 5785 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5786 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5787 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5788 info.psi_siginfo.si_errno); 5789 5790 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5791 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5792 5793 DPRINTF("Set LWP event mask for the child %d\n", child); 5794 memset(&event, 0, sizeof(event)); 5795 if (trace_create) 5796 event.pe_set_event |= PTRACE_LWP_CREATE; 5797 if (trace_exit) 5798 event.pe_set_event |= PTRACE_LWP_EXIT; 5799 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5800 5801 DPRINTF("Before resuming the child process where it left off and " 5802 "without signal to be sent\n"); 5803 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5804 5805 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 5806 DPRINTF("Before calling %s() for the child - expected stopped " 5807 "SIGTRAP\n", TWAIT_FNAME); 5808 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5809 child); 5810 5811 validate_status_stopped(status, SIGTRAP); 5812 5813 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5814 "child\n"); 5815 SYSCALL_REQUIRE( 5816 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5817 5818 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5819 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5820 "si_errno=%#x\n", 5821 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5822 info.psi_siginfo.si_errno); 5823 5824 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5825 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5826 5827 SYSCALL_REQUIRE( 5828 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5829 5830 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 5831 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 5832 5833 lid = state.pe_lwp; 5834 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 5835 5836 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 5837 5838 DPRINTF("Before resuming the child process where it left off " 5839 "and without signal to be sent\n"); 5840 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5841 } 5842 5843 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 5844 DPRINTF("Before calling %s() for the child - expected stopped " 5845 "SIGTRAP\n", TWAIT_FNAME); 5846 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5847 child); 5848 5849 validate_status_stopped(status, SIGTRAP); 5850 5851 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5852 "child\n"); 5853 SYSCALL_REQUIRE( 5854 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5855 5856 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5857 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5858 "si_errno=%#x\n", 5859 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5860 info.psi_siginfo.si_errno); 5861 5862 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5863 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5864 5865 SYSCALL_REQUIRE( 5866 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5867 5868 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 5869 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 5870 5871 lid = state.pe_lwp; 5872 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 5873 5874 if (trace_create) { 5875 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 5876 ATF_REQUIRE_EQ(*count, 1); 5877 *count = 0; 5878 } 5879 5880 DPRINTF("Before resuming the child process where it left off " 5881 "and without signal to be sent\n"); 5882 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5883 } 5884 5885 kill(child, SIGKILL); 5886 5887 DPRINTF("Before calling %s() for the child - expected exited\n", 5888 TWAIT_FNAME); 5889 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5890 5891 validate_status_signaled(status, SIGKILL, 0); 5892 5893 DPRINTF("Before calling %s() for the child - expected no process\n", 5894 TWAIT_FNAME); 5895 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5896} 5897 5898#define TRACE_THREADS(test, trace_create, trace_exit) \ 5899ATF_TC(test); \ 5900ATF_TC_HEAD(test, tc) \ 5901{ \ 5902 atf_tc_set_md_var(tc, "descr", \ 5903 "Verify spawning threads with%s tracing LWP create and" \ 5904 "with%s tracing LWP exit", trace_create ? "" : "out", \ 5905 trace_exit ? "" : "out"); \ 5906} \ 5907 \ 5908ATF_TC_BODY(test, tc) \ 5909{ \ 5910 \ 5911 trace_threads(trace_create, trace_exit); \ 5912} 5913 5914TRACE_THREADS(trace_thread_nolwpevents, false, false) 5915TRACE_THREADS(trace_thread_lwpexit, false, true) 5916TRACE_THREADS(trace_thread_lwpcreate, true, false) 5917TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true) 5918 5919/// ---------------------------------------------------------------------------- 5920 5921ATF_TC(signal_mask_unrelated); 5922ATF_TC_HEAD(signal_mask_unrelated, tc) 5923{ 5924 atf_tc_set_md_var(tc, "descr", 5925 "Verify that masking single unrelated signal does not stop tracer " 5926 "from catching other signals"); 5927} 5928 5929ATF_TC_BODY(signal_mask_unrelated, tc) 5930{ 5931 const int exitval = 5; 5932 const int sigval = SIGSTOP; 5933 const int sigmasked = SIGTRAP; 5934 const int signotmasked = SIGINT; 5935 pid_t child, wpid; 5936#if defined(TWAIT_HAVE_STATUS) 5937 int status; 5938#endif 5939 sigset_t intmask; 5940 5941 DPRINTF("Before forking process PID=%d\n", getpid()); 5942 SYSCALL_REQUIRE((child = fork()) != -1); 5943 if (child == 0) { 5944 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5945 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5946 5947 sigemptyset(&intmask); 5948 sigaddset(&intmask, sigmasked); 5949 sigprocmask(SIG_BLOCK, &intmask, NULL); 5950 5951 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5952 FORKEE_ASSERT(raise(sigval) == 0); 5953 5954 DPRINTF("Before raising %s from child\n", 5955 strsignal(signotmasked)); 5956 FORKEE_ASSERT(raise(signotmasked) == 0); 5957 5958 DPRINTF("Before exiting of the child process\n"); 5959 _exit(exitval); 5960 } 5961 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5962 5963 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5964 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5965 5966 validate_status_stopped(status, sigval); 5967 5968 DPRINTF("Before resuming the child process where it left off and " 5969 "without signal to be sent\n"); 5970 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5971 5972 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5973 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5974 5975 validate_status_stopped(status, signotmasked); 5976 5977 DPRINTF("Before resuming the child process where it left off and " 5978 "without signal to be sent\n"); 5979 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5980 5981 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5982 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5983 5984 validate_status_exited(status, exitval); 5985 5986 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5987 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5988} 5989 5990/// ---------------------------------------------------------------------------- 5991 5992#if defined(TWAIT_HAVE_PID) 5993static void 5994fork2_body(const char *fn, bool masked, bool ignored) 5995{ 5996 const int exitval = 5; 5997 const int exitval2 = 0; /* Match exit status from /bin/echo */ 5998 const int sigval = SIGSTOP; 5999 pid_t child, child2 = 0, wpid; 6000#if defined(TWAIT_HAVE_STATUS) 6001 int status; 6002#endif 6003 ptrace_state_t state; 6004 const int slen = sizeof(state); 6005 ptrace_event_t event; 6006 const int elen = sizeof(event); 6007 struct sigaction sa; 6008 struct ptrace_siginfo info; 6009 sigset_t intmask; 6010 struct kinfo_proc2 kp; 6011 size_t len = sizeof(kp); 6012 6013 int name[6]; 6014 const size_t namelen = __arraycount(name); 6015 ki_sigset_t kp_sigmask; 6016 ki_sigset_t kp_sigignore; 6017 6018 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 6019 6020 DPRINTF("Before forking process PID=%d\n", getpid()); 6021 SYSCALL_REQUIRE((child = fork()) != -1); 6022 if (child == 0) { 6023 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6024 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6025 6026 if (masked) { 6027 sigemptyset(&intmask); 6028 sigaddset(&intmask, SIGTRAP); 6029 sigprocmask(SIG_BLOCK, &intmask, NULL); 6030 } 6031 6032 if (ignored) { 6033 memset(&sa, 0, sizeof(sa)); 6034 sa.sa_handler = SIG_IGN; 6035 sigemptyset(&sa.sa_mask); 6036 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 6037 } 6038 6039 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6040 FORKEE_ASSERT(raise(sigval) == 0); 6041 6042 if (strcmp(fn, "spawn") == 0) { 6043 FORKEE_ASSERT_EQ(posix_spawn(&child2, 6044 arg[0], NULL, NULL, arg, NULL), 0); 6045 } else { 6046 if (strcmp(fn, "fork") == 0) { 6047 FORKEE_ASSERT((child2 = fork()) != -1); 6048 } else { 6049 FORKEE_ASSERT((child2 = vfork()) != -1); 6050 } 6051 if (child2 == 0) 6052 _exit(exitval2); 6053 } 6054 6055 FORKEE_REQUIRE_SUCCESS 6056 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6057 6058 forkee_status_exited(status, exitval2); 6059 6060 DPRINTF("Before exiting of the child process\n"); 6061 _exit(exitval); 6062 } 6063 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6064 6065 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6066 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6067 6068 validate_status_stopped(status, sigval); 6069 6070 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6071 SYSCALL_REQUIRE( 6072 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6073 6074 DPRINTF("Before checking siginfo_t\n"); 6075 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6076 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6077 6078 name[0] = CTL_KERN, 6079 name[1] = KERN_PROC2, 6080 name[2] = KERN_PROC_PID; 6081 name[3] = child; 6082 name[4] = sizeof(kp); 6083 name[5] = 1; 6084 6085 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6086 6087 if (masked) 6088 kp_sigmask = kp.p_sigmask; 6089 6090 if (ignored) 6091 kp_sigignore = kp.p_sigignore; 6092 6093 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 6094 strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "", 6095 strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "", 6096 strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "", 6097 strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child); 6098 event.pe_set_event = 0; 6099 if (strcmp(fn, "spawn") == 0) 6100 event.pe_set_event |= PTRACE_POSIX_SPAWN; 6101 if (strcmp(fn, "fork") == 0) 6102 event.pe_set_event |= PTRACE_FORK; 6103 if (strcmp(fn, "vfork") == 0) 6104 event.pe_set_event |= PTRACE_VFORK; 6105 if (strcmp(fn, "vforkdone") == 0) 6106 event.pe_set_event |= PTRACE_VFORK_DONE; 6107 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6108 6109 DPRINTF("Before resuming the child process where it left off and " 6110 "without signal to be sent\n"); 6111 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6112 6113 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6114 strcmp(fn, "vfork") == 0) { 6115 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6116 child); 6117 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6118 child); 6119 6120 validate_status_stopped(status, SIGTRAP); 6121 6122 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6123 6124 if (masked) { 6125 DPRINTF("kp_sigmask=" 6126 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6127 PRIx32 "\n", 6128 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6129 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6130 6131 DPRINTF("kp.p_sigmask=" 6132 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6133 PRIx32 "\n", 6134 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6135 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6136 6137 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6138 sizeof(kp_sigmask))); 6139 } 6140 6141 if (ignored) { 6142 DPRINTF("kp_sigignore=" 6143 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6144 PRIx32 "\n", 6145 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6146 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6147 6148 DPRINTF("kp.p_sigignore=" 6149 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6150 PRIx32 "\n", 6151 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6152 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6153 6154 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6155 sizeof(kp_sigignore))); 6156 } 6157 6158 SYSCALL_REQUIRE( 6159 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6160 if (strcmp(fn, "spawn") == 0) { 6161 ATF_REQUIRE_EQ( 6162 state.pe_report_event & PTRACE_POSIX_SPAWN, 6163 PTRACE_POSIX_SPAWN); 6164 } 6165 if (strcmp(fn, "fork") == 0) { 6166 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6167 PTRACE_FORK); 6168 } 6169 if (strcmp(fn, "vfork") == 0) { 6170 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6171 PTRACE_VFORK); 6172 } 6173 6174 child2 = state.pe_other_pid; 6175 DPRINTF("Reported ptrace event with forkee %d\n", child2); 6176 6177 DPRINTF("Before calling %s() for the forkee %d of the child " 6178 "%d\n", TWAIT_FNAME, child2, child); 6179 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 6180 child2); 6181 6182 validate_status_stopped(status, SIGTRAP); 6183 6184 name[3] = child2; 6185 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6186 6187 if (masked) { 6188 DPRINTF("kp_sigmask=" 6189 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6190 PRIx32 "\n", 6191 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6192 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6193 6194 DPRINTF("kp.p_sigmask=" 6195 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6196 PRIx32 "\n", 6197 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6198 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6199 6200 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6201 sizeof(kp_sigmask))); 6202 } 6203 6204 if (ignored) { 6205 DPRINTF("kp_sigignore=" 6206 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6207 PRIx32 "\n", 6208 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6209 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6210 6211 DPRINTF("kp.p_sigignore=" 6212 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6213 PRIx32 "\n", 6214 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6215 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6216 6217 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6218 sizeof(kp_sigignore))); 6219 } 6220 6221 SYSCALL_REQUIRE( 6222 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 6223 if (strcmp(fn, "spawn") == 0) { 6224 ATF_REQUIRE_EQ( 6225 state.pe_report_event & PTRACE_POSIX_SPAWN, 6226 PTRACE_POSIX_SPAWN); 6227 } 6228 if (strcmp(fn, "fork") == 0) { 6229 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6230 PTRACE_FORK); 6231 } 6232 if (strcmp(fn, "vfork") == 0) { 6233 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6234 PTRACE_VFORK); 6235 } 6236 6237 ATF_REQUIRE_EQ(state.pe_other_pid, child); 6238 6239 DPRINTF("Before resuming the forkee process where it left off " 6240 "and without signal to be sent\n"); 6241 SYSCALL_REQUIRE( 6242 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6243 6244 DPRINTF("Before resuming the child process where it left off " 6245 "and without signal to be sent\n"); 6246 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6247 } 6248 6249 if (strcmp(fn, "vforkdone") == 0) { 6250 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6251 child); 6252 TWAIT_REQUIRE_SUCCESS( 6253 wpid = TWAIT_GENERIC(child, &status, 0), child); 6254 6255 validate_status_stopped(status, SIGTRAP); 6256 6257 name[3] = child; 6258 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6259 6260 /* 6261 * SIGCHLD is now pending in the signal queue and 6262 * the kernel presents it to userland as a masked signal. 6263 */ 6264 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 6265 6266 if (masked) { 6267 DPRINTF("kp_sigmask=" 6268 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6269 PRIx32 "\n", 6270 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6271 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6272 6273 DPRINTF("kp.p_sigmask=" 6274 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6275 PRIx32 "\n", 6276 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6277 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6278 6279 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6280 sizeof(kp_sigmask))); 6281 } 6282 6283 if (ignored) { 6284 DPRINTF("kp_sigignore=" 6285 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6286 PRIx32 "\n", 6287 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6288 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6289 6290 DPRINTF("kp.p_sigignore=" 6291 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6292 PRIx32 "\n", 6293 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6294 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6295 6296 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6297 sizeof(kp_sigignore))); 6298 } 6299 6300 SYSCALL_REQUIRE( 6301 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6302 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6303 6304 child2 = state.pe_other_pid; 6305 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6306 child2); 6307 6308 DPRINTF("Before resuming the child process where it left off " 6309 "and without signal to be sent\n"); 6310 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6311 } 6312 6313 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6314 strcmp(fn, "vfork") == 0) { 6315 DPRINTF("Before calling %s() for the forkee - expected exited" 6316 "\n", TWAIT_FNAME); 6317 TWAIT_REQUIRE_SUCCESS( 6318 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6319 6320 validate_status_exited(status, exitval2); 6321 6322 DPRINTF("Before calling %s() for the forkee - expected no " 6323 "process\n", TWAIT_FNAME); 6324 TWAIT_REQUIRE_FAILURE(ECHILD, 6325 wpid = TWAIT_GENERIC(child2, &status, 0)); 6326 } 6327 6328 DPRINTF("Before calling %s() for the child - expected stopped " 6329 "SIGCHLD\n", TWAIT_FNAME); 6330 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6331 6332 validate_status_stopped(status, SIGCHLD); 6333 6334 DPRINTF("Before resuming the child process where it left off and " 6335 "without signal to be sent\n"); 6336 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6337 6338 DPRINTF("Before calling %s() for the child - expected exited\n", 6339 TWAIT_FNAME); 6340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6341 6342 validate_status_exited(status, exitval); 6343 6344 DPRINTF("Before calling %s() for the child - expected no process\n", 6345 TWAIT_FNAME); 6346 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6347} 6348 6349#define FORK2_TEST(name,fn,masked,ignored) \ 6350ATF_TC(name); \ 6351ATF_TC_HEAD(name, tc) \ 6352{ \ 6353 atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught " \ 6354 "regardless of signal %s%s", \ 6355 masked ? "masked" : "", ignored ? "ignored" : ""); \ 6356} \ 6357 \ 6358ATF_TC_BODY(name, tc) \ 6359{ \ 6360 \ 6361 fork2_body(fn, masked, ignored); \ 6362} 6363 6364FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false) 6365FORK2_TEST(posix_spawn_singalignored, "spawn", false, true) 6366FORK2_TEST(fork_singalmasked, "fork", true, false) 6367FORK2_TEST(fork_singalignored, "fork", false, true) 6368FORK2_TEST(vfork_singalmasked, "vfork", true, false) 6369FORK2_TEST(vfork_singalignored, "vfork", false, true) 6370FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false) 6371FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true) 6372#endif 6373 6374/// ---------------------------------------------------------------------------- 6375 6376volatile lwpid_t the_lwp_id = 0; 6377 6378static void 6379lwp_main_func(void *arg) 6380{ 6381 the_lwp_id = _lwp_self(); 6382 _lwp_exit(); 6383} 6384 6385ATF_TC(signal9); 6386ATF_TC_HEAD(signal9, tc) 6387{ 6388 atf_tc_set_md_var(tc, "descr", 6389 "Verify that masking SIGTRAP in tracee does not stop tracer from " 6390 "catching PTRACE_LWP_CREATE breakpoint"); 6391} 6392 6393ATF_TC_BODY(signal9, tc) 6394{ 6395 const int exitval = 5; 6396 const int sigval = SIGSTOP; 6397 const int sigmasked = SIGTRAP; 6398 pid_t child, wpid; 6399#if defined(TWAIT_HAVE_STATUS) 6400 int status; 6401#endif 6402 sigset_t intmask; 6403 ptrace_state_t state; 6404 const int slen = sizeof(state); 6405 ptrace_event_t event; 6406 const int elen = sizeof(event); 6407 ucontext_t uc; 6408 lwpid_t lid; 6409 static const size_t ssize = 16*1024; 6410 void *stack; 6411 6412 DPRINTF("Before forking process PID=%d\n", getpid()); 6413 SYSCALL_REQUIRE((child = fork()) != -1); 6414 if (child == 0) { 6415 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6416 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6417 6418 sigemptyset(&intmask); 6419 sigaddset(&intmask, sigmasked); 6420 sigprocmask(SIG_BLOCK, &intmask, NULL); 6421 6422 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6423 FORKEE_ASSERT(raise(sigval) == 0); 6424 6425 DPRINTF("Before allocating memory for stack in child\n"); 6426 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6427 6428 DPRINTF("Before making context for new lwp in child\n"); 6429 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 6430 6431 DPRINTF("Before creating new in child\n"); 6432 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6433 6434 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6435 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6436 6437 DPRINTF("Before verifying that reported %d and running lid %d " 6438 "are the same\n", lid, the_lwp_id); 6439 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6440 6441 DPRINTF("Before exiting of the child process\n"); 6442 _exit(exitval); 6443 } 6444 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6445 6446 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6447 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6448 6449 validate_status_stopped(status, sigval); 6450 6451 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 6452 event.pe_set_event = PTRACE_LWP_CREATE; 6453 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6454 6455 DPRINTF("Before resuming the child process where it left off and " 6456 "without signal to be sent\n"); 6457 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6458 6459 DPRINTF("Before calling %s() for the child - expected stopped " 6460 "SIGTRAP\n", TWAIT_FNAME); 6461 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6462 6463 validate_status_stopped(status, sigmasked); 6464 6465 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6466 6467 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 6468 6469 lid = state.pe_lwp; 6470 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 6471 6472 DPRINTF("Before resuming the child process where it left off and " 6473 "without signal to be sent\n"); 6474 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6475 6476 DPRINTF("Before calling %s() for the child - expected exited\n", 6477 TWAIT_FNAME); 6478 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6479 6480 validate_status_exited(status, exitval); 6481 6482 DPRINTF("Before calling %s() for the child - expected no process\n", 6483 TWAIT_FNAME); 6484 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6485} 6486 6487ATF_TC(signal10); 6488ATF_TC_HEAD(signal10, tc) 6489{ 6490 atf_tc_set_md_var(tc, "descr", 6491 "Verify that masking SIGTRAP in tracee does not stop tracer from " 6492 "catching PTRACE_LWP_EXIT breakpoint"); 6493} 6494 6495ATF_TC_BODY(signal10, tc) 6496{ 6497 const int exitval = 5; 6498 const int sigval = SIGSTOP; 6499 const int sigmasked = SIGTRAP; 6500 pid_t child, wpid; 6501#if defined(TWAIT_HAVE_STATUS) 6502 int status; 6503#endif 6504 sigset_t intmask; 6505 ptrace_state_t state; 6506 const int slen = sizeof(state); 6507 ptrace_event_t event; 6508 const int elen = sizeof(event); 6509 ucontext_t uc; 6510 lwpid_t lid; 6511 static const size_t ssize = 16*1024; 6512 void *stack; 6513 6514 DPRINTF("Before forking process PID=%d\n", getpid()); 6515 SYSCALL_REQUIRE((child = fork()) != -1); 6516 if (child == 0) { 6517 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6518 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6519 6520 sigemptyset(&intmask); 6521 sigaddset(&intmask, sigmasked); 6522 sigprocmask(SIG_BLOCK, &intmask, NULL); 6523 6524 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6525 FORKEE_ASSERT(raise(sigval) == 0); 6526 6527 DPRINTF("Before allocating memory for stack in child\n"); 6528 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6529 6530 DPRINTF("Before making context for new lwp in child\n"); 6531 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 6532 6533 DPRINTF("Before creating new in child\n"); 6534 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6535 6536 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6537 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6538 6539 DPRINTF("Before verifying that reported %d and running lid %d " 6540 "are the same\n", lid, the_lwp_id); 6541 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6542 6543 DPRINTF("Before exiting of the child process\n"); 6544 _exit(exitval); 6545 } 6546 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6547 6548 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6549 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6550 6551 validate_status_stopped(status, sigval); 6552 6553 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 6554 event.pe_set_event = PTRACE_LWP_EXIT; 6555 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6556 6557 DPRINTF("Before resuming the child process where it left off and " 6558 "without signal to be sent\n"); 6559 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6560 6561 DPRINTF("Before calling %s() for the child - expected stopped " 6562 "SIGTRAP\n", TWAIT_FNAME); 6563 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6564 6565 validate_status_stopped(status, sigmasked); 6566 6567 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6568 6569 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 6570 6571 lid = state.pe_lwp; 6572 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 6573 6574 DPRINTF("Before resuming the child process where it left off and " 6575 "without signal to be sent\n"); 6576 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6577 6578 DPRINTF("Before calling %s() for the child - expected exited\n", 6579 TWAIT_FNAME); 6580 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6581 6582 validate_status_exited(status, exitval); 6583 6584 DPRINTF("Before calling %s() for the child - expected no process\n", 6585 TWAIT_FNAME); 6586 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6587} 6588 6589static void 6590lwp_main_stop(void *arg) 6591{ 6592 the_lwp_id = _lwp_self(); 6593 6594 raise(SIGTRAP); 6595 6596 _lwp_exit(); 6597} 6598 6599ATF_TC(suspend2); 6600ATF_TC_HEAD(suspend2, tc) 6601{ 6602 atf_tc_set_md_var(tc, "descr", 6603 "Verify that the while the only thread within a process is " 6604 "suspended, the whole process cannot be unstopped"); 6605} 6606 6607ATF_TC_BODY(suspend2, tc) 6608{ 6609 const int exitval = 5; 6610 const int sigval = SIGSTOP; 6611 pid_t child, wpid; 6612#if defined(TWAIT_HAVE_STATUS) 6613 int status; 6614#endif 6615 struct ptrace_siginfo psi; 6616 6617 DPRINTF("Before forking process PID=%d\n", getpid()); 6618 SYSCALL_REQUIRE((child = fork()) != -1); 6619 if (child == 0) { 6620 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6621 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6622 6623 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6624 FORKEE_ASSERT(raise(sigval) == 0); 6625 6626 DPRINTF("Before exiting of the child process\n"); 6627 _exit(exitval); 6628 } 6629 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6630 6631 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6632 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6633 6634 validate_status_stopped(status, sigval); 6635 6636 DPRINTF("Before reading siginfo and lwpid_t\n"); 6637 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6638 6639 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6640 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6641 6642 DPRINTF("Before resuming the child process where it left off and " 6643 "without signal to be sent\n"); 6644 ATF_REQUIRE_ERRNO(EDEADLK, 6645 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 6646 6647 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6648 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6649 6650 DPRINTF("Before resuming the child process where it left off and " 6651 "without signal to be sent\n"); 6652 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6653 6654 DPRINTF("Before calling %s() for the child - expected exited\n", 6655 TWAIT_FNAME); 6656 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6657 6658 validate_status_exited(status, exitval); 6659 6660 DPRINTF("Before calling %s() for the child - expected no process\n", 6661 TWAIT_FNAME); 6662 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6663} 6664 6665ATF_TC(resume1); 6666ATF_TC_HEAD(resume1, tc) 6667{ 6668 atf_tc_set_md_var(tc, "descr", 6669 "Verify that a thread can be suspended by a debugger and later " 6670 "resumed by the debugger"); 6671} 6672 6673ATF_TC_BODY(resume1, tc) 6674{ 6675 struct msg_fds fds; 6676 const int exitval = 5; 6677 const int sigval = SIGSTOP; 6678 pid_t child, wpid; 6679 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 6680#if defined(TWAIT_HAVE_STATUS) 6681 int status; 6682#endif 6683 ucontext_t uc; 6684 lwpid_t lid; 6685 static const size_t ssize = 16*1024; 6686 void *stack; 6687 struct ptrace_lwpinfo pl; 6688 struct ptrace_siginfo psi; 6689 6690 SYSCALL_REQUIRE(msg_open(&fds) == 0); 6691 6692 DPRINTF("Before forking process PID=%d\n", getpid()); 6693 SYSCALL_REQUIRE((child = fork()) != -1); 6694 if (child == 0) { 6695 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6696 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6697 6698 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6699 FORKEE_ASSERT(raise(sigval) == 0); 6700 6701 DPRINTF("Before allocating memory for stack in child\n"); 6702 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6703 6704 DPRINTF("Before making context for new lwp in child\n"); 6705 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 6706 6707 DPRINTF("Before creating new in child\n"); 6708 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6709 6710 CHILD_TO_PARENT("Message", fds, msg); 6711 6712 raise(SIGINT); 6713 6714 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6715 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6716 6717 DPRINTF("Before verifying that reported %d and running lid %d " 6718 "are the same\n", lid, the_lwp_id); 6719 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6720 6721 DPRINTF("Before exiting of the child process\n"); 6722 _exit(exitval); 6723 } 6724 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6725 6726 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6727 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6728 6729 validate_status_stopped(status, sigval); 6730 6731 DPRINTF("Before resuming the child process where it left off and " 6732 "without signal to be sent\n"); 6733 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6734 6735 DPRINTF("Before calling %s() for the child - expected stopped " 6736 "SIGTRAP\n", TWAIT_FNAME); 6737 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6738 6739 validate_status_stopped(status, SIGTRAP); 6740 6741 DPRINTF("Before reading siginfo and lwpid_t\n"); 6742 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6743 6744 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6745 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6746 6747 PARENT_FROM_CHILD("Message", fds, msg); 6748 6749 DPRINTF("Before resuming the child process where it left off and " 6750 "without signal to be sent\n"); 6751 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6752 6753 DPRINTF("Before calling %s() for the child - expected stopped " 6754 "SIGINT\n", TWAIT_FNAME); 6755 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6756 6757 validate_status_stopped(status, SIGINT); 6758 6759 pl.pl_lwpid = 0; 6760 6761 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6762 while (pl.pl_lwpid != 0) { 6763 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6764 switch (pl.pl_lwpid) { 6765 case 1: 6766 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 6767 break; 6768 case 2: 6769 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 6770 break; 6771 } 6772 } 6773 6774 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6775 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6776 6777 DPRINTF("Before resuming the child process where it left off and " 6778 "without signal to be sent\n"); 6779 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6780 6781 DPRINTF("Before calling %s() for the child - expected exited\n", 6782 TWAIT_FNAME); 6783 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6784 6785 validate_status_exited(status, exitval); 6786 6787 DPRINTF("Before calling %s() for the child - expected no process\n", 6788 TWAIT_FNAME); 6789 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6790 6791 msg_close(&fds); 6792} 6793 6794ATF_TC(syscall1); 6795ATF_TC_HEAD(syscall1, tc) 6796{ 6797 atf_tc_set_md_var(tc, "descr", 6798 "Verify that getpid(2) can be traced with PT_SYSCALL"); 6799} 6800 6801ATF_TC_BODY(syscall1, tc) 6802{ 6803 const int exitval = 5; 6804 const int sigval = SIGSTOP; 6805 pid_t child, wpid; 6806#if defined(TWAIT_HAVE_STATUS) 6807 int status; 6808#endif 6809 struct ptrace_siginfo info; 6810 memset(&info, 0, sizeof(info)); 6811 6812 DPRINTF("Before forking process PID=%d\n", getpid()); 6813 SYSCALL_REQUIRE((child = fork()) != -1); 6814 if (child == 0) { 6815 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6816 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6817 6818 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6819 FORKEE_ASSERT(raise(sigval) == 0); 6820 6821 syscall(SYS_getpid); 6822 6823 DPRINTF("Before exiting of the child process\n"); 6824 _exit(exitval); 6825 } 6826 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6827 6828 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6829 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6830 6831 validate_status_stopped(status, sigval); 6832 6833 DPRINTF("Before resuming the child process where it left off and " 6834 "without signal to be sent\n"); 6835 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6836 6837 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6838 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6839 6840 validate_status_stopped(status, SIGTRAP); 6841 6842 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6843 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6844 6845 DPRINTF("Before checking siginfo_t and lwpid\n"); 6846 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6847 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6848 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 6849 6850 DPRINTF("Before resuming the child process where it left off and " 6851 "without signal to be sent\n"); 6852 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6853 6854 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6855 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6856 6857 validate_status_stopped(status, SIGTRAP); 6858 6859 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6860 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6861 6862 DPRINTF("Before checking siginfo_t and lwpid\n"); 6863 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6864 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6865 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 6866 6867 DPRINTF("Before resuming the child process where it left off and " 6868 "without signal to be sent\n"); 6869 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6870 6871 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6872 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6873 6874 validate_status_exited(status, exitval); 6875 6876 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6877 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6878} 6879 6880ATF_TC(syscallemu1); 6881ATF_TC_HEAD(syscallemu1, tc) 6882{ 6883 atf_tc_set_md_var(tc, "descr", 6884 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 6885} 6886 6887ATF_TC_BODY(syscallemu1, tc) 6888{ 6889 const int exitval = 5; 6890 const int sigval = SIGSTOP; 6891 pid_t child, wpid; 6892#if defined(TWAIT_HAVE_STATUS) 6893 int status; 6894#endif 6895 6896#if defined(__sparc__) && !defined(__sparc64__) 6897 /* syscallemu does not work on sparc (32-bit) */ 6898 atf_tc_expect_fail("PR kern/52166"); 6899#endif 6900 6901 DPRINTF("Before forking process PID=%d\n", getpid()); 6902 SYSCALL_REQUIRE((child = fork()) != -1); 6903 if (child == 0) { 6904 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6905 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6906 6907 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6908 FORKEE_ASSERT(raise(sigval) == 0); 6909 6910 syscall(SYS_exit, 100); 6911 6912 DPRINTF("Before exiting of the child process\n"); 6913 _exit(exitval); 6914 } 6915 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6916 6917 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6918 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6919 6920 validate_status_stopped(status, sigval); 6921 6922 DPRINTF("Before resuming the child process where it left off and " 6923 "without signal to be sent\n"); 6924 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6925 6926 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6927 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6928 6929 validate_status_stopped(status, SIGTRAP); 6930 6931 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 6932 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 6933 6934 DPRINTF("Before resuming the child process where it left off and " 6935 "without signal to be sent\n"); 6936 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6937 6938 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6939 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6940 6941 validate_status_stopped(status, SIGTRAP); 6942 6943 DPRINTF("Before resuming the child process where it left off and " 6944 "without signal to be sent\n"); 6945 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6946 6947 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6948 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6949 6950 validate_status_exited(status, exitval); 6951 6952 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6953 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6954} 6955 6956/// ---------------------------------------------------------------------------- 6957 6958static void 6959clone_body(int flags, bool trackfork, bool trackvfork, 6960 bool trackvforkdone) 6961{ 6962 const int exitval = 5; 6963 const int exitval2 = 15; 6964 const int sigval = SIGSTOP; 6965 pid_t child, child2 = 0, wpid; 6966#if defined(TWAIT_HAVE_STATUS) 6967 int status; 6968#endif 6969 ptrace_state_t state; 6970 const int slen = sizeof(state); 6971 ptrace_event_t event; 6972 const int elen = sizeof(event); 6973 6974 const size_t stack_size = 1024 * 1024; 6975 void *stack, *stack_base; 6976 6977 stack = malloc(stack_size); 6978 ATF_REQUIRE(stack != NULL); 6979 6980#ifdef __MACHINE_STACK_GROWS_UP 6981 stack_base = stack; 6982#else 6983 stack_base = (char *)stack + stack_size; 6984#endif 6985 6986 DPRINTF("Before forking process PID=%d\n", getpid()); 6987 SYSCALL_REQUIRE((child = fork()) != -1); 6988 if (child == 0) { 6989 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6990 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6991 6992 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6993 FORKEE_ASSERT(raise(sigval) == 0); 6994 6995 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 6996 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 6997 6998 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 6999 child2); 7000 7001 // XXX WALLSIG? 7002 FORKEE_REQUIRE_SUCCESS 7003 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7004 7005 forkee_status_exited(status, exitval2); 7006 7007 DPRINTF("Before exiting of the child process\n"); 7008 _exit(exitval); 7009 } 7010 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7011 7012 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7013 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7014 7015 validate_status_stopped(status, sigval); 7016 7017 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 7018 trackfork ? "|PTRACE_FORK" : "", 7019 trackvfork ? "|PTRACE_VFORK" : "", 7020 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 7021 event.pe_set_event = 0; 7022 if (trackfork) 7023 event.pe_set_event |= PTRACE_FORK; 7024 if (trackvfork) 7025 event.pe_set_event |= PTRACE_VFORK; 7026 if (trackvforkdone) 7027 event.pe_set_event |= PTRACE_VFORK_DONE; 7028 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7029 7030 DPRINTF("Before resuming the child process where it left off and " 7031 "without signal to be sent\n"); 7032 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7033 7034#if defined(TWAIT_HAVE_PID) 7035 if ((trackfork && !(flags & CLONE_VFORK)) || 7036 (trackvfork && (flags & CLONE_VFORK))) { 7037 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7038 child); 7039 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7040 child); 7041 7042 validate_status_stopped(status, SIGTRAP); 7043 7044 SYSCALL_REQUIRE( 7045 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7046 if (trackfork && !(flags & CLONE_VFORK)) { 7047 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7048 PTRACE_FORK); 7049 } 7050 if (trackvfork && (flags & CLONE_VFORK)) { 7051 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7052 PTRACE_VFORK); 7053 } 7054 7055 child2 = state.pe_other_pid; 7056 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7057 7058 DPRINTF("Before calling %s() for the forkee %d of the child " 7059 "%d\n", TWAIT_FNAME, child2, child); 7060 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7061 child2); 7062 7063 validate_status_stopped(status, SIGTRAP); 7064 7065 SYSCALL_REQUIRE( 7066 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7067 if (trackfork && !(flags & CLONE_VFORK)) { 7068 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7069 PTRACE_FORK); 7070 } 7071 if (trackvfork && (flags & CLONE_VFORK)) { 7072 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7073 PTRACE_VFORK); 7074 } 7075 7076 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7077 7078 DPRINTF("Before resuming the forkee process where it left off " 7079 "and without signal to be sent\n"); 7080 SYSCALL_REQUIRE( 7081 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7082 7083 DPRINTF("Before resuming the child process where it left off " 7084 "and without signal to be sent\n"); 7085 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7086 } 7087#endif 7088 7089 if (trackvforkdone && (flags & CLONE_VFORK)) { 7090 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7091 child); 7092 TWAIT_REQUIRE_SUCCESS( 7093 wpid = TWAIT_GENERIC(child, &status, 0), child); 7094 7095 validate_status_stopped(status, SIGTRAP); 7096 7097 SYSCALL_REQUIRE( 7098 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7099 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7100 7101 child2 = state.pe_other_pid; 7102 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7103 child2); 7104 7105 DPRINTF("Before resuming the child process where it left off " 7106 "and without signal to be sent\n"); 7107 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7108 } 7109 7110#if defined(TWAIT_HAVE_PID) 7111 if ((trackfork && !(flags & CLONE_VFORK)) || 7112 (trackvfork && (flags & CLONE_VFORK))) { 7113 DPRINTF("Before calling %s() for the forkee - expected exited" 7114 "\n", TWAIT_FNAME); 7115 TWAIT_REQUIRE_SUCCESS( 7116 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7117 7118 validate_status_exited(status, exitval2); 7119 7120 DPRINTF("Before calling %s() for the forkee - expected no " 7121 "process\n", TWAIT_FNAME); 7122 TWAIT_REQUIRE_FAILURE(ECHILD, 7123 wpid = TWAIT_GENERIC(child2, &status, 0)); 7124 } 7125#endif 7126 7127 DPRINTF("Before calling %s() for the child - expected stopped " 7128 "SIGCHLD\n", TWAIT_FNAME); 7129 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7130 7131 validate_status_stopped(status, SIGCHLD); 7132 7133 DPRINTF("Before resuming the child process where it left off and " 7134 "without signal to be sent\n"); 7135 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7136 7137 DPRINTF("Before calling %s() for the child - expected exited\n", 7138 TWAIT_FNAME); 7139 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7140 7141 validate_status_exited(status, exitval); 7142 7143 DPRINTF("Before calling %s() for the child - expected no process\n", 7144 TWAIT_FNAME); 7145 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7146} 7147 7148#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \ 7149ATF_TC(name); \ 7150ATF_TC_HEAD(name, tc) \ 7151{ \ 7152 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \ 7153 "called with 0%s%s%s in EVENT_MASK", \ 7154 #flags, \ 7155 tfork ? "|PTRACE_FORK" : "", \ 7156 tvfork ? "|PTRACE_VFORK" : "", \ 7157 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 7158} \ 7159 \ 7160ATF_TC_BODY(name, tc) \ 7161{ \ 7162 \ 7163 clone_body(flags, tfork, tvfork, tvforkdone); \ 7164} 7165 7166CLONE_TEST(clone1, 0, false, false, false) 7167#if defined(TWAIT_HAVE_PID) 7168CLONE_TEST(clone2, 0, true, false, false) 7169CLONE_TEST(clone3, 0, false, true, false) 7170CLONE_TEST(clone4, 0, true, true, false) 7171#endif 7172CLONE_TEST(clone5, 0, false, false, true) 7173#if defined(TWAIT_HAVE_PID) 7174CLONE_TEST(clone6, 0, true, false, true) 7175CLONE_TEST(clone7, 0, false, true, true) 7176CLONE_TEST(clone8, 0, true, true, true) 7177#endif 7178 7179CLONE_TEST(clone_vm1, CLONE_VM, false, false, false) 7180#if defined(TWAIT_HAVE_PID) 7181CLONE_TEST(clone_vm2, CLONE_VM, true, false, false) 7182CLONE_TEST(clone_vm3, CLONE_VM, false, true, false) 7183CLONE_TEST(clone_vm4, CLONE_VM, true, true, false) 7184#endif 7185CLONE_TEST(clone_vm5, CLONE_VM, false, false, true) 7186#if defined(TWAIT_HAVE_PID) 7187CLONE_TEST(clone_vm6, CLONE_VM, true, false, true) 7188CLONE_TEST(clone_vm7, CLONE_VM, false, true, true) 7189CLONE_TEST(clone_vm8, CLONE_VM, true, true, true) 7190#endif 7191 7192CLONE_TEST(clone_fs1, CLONE_FS, false, false, false) 7193#if defined(TWAIT_HAVE_PID) 7194CLONE_TEST(clone_fs2, CLONE_FS, true, false, false) 7195CLONE_TEST(clone_fs3, CLONE_FS, false, true, false) 7196CLONE_TEST(clone_fs4, CLONE_FS, true, true, false) 7197#endif 7198CLONE_TEST(clone_fs5, CLONE_FS, false, false, true) 7199#if defined(TWAIT_HAVE_PID) 7200CLONE_TEST(clone_fs6, CLONE_FS, true, false, true) 7201CLONE_TEST(clone_fs7, CLONE_FS, false, true, true) 7202CLONE_TEST(clone_fs8, CLONE_FS, true, true, true) 7203#endif 7204 7205CLONE_TEST(clone_files1, CLONE_FILES, false, false, false) 7206#if defined(TWAIT_HAVE_PID) 7207CLONE_TEST(clone_files2, CLONE_FILES, true, false, false) 7208CLONE_TEST(clone_files3, CLONE_FILES, false, true, false) 7209CLONE_TEST(clone_files4, CLONE_FILES, true, true, false) 7210#endif 7211CLONE_TEST(clone_files5, CLONE_FILES, false, false, true) 7212#if defined(TWAIT_HAVE_PID) 7213CLONE_TEST(clone_files6, CLONE_FILES, true, false, true) 7214CLONE_TEST(clone_files7, CLONE_FILES, false, true, true) 7215CLONE_TEST(clone_files8, CLONE_FILES, true, true, true) 7216#endif 7217 7218//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false) 7219#if defined(TWAIT_HAVE_PID) 7220//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false) 7221//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false) 7222//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false) 7223#endif 7224//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true) 7225#if defined(TWAIT_HAVE_PID) 7226//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true) 7227//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true) 7228//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true) 7229#endif 7230 7231CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false) 7232#if defined(TWAIT_HAVE_PID) 7233CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false) 7234CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false) 7235CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false) 7236#endif 7237CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true) 7238#if defined(TWAIT_HAVE_PID) 7239CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true) 7240CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true) 7241CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true) 7242#endif 7243 7244/// ---------------------------------------------------------------------------- 7245 7246#if defined(TWAIT_HAVE_PID) 7247static void 7248clone_body2(int flags, bool masked, bool ignored) 7249{ 7250 const int exitval = 5; 7251 const int exitval2 = 15; 7252 const int sigval = SIGSTOP; 7253 pid_t child, child2 = 0, wpid; 7254#if defined(TWAIT_HAVE_STATUS) 7255 int status; 7256#endif 7257 ptrace_state_t state; 7258 const int slen = sizeof(state); 7259 ptrace_event_t event; 7260 const int elen = sizeof(event); 7261 struct sigaction sa; 7262 struct ptrace_siginfo info; 7263 sigset_t intmask; 7264 struct kinfo_proc2 kp; 7265 size_t len = sizeof(kp); 7266 7267 int name[6]; 7268 const size_t namelen = __arraycount(name); 7269 ki_sigset_t kp_sigmask; 7270 ki_sigset_t kp_sigignore; 7271 7272 const size_t stack_size = 1024 * 1024; 7273 void *stack, *stack_base; 7274 7275 stack = malloc(stack_size); 7276 ATF_REQUIRE(stack != NULL); 7277 7278#ifdef __MACHINE_STACK_GROWS_UP 7279 stack_base = stack; 7280#else 7281 stack_base = (char *)stack + stack_size; 7282#endif 7283 7284 SYSCALL_REQUIRE((child = fork()) != -1); 7285 if (child == 0) { 7286 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7287 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7288 7289 if (masked) { 7290 sigemptyset(&intmask); 7291 sigaddset(&intmask, SIGTRAP); 7292 sigprocmask(SIG_BLOCK, &intmask, NULL); 7293 } 7294 7295 if (ignored) { 7296 memset(&sa, 0, sizeof(sa)); 7297 sa.sa_handler = SIG_IGN; 7298 sigemptyset(&sa.sa_mask); 7299 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 7300 } 7301 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7302 FORKEE_ASSERT(raise(sigval) == 0); 7303 7304 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7305 flags); 7306 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7307 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7308 7309 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7310 child2); 7311 7312 // XXX WALLSIG? 7313 FORKEE_REQUIRE_SUCCESS 7314 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7315 7316 forkee_status_exited(status, exitval2); 7317 7318 DPRINTF("Before exiting of the child process\n"); 7319 _exit(exitval); 7320 } 7321 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7322 7323 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7324 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7325 7326 validate_status_stopped(status, sigval); 7327 7328 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7329 SYSCALL_REQUIRE( 7330 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7331 7332 DPRINTF("Before checking siginfo_t\n"); 7333 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7334 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7335 7336 name[0] = CTL_KERN, 7337 name[1] = KERN_PROC2, 7338 name[2] = KERN_PROC_PID; 7339 name[3] = child; 7340 name[4] = sizeof(kp); 7341 name[5] = 1; 7342 7343 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7344 7345 if (masked) 7346 kp_sigmask = kp.p_sigmask; 7347 7348 if (ignored) 7349 kp_sigignore = kp.p_sigignore; 7350 7351 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in " 7352 "EVENT_MASK for the child %d\n", child); 7353 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; 7354 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7355 7356 DPRINTF("Before resuming the child process where it left off and " 7357 "without signal to be sent\n"); 7358 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7359 7360 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7361 child); 7362 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7363 child); 7364 7365 validate_status_stopped(status, SIGTRAP); 7366 7367 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7368 7369 if (masked) { 7370 DPRINTF("kp_sigmask=" 7371 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7372 PRIx32 "\n", 7373 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7374 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7375 7376 DPRINTF("kp.p_sigmask=" 7377 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7378 PRIx32 "\n", 7379 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7380 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7381 7382 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7383 sizeof(kp_sigmask))); 7384 } 7385 7386 if (ignored) { 7387 DPRINTF("kp_sigignore=" 7388 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7389 PRIx32 "\n", 7390 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7391 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7392 7393 DPRINTF("kp.p_sigignore=" 7394 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7395 PRIx32 "\n", 7396 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7397 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7398 7399 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7400 sizeof(kp_sigignore))); 7401 } 7402 7403 SYSCALL_REQUIRE( 7404 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7405 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event, 7406 child2); 7407 if (!(flags & CLONE_VFORK)) { 7408 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7409 PTRACE_FORK); 7410 } else { 7411 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7412 PTRACE_VFORK); 7413 } 7414 7415 child2 = state.pe_other_pid; 7416 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7417 7418 DPRINTF("Before calling %s() for the forkee %d of the child " 7419 "%d\n", TWAIT_FNAME, child2, child); 7420 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7421 child2); 7422 7423 validate_status_stopped(status, SIGTRAP); 7424 7425 name[3] = child2; 7426 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7427 7428 if (masked) { 7429 DPRINTF("kp_sigmask=" 7430 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7431 PRIx32 "\n", 7432 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7433 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7434 7435 DPRINTF("kp.p_sigmask=" 7436 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7437 PRIx32 "\n", 7438 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7439 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7440 7441 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7442 sizeof(kp_sigmask))); 7443 } 7444 7445 if (ignored) { 7446 DPRINTF("kp_sigignore=" 7447 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7448 PRIx32 "\n", 7449 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7450 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7451 7452 DPRINTF("kp.p_sigignore=" 7453 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7454 PRIx32 "\n", 7455 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7456 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7457 7458 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7459 sizeof(kp_sigignore))); 7460 } 7461 7462 SYSCALL_REQUIRE( 7463 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7464 if (!(flags & CLONE_VFORK)) { 7465 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7466 PTRACE_FORK); 7467 } else { 7468 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7469 PTRACE_VFORK); 7470 } 7471 7472 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7473 7474 DPRINTF("Before resuming the forkee process where it left off " 7475 "and without signal to be sent\n"); 7476 SYSCALL_REQUIRE( 7477 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7478 7479 DPRINTF("Before resuming the child process where it left off " 7480 "and without signal to be sent\n"); 7481 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7482 7483 if (flags & CLONE_VFORK) { 7484 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7485 child); 7486 TWAIT_REQUIRE_SUCCESS( 7487 wpid = TWAIT_GENERIC(child, &status, 0), child); 7488 7489 validate_status_stopped(status, SIGTRAP); 7490 7491 name[3] = child; 7492 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7493 7494 /* 7495 * SIGCHLD is now pending in the signal queue and 7496 * the kernel presents it to userland as a masked signal. 7497 */ 7498 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 7499 7500 if (masked) { 7501 DPRINTF("kp_sigmask=" 7502 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7503 PRIx32 "\n", 7504 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7505 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7506 7507 DPRINTF("kp.p_sigmask=" 7508 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7509 PRIx32 "\n", 7510 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7511 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7512 7513 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7514 sizeof(kp_sigmask))); 7515 } 7516 7517 if (ignored) { 7518 DPRINTF("kp_sigignore=" 7519 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7520 PRIx32 "\n", 7521 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7522 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7523 7524 DPRINTF("kp.p_sigignore=" 7525 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7526 PRIx32 "\n", 7527 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7528 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7529 7530 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7531 sizeof(kp_sigignore))); 7532 } 7533 7534 SYSCALL_REQUIRE( 7535 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7536 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7537 7538 child2 = state.pe_other_pid; 7539 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7540 child2); 7541 7542 DPRINTF("Before resuming the child process where it left off " 7543 "and without signal to be sent\n"); 7544 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7545 } 7546 7547 DPRINTF("Before calling %s() for the forkee - expected exited" 7548 "\n", TWAIT_FNAME); 7549 TWAIT_REQUIRE_SUCCESS( 7550 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7551 7552 validate_status_exited(status, exitval2); 7553 7554 DPRINTF("Before calling %s() for the forkee - expected no " 7555 "process\n", TWAIT_FNAME); 7556 TWAIT_REQUIRE_FAILURE(ECHILD, 7557 wpid = TWAIT_GENERIC(child2, &status, 0)); 7558 7559 DPRINTF("Before calling %s() for the child - expected stopped " 7560 "SIGCHLD\n", TWAIT_FNAME); 7561 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7562 7563 validate_status_stopped(status, SIGCHLD); 7564 7565 DPRINTF("Before resuming the child process where it left off and " 7566 "without signal to be sent\n"); 7567 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7568 7569 DPRINTF("Before calling %s() for the child - expected exited\n", 7570 TWAIT_FNAME); 7571 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7572 7573 validate_status_exited(status, exitval); 7574 7575 DPRINTF("Before calling %s() for the child - expected no process\n", 7576 TWAIT_FNAME); 7577 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7578} 7579 7580#define CLONE_TEST2(name,flags,masked,ignored) \ 7581ATF_TC(name); \ 7582ATF_TC_HEAD(name, tc) \ 7583{ \ 7584 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\ 7585 " regardless of signal %s%s", \ 7586 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \ 7587} \ 7588 \ 7589ATF_TC_BODY(name, tc) \ 7590{ \ 7591 \ 7592 clone_body2(flags, masked, ignored); \ 7593} 7594 7595CLONE_TEST2(clone_signalignored, 0, true, false) 7596CLONE_TEST2(clone_signalmasked, 0, false, true) 7597CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false) 7598CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true) 7599CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false) 7600CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true) 7601CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false) 7602CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true) 7603//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX 7604//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX 7605CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false) 7606CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true) 7607#endif 7608 7609/// ---------------------------------------------------------------------------- 7610 7611#if defined(TWAIT_HAVE_PID) 7612static void 7613traceme_vfork_clone_body(int flags) 7614{ 7615 const int exitval = 5; 7616 const int exitval2 = 15; 7617 pid_t child, child2 = 0, wpid; 7618#if defined(TWAIT_HAVE_STATUS) 7619 int status; 7620#endif 7621 7622 const size_t stack_size = 1024 * 1024; 7623 void *stack, *stack_base; 7624 7625 stack = malloc(stack_size); 7626 ATF_REQUIRE(stack != NULL); 7627 7628#ifdef __MACHINE_STACK_GROWS_UP 7629 stack_base = stack; 7630#else 7631 stack_base = (char *)stack + stack_size; 7632#endif 7633 7634 SYSCALL_REQUIRE((child = vfork()) != -1); 7635 if (child == 0) { 7636 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7637 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7638 7639 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7640 flags); 7641 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7642 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7643 7644 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7645 child2); 7646 7647 // XXX WALLSIG? 7648 FORKEE_REQUIRE_SUCCESS 7649 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7650 7651 forkee_status_exited(status, exitval2); 7652 7653 DPRINTF("Before exiting of the child process\n"); 7654 _exit(exitval); 7655 } 7656 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7657 7658 DPRINTF("Before calling %s() for the child - expected exited\n", 7659 TWAIT_FNAME); 7660 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7661 7662 validate_status_exited(status, exitval); 7663 7664 DPRINTF("Before calling %s() for the child - expected no process\n", 7665 TWAIT_FNAME); 7666 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7667} 7668 7669#define TRACEME_VFORK_CLONE_TEST(name,flags) \ 7670ATF_TC(name); \ 7671ATF_TC_HEAD(name, tc) \ 7672{ \ 7673 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \ 7674 "handled correctly with vfork(2)ed tracer", \ 7675 #flags); \ 7676} \ 7677 \ 7678ATF_TC_BODY(name, tc) \ 7679{ \ 7680 \ 7681 traceme_vfork_clone_body(flags); \ 7682} 7683 7684TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0) 7685TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM) 7686TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS) 7687TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES) 7688//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX 7689TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK) 7690#endif 7691 7692/// ---------------------------------------------------------------------------- 7693 7694static void 7695user_va0_disable(int operation) 7696{ 7697 pid_t child, wpid; 7698#if defined(TWAIT_HAVE_STATUS) 7699 int status; 7700#endif 7701 const int sigval = SIGSTOP; 7702 int rv; 7703 7704 struct ptrace_siginfo info; 7705 7706 if (get_user_va0_disable() == 0) 7707 atf_tc_skip("vm.user_va0_disable is set to 0"); 7708 7709 memset(&info, 0, sizeof(info)); 7710 7711 DPRINTF("Before forking process PID=%d\n", getpid()); 7712 SYSCALL_REQUIRE((child = fork()) != -1); 7713 if (child == 0) { 7714 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7715 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7716 7717 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7718 FORKEE_ASSERT(raise(sigval) == 0); 7719 7720 /* NOTREACHED */ 7721 FORKEE_ASSERTX(0 && "This shall not be reached"); 7722 __unreachable(); 7723 } 7724 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7725 7726 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7727 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7728 7729 validate_status_stopped(status, sigval); 7730 7731 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7732 "child\n"); 7733 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 7734 sizeof(info)) != -1); 7735 7736 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7737 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7738 "si_errno=%#x\n", 7739 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7740 info.psi_siginfo.si_errno); 7741 7742 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7743 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7744 7745 DPRINTF("Before resuming the child process in PC=0x0 " 7746 "and without signal to be sent\n"); 7747 errno = 0; 7748 rv = ptrace(operation, child, (void *)0, 0); 7749 ATF_REQUIRE_EQ(errno, EINVAL); 7750 ATF_REQUIRE_EQ(rv, -1); 7751 7752 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 7753 7754 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7755 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7756 validate_status_signaled(status, SIGKILL, 0); 7757 7758 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7759 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7760} 7761 7762#define USER_VA0_DISABLE(test, operation) \ 7763ATF_TC(test); \ 7764ATF_TC_HEAD(test, tc) \ 7765{ \ 7766 atf_tc_set_md_var(tc, "descr", \ 7767 "Verify behavior of " #operation " with PC set to 0x0"); \ 7768} \ 7769 \ 7770ATF_TC_BODY(test, tc) \ 7771{ \ 7772 \ 7773 user_va0_disable(operation); \ 7774} 7775 7776USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 7777USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 7778USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 7779 7780/// ---------------------------------------------------------------------------- 7781 7782/* 7783 * Parse the core file and find the requested note. If the reading or parsing 7784 * fails, the test is failed. If the note is found, it is read onto buf, up to 7785 * buf_len. The actual length of the note is returned (which can be greater 7786 * than buf_len, indicating that it has been truncated). If the note is not 7787 * found, -1 is returned. 7788 */ 7789static ssize_t core_find_note(const char *core_path, 7790 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 7791{ 7792 int core_fd; 7793 Elf *core_elf; 7794 size_t core_numhdr, i; 7795 ssize_t ret = -1; 7796 /* note: we assume note name will be null-terminated */ 7797 size_t name_len = strlen(note_name) + 1; 7798 7799 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 7800 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 7801 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 7802 7803 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 7804 for (i = 0; i < core_numhdr && ret == -1; i++) { 7805 GElf_Phdr core_hdr; 7806 size_t offset; 7807 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 7808 if (core_hdr.p_type != PT_NOTE) 7809 continue; 7810 7811 for (offset = core_hdr.p_offset; 7812 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 7813 Elf64_Nhdr note_hdr; 7814 char name_buf[64]; 7815 7816 switch (gelf_getclass(core_elf)) { 7817 case ELFCLASS64: 7818 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 7819 sizeof(note_hdr), offset) 7820 == sizeof(note_hdr)); 7821 offset += sizeof(note_hdr); 7822 break; 7823 case ELFCLASS32: 7824 { 7825 Elf32_Nhdr tmp_hdr; 7826 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 7827 sizeof(tmp_hdr), offset) 7828 == sizeof(tmp_hdr)); 7829 offset += sizeof(tmp_hdr); 7830 note_hdr.n_namesz = tmp_hdr.n_namesz; 7831 note_hdr.n_descsz = tmp_hdr.n_descsz; 7832 note_hdr.n_type = tmp_hdr.n_type; 7833 } 7834 break; 7835 } 7836 7837 /* indicates end of notes */ 7838 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 7839 break; 7840 if (note_hdr.n_namesz == name_len && 7841 note_hdr.n_namesz <= sizeof(name_buf)) { 7842 SYSCALL_REQUIRE(pread(core_fd, name_buf, 7843 note_hdr.n_namesz, offset) 7844 == (ssize_t)(size_t)note_hdr.n_namesz); 7845 7846 if (!strncmp(note_name, name_buf, name_len) && 7847 note_hdr.n_type == note_type) 7848 ret = note_hdr.n_descsz; 7849 } 7850 7851 offset += note_hdr.n_namesz; 7852 /* fix to alignment */ 7853 offset = ((offset + core_hdr.p_align - 1) 7854 / core_hdr.p_align) * core_hdr.p_align; 7855 7856 /* if name & type matched above */ 7857 if (ret != -1) { 7858 ssize_t read_len = MIN(buf_len, 7859 note_hdr.n_descsz); 7860 SYSCALL_REQUIRE(pread(core_fd, buf, 7861 read_len, offset) == read_len); 7862 break; 7863 } 7864 7865 offset += note_hdr.n_descsz; 7866 } 7867 } 7868 7869 elf_end(core_elf); 7870 close(core_fd); 7871 7872 return ret; 7873} 7874 7875ATF_TC(core_dump_procinfo); 7876ATF_TC_HEAD(core_dump_procinfo, tc) 7877{ 7878 atf_tc_set_md_var(tc, "descr", 7879 "Trigger a core dump and verify its contents."); 7880} 7881 7882ATF_TC_BODY(core_dump_procinfo, tc) 7883{ 7884 const int exitval = 5; 7885 pid_t child, wpid; 7886#if defined(TWAIT_HAVE_STATUS) 7887 const int sigval = SIGTRAP; 7888 int status; 7889#endif 7890 char core_path[] = "/tmp/core.XXXXXX"; 7891 int core_fd; 7892 struct netbsd_elfcore_procinfo procinfo; 7893 7894 DPRINTF("Before forking process PID=%d\n", getpid()); 7895 SYSCALL_REQUIRE((child = fork()) != -1); 7896 if (child == 0) { 7897 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7898 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7899 7900 DPRINTF("Before triggering SIGTRAP\n"); 7901 trigger_trap(); 7902 7903 DPRINTF("Before exiting of the child process\n"); 7904 _exit(exitval); 7905 } 7906 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7907 7908 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7909 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7910 7911 validate_status_stopped(status, sigval); 7912 7913 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 7914 close(core_fd); 7915 7916 DPRINTF("Call DUMPCORE for the child process\n"); 7917 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 7918 != -1); 7919 7920 DPRINTF("Read core file\n"); 7921 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 7922 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 7923 sizeof(procinfo)); 7924 7925 ATF_CHECK_EQ(procinfo.cpi_version, 1); 7926 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 7927 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 7928 ATF_CHECK_EQ(procinfo.cpi_pid, child); 7929 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 7930 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 7931 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 7932 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 7933 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 7934 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 7935 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 7936 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 7937 ATF_CHECK_EQ(procinfo.cpi_siglwp, 1); 7938 7939 unlink(core_path); 7940 7941 DPRINTF("Before resuming the child process where it left off and " 7942 "without signal to be sent\n"); 7943 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7944 7945 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7946 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7947 7948 validate_status_exited(status, exitval); 7949 7950 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7951 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7952} 7953 7954/// ---------------------------------------------------------------------------- 7955 7956#if defined(TWAIT_HAVE_STATUS) 7957 7958ATF_TC(thread_concurrent_signals); 7959ATF_TC_HEAD(thread_concurrent_signals, tc) 7960{ 7961 atf_tc_set_md_var(tc, "descr", 7962 "Verify that concurrent signals issued to a single thread " 7963 "are reported correctly"); 7964} 7965 7966/* List of signals to use for the test */ 7967const int thread_concurrent_signals_list[] = { 7968 SIGIO, 7969 SIGXCPU, 7970 SIGXFSZ, 7971 SIGVTALRM, 7972 SIGPROF, 7973 SIGWINCH, 7974 SIGINFO, 7975 SIGUSR1, 7976 SIGUSR2 7977}; 7978 7979pthread_barrier_t thread_concurrent_signals_barrier; 7980 7981static void * 7982thread_concurrent_signals_thread(void *arg) 7983{ 7984 int sigval = thread_concurrent_signals_list[ 7985 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 7986 pthread_barrier_wait(&thread_concurrent_signals_barrier); 7987 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 7988 _lwp_self()); 7989 pthread_kill(pthread_self(), sigval); 7990 return NULL; 7991} 7992 7993#define THREAD_CONCURRENT_SIGNALS_NUM 50 7994 7995ATF_TC_BODY(thread_concurrent_signals, tc) 7996{ 7997 const int exitval = 5; 7998 const int sigval = SIGSTOP; 7999 pid_t child, wpid; 8000 int status; 8001 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 8002 = {{0, 0}}; 8003 unsigned int i; 8004 8005 DPRINTF("Before forking process PID=%d\n", getpid()); 8006 SYSCALL_REQUIRE((child = fork()) != -1); 8007 if (child == 0) { 8008 pthread_t threads[THREAD_CONCURRENT_SIGNALS_NUM]; 8009 8010 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8011 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8012 8013 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8014 FORKEE_ASSERT(raise(sigval) == 0); 8015 8016 DPRINTF("Before starting threads from the child\n"); 8017 FORKEE_ASSERT(pthread_barrier_init( 8018 &thread_concurrent_signals_barrier, NULL, 8019 __arraycount(threads)) == 0); 8020 8021 for (i = 0; i < __arraycount(threads); i++) { 8022 FORKEE_ASSERT(pthread_create(&threads[i], NULL, 8023 thread_concurrent_signals_thread, NULL) == 0); 8024 } 8025 8026 DPRINTF("Before joining threads from the child\n"); 8027 for (i = 0; i < __arraycount(threads); i++) { 8028 FORKEE_ASSERT(pthread_join(threads[i], NULL) == 0); 8029 } 8030 8031 FORKEE_ASSERT(pthread_barrier_destroy( 8032 &thread_concurrent_signals_barrier) == 0); 8033 8034 DPRINTF("Before exiting of the child process\n"); 8035 _exit(exitval); 8036 } 8037 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8038 8039 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8040 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8041 8042 validate_status_stopped(status, sigval); 8043 8044 DPRINTF("Before resuming the child process where it left off\n"); 8045 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8046 8047 DPRINTF("Before entering signal collection loop\n"); 8048 while (1) { 8049 ptrace_siginfo_t info; 8050 int expected_sig; 8051 8052 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8053 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 8054 child); 8055 if (WIFEXITED(status)) 8056 break; 8057 /* Note: we use validate_status_stopped() to get nice error 8058 * message. Signal is irrelevant since it won't be reached. 8059 */ 8060 else if (!WIFSTOPPED(status)) 8061 validate_status_stopped(status, 0); 8062 8063 DPRINTF("Before calling PT_GET_SIGINFO\n"); 8064 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 8065 sizeof(info)) != -1); 8066 8067 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 8068 info.psi_siginfo.si_signo, info.psi_lwpid, 8069 WSTOPSIG(status)); 8070 8071 expected_sig = thread_concurrent_signals_list[info.psi_lwpid % 8072 __arraycount(thread_concurrent_signals_list)]; 8073 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, expected_sig, 8074 "lwp=%d, expected %d, got %d", info.psi_lwpid, 8075 expected_sig, info.psi_siginfo.si_signo); 8076 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 8077 "lwp=%d, expected %d, got %d", info.psi_lwpid, 8078 expected_sig, WSTOPSIG(status)); 8079 8080 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 8081 8082 DPRINTF("Before resuming the child process\n"); 8083 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8084 } 8085 8086 for (i = 0; i < __arraycount(signal_counts); i++) 8087 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 8088 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 8089 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 8090 8091 validate_status_exited(status, exitval); 8092} 8093 8094#endif /*defined(TWAIT_HAVE_STATUS)*/ 8095 8096/// ---------------------------------------------------------------------------- 8097 8098#include "t_ptrace_amd64_wait.h" 8099#include "t_ptrace_i386_wait.h" 8100#include "t_ptrace_x86_wait.h" 8101 8102ATF_TP_ADD_TCS(tp) 8103{ 8104 setvbuf(stdout, NULL, _IONBF, 0); 8105 setvbuf(stderr, NULL, _IONBF, 0); 8106 8107 ATF_TP_ADD_TC(tp, traceme_raise1); 8108 ATF_TP_ADD_TC(tp, traceme_raise2); 8109 ATF_TP_ADD_TC(tp, traceme_raise3); 8110 ATF_TP_ADD_TC(tp, traceme_raise4); 8111 ATF_TP_ADD_TC(tp, traceme_raise5); 8112 ATF_TP_ADD_TC(tp, traceme_raise6); 8113 ATF_TP_ADD_TC(tp, traceme_raise7); 8114 ATF_TP_ADD_TC(tp, traceme_raise8); 8115 ATF_TP_ADD_TC(tp, traceme_raise9); 8116 ATF_TP_ADD_TC(tp, traceme_raise10); 8117 8118 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 8119 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 8120 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 8121 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 8122 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 8123 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 8124 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 8125 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 8126 8127 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 8128 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 8129 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 8130 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 8131 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 8132 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 8133 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 8134 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 8135 8136 ATF_TP_ADD_TC(tp, traceme_crash_trap); 8137 ATF_TP_ADD_TC(tp, traceme_crash_segv); 8138 ATF_TP_ADD_TC(tp, traceme_crash_ill); 8139 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 8140 ATF_TP_ADD_TC(tp, traceme_crash_bus); 8141 8142 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 8143 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 8144 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 8145 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 8146 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 8147 8148 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 8149 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 8150 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 8151 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 8152 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 8153 8154 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 8155 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 8156 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 8157 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 8158 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 8159 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 8160 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 8161 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 8162 8163 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 8164 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 8165 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 8166 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 8167 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 8168 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 8169 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 8170 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 8171 8172 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 8173 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 8174 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 8175 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 8176 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 8177 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 8178 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 8179 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 8180 8181 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 8182 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 8183 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 8184 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 8185 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 8186 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 8187 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 8188 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 8189 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 8190 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 8191 8192 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 8193 8194 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 8195 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 8196 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 8197 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 8198 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 8199 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 8200 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 8201 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 8202 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 8203 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 8204 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 8205 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 8206 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 8207 8208 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 8209 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 8210 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 8211 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 8212 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 8213 8214 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 8215 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 8216 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 8217 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 8218 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 8219 8220 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 8221 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 8222 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 8223 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 8224 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 8225 8226 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 8227 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 8228 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 8229 8230 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 8231 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 8232 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 8233 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 8234 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 8235 8236 ATF_TP_ADD_TC_HAVE_PID(tp, 8237 unrelated_tracer_sees_signalmasked_crash_trap); 8238 ATF_TP_ADD_TC_HAVE_PID(tp, 8239 unrelated_tracer_sees_signalmasked_crash_segv); 8240 ATF_TP_ADD_TC_HAVE_PID(tp, 8241 unrelated_tracer_sees_signalmasked_crash_ill); 8242 ATF_TP_ADD_TC_HAVE_PID(tp, 8243 unrelated_tracer_sees_signalmasked_crash_fpe); 8244 ATF_TP_ADD_TC_HAVE_PID(tp, 8245 unrelated_tracer_sees_signalmasked_crash_bus); 8246 8247 ATF_TP_ADD_TC_HAVE_PID(tp, 8248 unrelated_tracer_sees_signalignored_crash_trap); 8249 ATF_TP_ADD_TC_HAVE_PID(tp, 8250 unrelated_tracer_sees_signalignored_crash_segv); 8251 ATF_TP_ADD_TC_HAVE_PID(tp, 8252 unrelated_tracer_sees_signalignored_crash_ill); 8253 ATF_TP_ADD_TC_HAVE_PID(tp, 8254 unrelated_tracer_sees_signalignored_crash_fpe); 8255 ATF_TP_ADD_TC_HAVE_PID(tp, 8256 unrelated_tracer_sees_signalignored_crash_bus); 8257 8258 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 8259 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 8260 ATF_TP_ADD_TC_HAVE_PID(tp, 8261 unrelated_tracer_sees_terminaton_before_the_parent); 8262 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 8263 8264 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 8265 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 8266 8267 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 8268 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 8269 8270 ATF_TP_ADD_TC_HAVE_PID(tp, 8271 tracee_sees_its_original_parent_getppid); 8272 ATF_TP_ADD_TC_HAVE_PID(tp, 8273 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 8274 ATF_TP_ADD_TC_HAVE_PID(tp, 8275 tracee_sees_its_original_parent_procfs_status); 8276 8277 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 8278 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 8279 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 8280 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 8281 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 8282 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 8283 ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn); 8284 8285 ATF_TP_ADD_TC(tp, fork1); 8286 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 8287 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 8288 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 8289 ATF_TP_ADD_TC(tp, fork5); 8290 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 8291 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 8292 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 8293 ATF_TP_ADD_TC(tp, fork9); 8294 ATF_TP_ADD_TC_HAVE_PID(tp, fork10); 8295 ATF_TP_ADD_TC_HAVE_PID(tp, fork11); 8296 ATF_TP_ADD_TC_HAVE_PID(tp, fork12); 8297 ATF_TP_ADD_TC(tp, fork13); 8298 ATF_TP_ADD_TC_HAVE_PID(tp, fork14); 8299 ATF_TP_ADD_TC_HAVE_PID(tp, fork15); 8300 ATF_TP_ADD_TC_HAVE_PID(tp, fork16); 8301 8302 ATF_TP_ADD_TC(tp, vfork1); 8303 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 8304 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 8305 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 8306 ATF_TP_ADD_TC(tp, vfork5); 8307 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 8308 ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 8309 ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 8310 ATF_TP_ADD_TC(tp, vfork9); 8311 ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); 8312 ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); 8313 ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); 8314 ATF_TP_ADD_TC(tp, vfork13); 8315 ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); 8316 ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); 8317 ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); 8318 8319 ATF_TP_ADD_TC(tp, posix_spawn1); 8320 ATF_TP_ADD_TC(tp, posix_spawn2); 8321 ATF_TP_ADD_TC(tp, posix_spawn3); 8322 ATF_TP_ADD_TC(tp, posix_spawn4); 8323 ATF_TP_ADD_TC(tp, posix_spawn5); 8324 ATF_TP_ADD_TC(tp, posix_spawn6); 8325 ATF_TP_ADD_TC(tp, posix_spawn7); 8326 ATF_TP_ADD_TC(tp, posix_spawn8); 8327 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); 8328 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); 8329 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); 8330 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); 8331 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); 8332 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); 8333 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); 8334 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); 8335 8336 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); 8337 ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); 8338 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); 8339 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); 8340 8341 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); 8342 ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); 8343 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); 8344 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); 8345 8346 ATF_TP_ADD_TC(tp, traceme_vfork_fork); 8347 ATF_TP_ADD_TC(tp, traceme_vfork_vfork); 8348 8349 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 8350 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 8351 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 8352 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 8353 8354 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 8355 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 8356 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 8357 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 8358 8359 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 8360 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 8361 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 8362 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 8363 8364 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 8365 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 8366 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 8367 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 8368 8369 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 8370 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 8371 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 8372 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 8373 8374 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 8375 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 8376 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 8377 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 8378 8379 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 8380 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 8381 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 8382 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 8383 8384 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 8385 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 8386 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 8387 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 8388 8389 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 8390 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 8391 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 8392 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 8393 8394 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 8395 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 8396 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 8397 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 8398 8399 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 8400 8401 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); 8402 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); 8403 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); 8404 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); 8405 8406 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); 8407 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); 8408 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); 8409 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); 8410 8411 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); 8412 8413 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); 8414 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); 8415 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); 8416 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); 8417 8418 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); 8419 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); 8420 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); 8421 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d); 8422 8423 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 8424 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 8425 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 8426 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 8427 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 8428 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 8429 8430 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 8431 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 8432 8433 ATF_TP_ADD_TC_PT_STEP(tp, step1); 8434 ATF_TP_ADD_TC_PT_STEP(tp, step2); 8435 ATF_TP_ADD_TC_PT_STEP(tp, step3); 8436 ATF_TP_ADD_TC_PT_STEP(tp, step4); 8437 8438 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 8439 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 8440 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 8441 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 8442 8443 ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked); 8444 ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored); 8445 8446 ATF_TP_ADD_TC(tp, kill1); 8447 ATF_TP_ADD_TC(tp, kill2); 8448 ATF_TP_ADD_TC(tp, kill3); 8449 8450 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 8451 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 8452 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 8453 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 8454 8455 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus); 8456 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus); 8457 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus); 8458 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus); 8459 8460 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask); 8461 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask); 8462 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask); 8463 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask); 8464 8465 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name); 8466 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name); 8467 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name); 8468 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name); 8469 8470 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private); 8471 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private); 8472 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private); 8473 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private); 8474 8475 ATF_TP_ADD_TC(tp, traceme_lwpnext0); 8476 ATF_TP_ADD_TC(tp, traceme_lwpnext1); 8477 ATF_TP_ADD_TC(tp, traceme_lwpnext2); 8478 ATF_TP_ADD_TC(tp, traceme_lwpnext3); 8479 8480 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask); 8481 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask); 8482 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask); 8483 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask); 8484 8485 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name); 8486 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name); 8487 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name); 8488 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name); 8489 8490 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private); 8491 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private); 8492 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private); 8493 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private); 8494 8495 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 8496 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 8497 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 8498 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 8499 8500 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 8501 ATF_TP_ADD_TC(tp, siginfo_set_faked); 8502 8503 ATF_TP_ADD_TC(tp, traceme_exec); 8504 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 8505 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 8506 8507 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 8508 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 8509 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 8510 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 8511 8512 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 8513 8514 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked); 8515 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored); 8516 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked); 8517 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored); 8518 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked); 8519 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored); 8520 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked); 8521 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored); 8522 8523 ATF_TP_ADD_TC(tp, signal9); 8524 ATF_TP_ADD_TC(tp, signal10); 8525 8526 ATF_TP_ADD_TC(tp, suspend2); 8527 8528 ATF_TP_ADD_TC(tp, resume1); 8529 8530 ATF_TP_ADD_TC(tp, syscall1); 8531 8532 ATF_TP_ADD_TC(tp, syscallemu1); 8533 8534 ATF_TP_ADD_TC(tp, clone1); 8535 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); 8536 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); 8537 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); 8538 ATF_TP_ADD_TC(tp, clone5); 8539 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); 8540 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); 8541 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); 8542 8543 ATF_TP_ADD_TC(tp, clone_vm1); 8544 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); 8545 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); 8546 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); 8547 ATF_TP_ADD_TC(tp, clone_vm5); 8548 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); 8549 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); 8550 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); 8551 8552 ATF_TP_ADD_TC(tp, clone_fs1); 8553 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); 8554 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); 8555 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); 8556 ATF_TP_ADD_TC(tp, clone_fs5); 8557 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); 8558 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); 8559 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); 8560 8561 ATF_TP_ADD_TC(tp, clone_files1); 8562 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); 8563 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); 8564 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); 8565 ATF_TP_ADD_TC(tp, clone_files5); 8566 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); 8567 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); 8568 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); 8569 8570// ATF_TP_ADD_TC(tp, clone_sighand1); // XXX 8571// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX 8572// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX 8573// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX 8574// ATF_TP_ADD_TC(tp, clone_sighand5); // XXX 8575// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX 8576// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX 8577// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX 8578 8579 ATF_TP_ADD_TC(tp, clone_vfork1); 8580 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); 8581 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); 8582 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); 8583 ATF_TP_ADD_TC(tp, clone_vfork5); 8584 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); 8585 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); 8586 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); 8587 8588 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); 8589 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); 8590 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); 8591 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); 8592 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); 8593 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); 8594 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); 8595 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); 8596// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX 8597// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX 8598 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); 8599 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); 8600 8601 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); 8602 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); 8603 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); 8604 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); 8605// ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX 8606 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork); 8607 8608 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 8609 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 8610 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 8611 8612 ATF_TP_ADD_TC(tp, core_dump_procinfo); 8613 8614#if defined(TWAIT_HAVE_STATUS) 8615 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 8616#endif 8617 8618 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 8619 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 8620 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 8621 8622 return atf_no_error(); 8623} 8624