t_ptrace_wait.c revision 1.145
1/* $NetBSD: t_ptrace_wait.c,v 1.145 2019/12/25 02:23:37 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.145 2019/12/25 02:23:37 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 int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG}; 4807 4808static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER; 4809static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER; 4810static volatile size_t lwpinfo_thread_done; 4811 4812static void * 4813lwpinfo_thread(void *arg) 4814{ 4815 sigset_t s; 4816 volatile void **tcb; 4817 4818 tcb = (volatile void **)arg; 4819 4820 *tcb = _lwp_getprivate(); 4821 DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self()); 4822 4823 pthread_setname_np(pthread_self(), "thread %d", 4824 (void *)(intptr_t)_lwp_self()); 4825 4826 sigemptyset(&s); 4827 pthread_mutex_lock(&lwpinfo_thread_mtx); 4828 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 4829 lwpinfo_thread_done++; 4830 pthread_sigmask(SIG_BLOCK, &s, NULL); 4831 pthread_cond_signal(&lwpinfo_thread_cnd); 4832 pthread_mutex_unlock(&lwpinfo_thread_mtx); 4833 4834 return infinite_thread(NULL); 4835} 4836 4837static void 4838traceme_lwpinfo(const size_t threads, const char *iter) 4839{ 4840 const int sigval = SIGSTOP; 4841 const int sigval2 = SIGINT; 4842 pid_t child, wpid; 4843#if defined(TWAIT_HAVE_STATUS) 4844 int status; 4845#endif 4846 struct ptrace_lwpinfo lwp = {0, 0}; 4847 struct ptrace_lwpstatus lwpstatus = {0}; 4848 struct ptrace_siginfo info; 4849 void *private; 4850 char *name; 4851 char namebuf[PL_LNAMELEN]; 4852 volatile void *tcb[4]; 4853 bool found; 4854 sigset_t s; 4855 4856 /* Maximum number of supported threads in this test */ 4857 pthread_t t[__arraycount(tcb) - 1]; 4858 size_t n, m; 4859 int rv; 4860 size_t bytes_read; 4861 4862 struct ptrace_io_desc io; 4863 sigset_t sigmask; 4864 4865 ATF_REQUIRE(__arraycount(t) >= threads); 4866 memset(tcb, 0, sizeof(tcb)); 4867 4868 DPRINTF("Before forking process PID=%d\n", getpid()); 4869 SYSCALL_REQUIRE((child = fork()) != -1); 4870 if (child == 0) { 4871 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4872 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4873 4874 tcb[0] = _lwp_getprivate(); 4875 DPRINTF("Storing tcb[0] = %p\n", tcb[0]); 4876 4877 pthread_setname_np(pthread_self(), "thread %d", 4878 (void *)(intptr_t)_lwp_self()); 4879 4880 sigemptyset(&s); 4881 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 4882 pthread_sigmask(SIG_BLOCK, &s, NULL); 4883 4884 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4885 FORKEE_ASSERT(raise(sigval) == 0); 4886 4887 for (n = 0; n < threads; n++) { 4888 rv = pthread_create(&t[n], NULL, lwpinfo_thread, 4889 &tcb[n + 1]); 4890 FORKEE_ASSERT(rv == 0); 4891 } 4892 4893 pthread_mutex_lock(&lwpinfo_thread_mtx); 4894 while (lwpinfo_thread_done < threads) { 4895 pthread_cond_wait(&lwpinfo_thread_cnd, 4896 &lwpinfo_thread_mtx); 4897 } 4898 pthread_mutex_unlock(&lwpinfo_thread_mtx); 4899 4900 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 4901 FORKEE_ASSERT(raise(sigval2) == 0); 4902 4903 /* NOTREACHED */ 4904 FORKEE_ASSERTX(0 && "Not reached"); 4905 } 4906 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4907 4908 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4909 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4910 4911 validate_status_stopped(status, sigval); 4912 4913 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4914 SYSCALL_REQUIRE( 4915 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4916 4917 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4918 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4919 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4920 info.psi_siginfo.si_errno); 4921 4922 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4923 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4924 4925 if (strstr(iter, "LWPINFO") != NULL) { 4926 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4927 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 4928 != -1); 4929 4930 DPRINTF("Assert that there exists a single thread only\n"); 4931 ATF_REQUIRE(lwp.pl_lwpid > 0); 4932 4933 DPRINTF("Assert that lwp thread %d received event " 4934 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 4935 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 4936 4937 if (strstr(iter, "LWPSTATUS") != NULL) { 4938 DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS " 4939 "for child\n"); 4940 lwpstatus.pl_lwpid = lwp.pl_lwpid; 4941 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus, 4942 sizeof(lwpstatus)) != -1); 4943 } 4944 4945 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4946 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 4947 != -1); 4948 4949 DPRINTF("Assert that there exists a single thread only\n"); 4950 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 4951 } else { 4952 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 4953 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 4954 sizeof(lwpstatus)) != -1); 4955 4956 DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid); 4957 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 4958 4959 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 4960 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 4961 sizeof(lwpstatus)) != -1); 4962 4963 DPRINTF("Assert that there exists a single thread only\n"); 4964 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 4965 } 4966 4967 DPRINTF("Before resuming the child process where it left off and " 4968 "without signal to be sent\n"); 4969 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4970 4971 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4972 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4973 4974 validate_status_stopped(status, sigval2); 4975 4976 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4977 SYSCALL_REQUIRE( 4978 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4979 4980 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4981 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4982 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4983 info.psi_siginfo.si_errno); 4984 4985 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 4986 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4987 4988 memset(&lwp, 0, sizeof(lwp)); 4989 memset(&lwpstatus, 0, sizeof(lwpstatus)); 4990 4991 memset(&io, 0, sizeof(io)); 4992 4993 bytes_read = 0; 4994 io.piod_op = PIOD_READ_D; 4995 io.piod_len = sizeof(tcb); 4996 4997 do { 4998 io.piod_addr = (char *)&tcb + bytes_read; 4999 io.piod_offs = io.piod_addr; 5000 5001 rv = ptrace(PT_IO, child, &io, sizeof(io)); 5002 ATF_REQUIRE(rv != -1 && io.piod_len != 0); 5003 5004 bytes_read += io.piod_len; 5005 io.piod_len = sizeof(tcb) - bytes_read; 5006 } while (bytes_read < sizeof(tcb)); 5007 5008 for (n = 0; n <= threads; n++) { 5009 if (strstr(iter, "LWPINFO") != NULL) { 5010 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5011 "child\n"); 5012 SYSCALL_REQUIRE( 5013 ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 5014 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5015 5016 DPRINTF("Assert that the thread exists\n"); 5017 ATF_REQUIRE(lwp.pl_lwpid > 0); 5018 5019 DPRINTF("Assert that lwp thread %d received expected " 5020 "event\n", lwp.pl_lwpid); 5021 FORKEE_ASSERT_EQ(lwp.pl_event, 5022 info.psi_lwpid == lwp.pl_lwpid ? 5023 PL_EVENT_SIGNAL : PL_EVENT_NONE); 5024 5025 if (strstr(iter, "LWPSTATUS") != NULL) { 5026 DPRINTF("Before calling ptrace(2) with " 5027 "PT_LWPSTATUS for child\n"); 5028 lwpstatus.pl_lwpid = lwp.pl_lwpid; 5029 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, 5030 &lwpstatus, sizeof(lwpstatus)) != -1); 5031 5032 goto check_lwpstatus; 5033 } 5034 } else { 5035 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for " 5036 "child\n"); 5037 SYSCALL_REQUIRE( 5038 ptrace(PT_LWPNEXT, child, &lwpstatus, 5039 sizeof(lwpstatus)) != -1); 5040 DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid); 5041 5042 DPRINTF("Assert that the thread exists\n"); 5043 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 5044 5045 check_lwpstatus: 5046 5047 if (strstr(iter, "pl_sigmask") != NULL) { 5048 sigmask = lwpstatus.pl_sigmask; 5049 5050 DPRINTF("Retrieved sigmask: " 5051 "%02x%02x%02x%02x\n", 5052 sigmask.__bits[0], sigmask.__bits[1], 5053 sigmask.__bits[2], sigmask.__bits[3]); 5054 5055 found = false; 5056 for (m = 0; 5057 m < __arraycount(lwpinfo_thread_sigmask); 5058 m++) { 5059 if (sigismember(&sigmask, 5060 lwpinfo_thread_sigmask[m])) { 5061 found = true; 5062 lwpinfo_thread_sigmask[m] = 0; 5063 break; 5064 } 5065 } 5066 ATF_REQUIRE(found == true); 5067 } else if (strstr(iter, "pl_name") != NULL) { 5068 name = lwpstatus.pl_name; 5069 5070 DPRINTF("Retrieved thread name: " 5071 "%s\n", name); 5072 5073 snprintf(namebuf, sizeof namebuf, "thread %d", 5074 lwpstatus.pl_lwpid); 5075 5076 ATF_REQUIRE(strcmp(name, namebuf) == 0); 5077 } else if (strstr(iter, "pl_private") != NULL) { 5078 private = lwpstatus.pl_private; 5079 5080 DPRINTF("Retrieved thread private pointer: " 5081 "%p\n", private); 5082 5083 found = false; 5084 for (m = 0; m < __arraycount(tcb); m++) { 5085 DPRINTF("Comparing %p and %p\n", 5086 private, tcb[m]); 5087 if (private == tcb[m]) { 5088 found = true; 5089 break; 5090 } 5091 } 5092 ATF_REQUIRE(found == true); 5093 } 5094 } 5095 } 5096 5097 if (strstr(iter, "LWPINFO") != NULL) { 5098 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5099 "child\n"); 5100 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 5101 != -1); 5102 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5103 5104 DPRINTF("Assert that there are no more threads\n"); 5105 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 5106 } else { 5107 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 5108 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 5109 sizeof(lwpstatus)) != -1); 5110 5111 DPRINTF("Assert that there exists a single thread only\n"); 5112 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 5113 } 5114 5115 DPRINTF("Before resuming the child process where it left off and " 5116 "without signal to be sent\n"); 5117 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 5118 5119 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5120 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5121 5122 validate_status_signaled(status, SIGKILL, 0); 5123 5124 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5125 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5126} 5127 5128#define TRACEME_LWPINFO(test, threads, iter) \ 5129ATF_TC(test); \ 5130ATF_TC_HEAD(test, tc) \ 5131{ \ 5132 atf_tc_set_md_var(tc, "descr", \ 5133 "Verify " iter " with the child with " #threads \ 5134 " spawned extra threads"); \ 5135} \ 5136 \ 5137ATF_TC_BODY(test, tc) \ 5138{ \ 5139 \ 5140 traceme_lwpinfo(threads, iter); \ 5141} 5142 5143TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO") 5144TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO") 5145TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO") 5146TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO") 5147 5148TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS") 5149TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS") 5150TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS") 5151TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS") 5152 5153TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0, 5154 "LWPINFO+LWPSTATUS+pl_sigmask") 5155TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1, 5156 "LWPINFO+LWPSTATUS+pl_sigmask") 5157TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2, 5158 "LWPINFO+LWPSTATUS+pl_sigmask") 5159TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3, 5160 "LWPINFO+LWPSTATUS+pl_sigmask") 5161 5162TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0, 5163 "LWPINFO+LWPSTATUS+pl_name") 5164TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1, 5165 "LWPINFO+LWPSTATUS+pl_name") 5166TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2, 5167 "LWPINFO+LWPSTATUS+pl_name") 5168TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3, 5169 "LWPINFO+LWPSTATUS+pl_name") 5170 5171TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0, 5172 "LWPINFO+LWPSTATUS+pl_private") 5173TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1, 5174 "LWPINFO+LWPSTATUS+pl_private") 5175TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2, 5176 "LWPINFO+LWPSTATUS+pl_private") 5177TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3, 5178 "LWPINFO+LWPSTATUS+pl_private") 5179 5180TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT") 5181TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT") 5182TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT") 5183TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT") 5184 5185TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask") 5186TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask") 5187TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask") 5188TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask") 5189 5190TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name") 5191TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name") 5192TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name") 5193TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name") 5194 5195TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private") 5196TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private") 5197TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private") 5198TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private") 5199 5200/// ---------------------------------------------------------------------------- 5201 5202#if defined(TWAIT_HAVE_PID) 5203static void 5204attach_lwpinfo(const int threads) 5205{ 5206 const int sigval = SIGINT; 5207 struct msg_fds parent_tracee, parent_tracer; 5208 const int exitval_tracer = 10; 5209 pid_t tracee, tracer, wpid; 5210 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 5211#if defined(TWAIT_HAVE_STATUS) 5212 int status; 5213#endif 5214 struct ptrace_lwpinfo lwp = {0, 0}; 5215 struct ptrace_siginfo info; 5216 5217 /* Maximum number of supported threads in this test */ 5218 pthread_t t[3]; 5219 int n, rv; 5220 5221 DPRINTF("Spawn tracee\n"); 5222 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 5223 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 5224 tracee = atf_utils_fork(); 5225 if (tracee == 0) { 5226 /* Wait for message from the parent */ 5227 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 5228 5229 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 5230 5231 for (n = 0; n < threads; n++) { 5232 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 5233 FORKEE_ASSERT(rv == 0); 5234 } 5235 5236 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 5237 5238 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5239 FORKEE_ASSERT(raise(sigval) == 0); 5240 5241 /* NOTREACHED */ 5242 FORKEE_ASSERTX(0 && "Not reached"); 5243 } 5244 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 5245 5246 DPRINTF("Spawn debugger\n"); 5247 tracer = atf_utils_fork(); 5248 if (tracer == 0) { 5249 /* No IPC to communicate with the child */ 5250 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 5251 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 5252 5253 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 5254 FORKEE_REQUIRE_SUCCESS( 5255 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5256 5257 forkee_status_stopped(status, SIGSTOP); 5258 5259 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5260 "tracee"); 5261 FORKEE_ASSERT( 5262 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5263 5264 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5265 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5266 "si_errno=%#x\n", 5267 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5268 info.psi_siginfo.si_errno); 5269 5270 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 5271 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 5272 5273 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 5274 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5275 != -1); 5276 5277 DPRINTF("Assert that there exists a thread\n"); 5278 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 5279 5280 DPRINTF("Assert that lwp thread %d received event " 5281 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 5282 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 5283 5284 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5285 "tracee\n"); 5286 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5287 != -1); 5288 5289 DPRINTF("Assert that there are no more lwp threads in " 5290 "tracee\n"); 5291 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 5292 5293 /* Resume tracee with PT_CONTINUE */ 5294 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 5295 5296 /* Inform parent that tracer has attached to tracee */ 5297 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 5298 5299 /* Wait for parent */ 5300 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 5301 5302 /* Wait for tracee and assert that it raised a signal */ 5303 FORKEE_REQUIRE_SUCCESS( 5304 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5305 5306 forkee_status_stopped(status, SIGINT); 5307 5308 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5309 "child"); 5310 FORKEE_ASSERT( 5311 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 5312 5313 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5314 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5315 "si_errno=%#x\n", 5316 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5317 info.psi_siginfo.si_errno); 5318 5319 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 5320 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 5321 5322 memset(&lwp, 0, sizeof(lwp)); 5323 5324 for (n = 0; n <= threads; n++) { 5325 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5326 "child\n"); 5327 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 5328 sizeof(lwp)) != -1); 5329 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5330 5331 DPRINTF("Assert that the thread exists\n"); 5332 FORKEE_ASSERT(lwp.pl_lwpid > 0); 5333 5334 DPRINTF("Assert that lwp thread %d received expected " 5335 "event\n", lwp.pl_lwpid); 5336 FORKEE_ASSERT_EQ(lwp.pl_event, 5337 info.psi_lwpid == lwp.pl_lwpid ? 5338 PL_EVENT_SIGNAL : PL_EVENT_NONE); 5339 } 5340 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 5341 "tracee\n"); 5342 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 5343 != -1); 5344 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 5345 5346 DPRINTF("Assert that there are no more threads\n"); 5347 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 5348 5349 DPRINTF("Before resuming the child process where it left off " 5350 "and without signal to be sent\n"); 5351 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 5352 != -1); 5353 5354 /* Wait for tracee and assert that it exited */ 5355 FORKEE_REQUIRE_SUCCESS( 5356 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 5357 5358 forkee_status_signaled(status, SIGKILL, 0); 5359 5360 DPRINTF("Before exiting of the tracer process\n"); 5361 _exit(exitval_tracer); 5362 } 5363 5364 DPRINTF("Wait for the tracer to attach to the tracee\n"); 5365 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 5366 5367 DPRINTF("Resume the tracee and spawn threads\n"); 5368 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 5369 5370 DPRINTF("Resume the tracee and let it exit\n"); 5371 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 5372 5373 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 5374 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 5375 5376 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 5377 TWAIT_FNAME); 5378 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 5379 tracer); 5380 5381 validate_status_exited(status, exitval_tracer); 5382 5383 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 5384 TWAIT_FNAME); 5385 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 5386 tracee); 5387 5388 validate_status_signaled(status, SIGKILL, 0); 5389 5390 msg_close(&parent_tracer); 5391 msg_close(&parent_tracee); 5392} 5393 5394#define ATTACH_LWPINFO(test, threads) \ 5395ATF_TC(test); \ 5396ATF_TC_HEAD(test, tc) \ 5397{ \ 5398 atf_tc_set_md_var(tc, "descr", \ 5399 "Verify LWPINFO with the child with " #threads \ 5400 " spawned extra threads (tracer is not the original " \ 5401 "parent)"); \ 5402} \ 5403 \ 5404ATF_TC_BODY(test, tc) \ 5405{ \ 5406 \ 5407 attach_lwpinfo(threads); \ 5408} 5409 5410ATTACH_LWPINFO(attach_lwpinfo0, 0) 5411ATTACH_LWPINFO(attach_lwpinfo1, 1) 5412ATTACH_LWPINFO(attach_lwpinfo2, 2) 5413ATTACH_LWPINFO(attach_lwpinfo3, 3) 5414#endif 5415 5416/// ---------------------------------------------------------------------------- 5417 5418static void 5419ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 5420{ 5421 const int exitval = 5; 5422 const int sigval = SIGINT; 5423 const int sigfaked = SIGTRAP; 5424 const int sicodefaked = TRAP_BRKPT; 5425 pid_t child, wpid; 5426 struct sigaction sa; 5427#if defined(TWAIT_HAVE_STATUS) 5428 int status; 5429#endif 5430 struct ptrace_siginfo info; 5431 memset(&info, 0, sizeof(info)); 5432 5433 DPRINTF("Before forking process PID=%d\n", getpid()); 5434 SYSCALL_REQUIRE((child = fork()) != -1); 5435 if (child == 0) { 5436 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5437 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5438 5439 sa.sa_sigaction = sah; 5440 sa.sa_flags = SA_SIGINFO; 5441 sigemptyset(&sa.sa_mask); 5442 5443 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 5444 != -1); 5445 5446 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5447 FORKEE_ASSERT(raise(sigval) == 0); 5448 5449 FORKEE_ASSERT_EQ(*signal_caught, 1); 5450 5451 DPRINTF("Before exiting of the child process\n"); 5452 _exit(exitval); 5453 } 5454 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5455 5456 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5457 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5458 5459 validate_status_stopped(status, sigval); 5460 5461 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5462 SYSCALL_REQUIRE( 5463 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5464 5465 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5466 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5467 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5468 info.psi_siginfo.si_errno); 5469 5470 if (faked) { 5471 DPRINTF("Before setting new faked signal to signo=%d " 5472 "si_code=%d\n", sigfaked, sicodefaked); 5473 info.psi_siginfo.si_signo = sigfaked; 5474 info.psi_siginfo.si_code = sicodefaked; 5475 } 5476 5477 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 5478 SYSCALL_REQUIRE( 5479 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 5480 5481 if (faked) { 5482 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5483 "child\n"); 5484 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 5485 sizeof(info)) != -1); 5486 5487 DPRINTF("Before checking siginfo_t\n"); 5488 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 5489 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 5490 } 5491 5492 DPRINTF("Before resuming the child process where it left off and " 5493 "without signal to be sent\n"); 5494 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 5495 faked ? sigfaked : sigval) != -1); 5496 5497 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5498 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5499 5500 validate_status_exited(status, exitval); 5501 5502 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5503 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5504} 5505 5506#define PTRACE_SIGINFO(test, faked) \ 5507ATF_TC(test); \ 5508ATF_TC_HEAD(test, tc) \ 5509{ \ 5510 atf_tc_set_md_var(tc, "descr", \ 5511 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 5512 "with%s setting signal to new value", faked ? "" : "out"); \ 5513} \ 5514 \ 5515static int test##_caught = 0; \ 5516 \ 5517static void \ 5518test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 5519{ \ 5520 if (faked) { \ 5521 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 5522 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 5523 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 5524 } else { \ 5525 FORKEE_ASSERT_EQ(sig, SIGINT); \ 5526 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 5527 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 5528 } \ 5529 \ 5530 ++ test##_caught; \ 5531} \ 5532 \ 5533ATF_TC_BODY(test, tc) \ 5534{ \ 5535 \ 5536 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 5537} 5538 5539PTRACE_SIGINFO(siginfo_set_unmodified, false) 5540PTRACE_SIGINFO(siginfo_set_faked, true) 5541 5542/// ---------------------------------------------------------------------------- 5543 5544static void 5545traceme_exec(bool masked, bool ignored) 5546{ 5547 const int sigval = SIGTRAP; 5548 pid_t child, wpid; 5549#if defined(TWAIT_HAVE_STATUS) 5550 int status; 5551#endif 5552 struct sigaction sa; 5553 struct ptrace_siginfo info; 5554 sigset_t intmask; 5555 struct kinfo_proc2 kp; 5556 size_t len = sizeof(kp); 5557 5558 int name[6]; 5559 const size_t namelen = __arraycount(name); 5560 ki_sigset_t kp_sigmask; 5561 ki_sigset_t kp_sigignore; 5562 5563 memset(&info, 0, sizeof(info)); 5564 5565 DPRINTF("Before forking process PID=%d\n", getpid()); 5566 SYSCALL_REQUIRE((child = fork()) != -1); 5567 if (child == 0) { 5568 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5569 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5570 5571 if (masked) { 5572 sigemptyset(&intmask); 5573 sigaddset(&intmask, sigval); 5574 sigprocmask(SIG_BLOCK, &intmask, NULL); 5575 } 5576 5577 if (ignored) { 5578 memset(&sa, 0, sizeof(sa)); 5579 sa.sa_handler = SIG_IGN; 5580 sigemptyset(&sa.sa_mask); 5581 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 5582 } 5583 5584 DPRINTF("Before calling execve(2) from child\n"); 5585 execlp("/bin/echo", "/bin/echo", NULL); 5586 5587 FORKEE_ASSERT(0 && "Not reached"); 5588 } 5589 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5590 5591 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5592 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5593 5594 validate_status_stopped(status, sigval); 5595 5596 name[0] = CTL_KERN, 5597 name[1] = KERN_PROC2, 5598 name[2] = KERN_PROC_PID; 5599 name[3] = getpid(); 5600 name[4] = sizeof(kp); 5601 name[5] = 1; 5602 5603 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5604 5605 if (masked) 5606 kp_sigmask = kp.p_sigmask; 5607 5608 if (ignored) 5609 kp_sigignore = kp.p_sigignore; 5610 5611 name[3] = getpid(); 5612 5613 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5614 5615 if (masked) { 5616 DPRINTF("kp_sigmask=" 5617 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5618 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5619 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5620 5621 DPRINTF("kp.p_sigmask=" 5622 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5623 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5624 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5625 5626 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5627 sizeof(kp_sigmask))); 5628 } 5629 5630 if (ignored) { 5631 DPRINTF("kp_sigignore=" 5632 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5633 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5634 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5635 5636 DPRINTF("kp.p_sigignore=" 5637 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 5638 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5639 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5640 5641 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5642 sizeof(kp_sigignore))); 5643 } 5644 5645 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5646 SYSCALL_REQUIRE( 5647 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5648 5649 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5650 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5651 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5652 info.psi_siginfo.si_errno); 5653 5654 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5655 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 5656 5657 DPRINTF("Before resuming the child process where it left off and " 5658 "without signal to be sent\n"); 5659 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5660 5661 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5662 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5663 5664 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5665 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5666} 5667 5668#define TRACEME_EXEC(test, masked, ignored) \ 5669ATF_TC(test); \ 5670ATF_TC_HEAD(test, tc) \ 5671{ \ 5672 atf_tc_set_md_var(tc, "descr", \ 5673 "Detect SIGTRAP TRAP_EXEC from " \ 5674 "child%s%s", masked ? " with masked signal" : "", \ 5675 masked ? " with ignored signal" : ""); \ 5676} \ 5677 \ 5678ATF_TC_BODY(test, tc) \ 5679{ \ 5680 \ 5681 traceme_exec(masked, ignored); \ 5682} 5683 5684TRACEME_EXEC(traceme_exec, false, false) 5685TRACEME_EXEC(traceme_signalmasked_exec, true, false) 5686TRACEME_EXEC(traceme_signalignored_exec, false, true) 5687 5688/// ---------------------------------------------------------------------------- 5689 5690#define TRACE_THREADS_NUM 100 5691 5692static volatile int done; 5693pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 5694 5695static void * 5696trace_threads_cb(void *arg __unused) 5697{ 5698 5699 pthread_mutex_lock(&trace_threads_mtx); 5700 done++; 5701 pthread_mutex_unlock(&trace_threads_mtx); 5702 5703 while (done < TRACE_THREADS_NUM) 5704 sched_yield(); 5705 5706 return NULL; 5707} 5708 5709static void 5710trace_threads(bool trace_create, bool trace_exit) 5711{ 5712 const int sigval = SIGSTOP; 5713 pid_t child, wpid; 5714#if defined(TWAIT_HAVE_STATUS) 5715 int status; 5716#endif 5717 ptrace_state_t state; 5718 const int slen = sizeof(state); 5719 ptrace_event_t event; 5720 const int elen = sizeof(event); 5721 struct ptrace_siginfo info; 5722 5723 pthread_t t[TRACE_THREADS_NUM]; 5724 int rv; 5725 size_t n; 5726 lwpid_t lid; 5727 5728 /* Track created and exited threads */ 5729 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 5730 5731 DPRINTF("Before forking process PID=%d\n", getpid()); 5732 SYSCALL_REQUIRE((child = fork()) != -1); 5733 if (child == 0) { 5734 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5735 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5736 5737 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5738 FORKEE_ASSERT(raise(sigval) == 0); 5739 5740 for (n = 0; n < __arraycount(t); n++) { 5741 rv = pthread_create(&t[n], NULL, trace_threads_cb, 5742 NULL); 5743 FORKEE_ASSERT(rv == 0); 5744 } 5745 5746 for (n = 0; n < __arraycount(t); n++) { 5747 rv = pthread_join(t[n], NULL); 5748 FORKEE_ASSERT(rv == 0); 5749 } 5750 5751 /* 5752 * There is race between _exit() and pthread_join() detaching 5753 * a thread. For simplicity kill the process after detecting 5754 * LWP events. 5755 */ 5756 while (true) 5757 continue; 5758 5759 FORKEE_ASSERT(0 && "Not reached"); 5760 } 5761 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5762 5763 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5764 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5765 5766 validate_status_stopped(status, sigval); 5767 5768 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5769 SYSCALL_REQUIRE( 5770 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5771 5772 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5773 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5774 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5775 info.psi_siginfo.si_errno); 5776 5777 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5778 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5779 5780 DPRINTF("Set LWP event mask for the child %d\n", child); 5781 memset(&event, 0, sizeof(event)); 5782 if (trace_create) 5783 event.pe_set_event |= PTRACE_LWP_CREATE; 5784 if (trace_exit) 5785 event.pe_set_event |= PTRACE_LWP_EXIT; 5786 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5787 5788 DPRINTF("Before resuming the child process where it left off and " 5789 "without signal to be sent\n"); 5790 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5791 5792 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 5793 DPRINTF("Before calling %s() for the child - expected stopped " 5794 "SIGTRAP\n", TWAIT_FNAME); 5795 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5796 child); 5797 5798 validate_status_stopped(status, SIGTRAP); 5799 5800 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5801 "child\n"); 5802 SYSCALL_REQUIRE( 5803 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5804 5805 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5806 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5807 "si_errno=%#x\n", 5808 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5809 info.psi_siginfo.si_errno); 5810 5811 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5812 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5813 5814 SYSCALL_REQUIRE( 5815 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5816 5817 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 5818 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 5819 5820 lid = state.pe_lwp; 5821 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 5822 5823 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 5824 5825 DPRINTF("Before resuming the child process where it left off " 5826 "and without signal to be sent\n"); 5827 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5828 } 5829 5830 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 5831 DPRINTF("Before calling %s() for the child - expected stopped " 5832 "SIGTRAP\n", TWAIT_FNAME); 5833 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5834 child); 5835 5836 validate_status_stopped(status, SIGTRAP); 5837 5838 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5839 "child\n"); 5840 SYSCALL_REQUIRE( 5841 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5842 5843 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5844 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5845 "si_errno=%#x\n", 5846 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5847 info.psi_siginfo.si_errno); 5848 5849 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5850 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5851 5852 SYSCALL_REQUIRE( 5853 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5854 5855 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 5856 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 5857 5858 lid = state.pe_lwp; 5859 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 5860 5861 if (trace_create) { 5862 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 5863 ATF_REQUIRE_EQ(*count, 1); 5864 *count = 0; 5865 } 5866 5867 DPRINTF("Before resuming the child process where it left off " 5868 "and without signal to be sent\n"); 5869 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5870 } 5871 5872 kill(child, SIGKILL); 5873 5874 DPRINTF("Before calling %s() for the child - expected exited\n", 5875 TWAIT_FNAME); 5876 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5877 5878 validate_status_signaled(status, SIGKILL, 0); 5879 5880 DPRINTF("Before calling %s() for the child - expected no process\n", 5881 TWAIT_FNAME); 5882 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5883} 5884 5885#define TRACE_THREADS(test, trace_create, trace_exit) \ 5886ATF_TC(test); \ 5887ATF_TC_HEAD(test, tc) \ 5888{ \ 5889 atf_tc_set_md_var(tc, "descr", \ 5890 "Verify spawning threads with%s tracing LWP create and" \ 5891 "with%s tracing LWP exit", trace_create ? "" : "out", \ 5892 trace_exit ? "" : "out"); \ 5893} \ 5894 \ 5895ATF_TC_BODY(test, tc) \ 5896{ \ 5897 \ 5898 trace_threads(trace_create, trace_exit); \ 5899} 5900 5901TRACE_THREADS(trace_thread_nolwpevents, false, false) 5902TRACE_THREADS(trace_thread_lwpexit, false, true) 5903TRACE_THREADS(trace_thread_lwpcreate, true, false) 5904TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true) 5905 5906/// ---------------------------------------------------------------------------- 5907 5908ATF_TC(signal_mask_unrelated); 5909ATF_TC_HEAD(signal_mask_unrelated, tc) 5910{ 5911 atf_tc_set_md_var(tc, "descr", 5912 "Verify that masking single unrelated signal does not stop tracer " 5913 "from catching other signals"); 5914} 5915 5916ATF_TC_BODY(signal_mask_unrelated, tc) 5917{ 5918 const int exitval = 5; 5919 const int sigval = SIGSTOP; 5920 const int sigmasked = SIGTRAP; 5921 const int signotmasked = SIGINT; 5922 pid_t child, wpid; 5923#if defined(TWAIT_HAVE_STATUS) 5924 int status; 5925#endif 5926 sigset_t intmask; 5927 5928 DPRINTF("Before forking process PID=%d\n", getpid()); 5929 SYSCALL_REQUIRE((child = fork()) != -1); 5930 if (child == 0) { 5931 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5932 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5933 5934 sigemptyset(&intmask); 5935 sigaddset(&intmask, sigmasked); 5936 sigprocmask(SIG_BLOCK, &intmask, NULL); 5937 5938 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5939 FORKEE_ASSERT(raise(sigval) == 0); 5940 5941 DPRINTF("Before raising %s from child\n", 5942 strsignal(signotmasked)); 5943 FORKEE_ASSERT(raise(signotmasked) == 0); 5944 5945 DPRINTF("Before exiting of the child process\n"); 5946 _exit(exitval); 5947 } 5948 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5949 5950 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5951 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5952 5953 validate_status_stopped(status, sigval); 5954 5955 DPRINTF("Before resuming the child process where it left off and " 5956 "without signal to be sent\n"); 5957 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5958 5959 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5960 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5961 5962 validate_status_stopped(status, signotmasked); 5963 5964 DPRINTF("Before resuming the child process where it left off and " 5965 "without signal to be sent\n"); 5966 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5967 5968 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5969 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5970 5971 validate_status_exited(status, exitval); 5972 5973 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5974 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5975} 5976 5977/// ---------------------------------------------------------------------------- 5978 5979#if defined(TWAIT_HAVE_PID) 5980static void 5981fork2_body(const char *fn, bool masked, bool ignored) 5982{ 5983 const int exitval = 5; 5984 const int exitval2 = 0; /* Match exit status from /bin/echo */ 5985 const int sigval = SIGSTOP; 5986 pid_t child, child2 = 0, wpid; 5987#if defined(TWAIT_HAVE_STATUS) 5988 int status; 5989#endif 5990 ptrace_state_t state; 5991 const int slen = sizeof(state); 5992 ptrace_event_t event; 5993 const int elen = sizeof(event); 5994 struct sigaction sa; 5995 struct ptrace_siginfo info; 5996 sigset_t intmask; 5997 struct kinfo_proc2 kp; 5998 size_t len = sizeof(kp); 5999 6000 int name[6]; 6001 const size_t namelen = __arraycount(name); 6002 ki_sigset_t kp_sigmask; 6003 ki_sigset_t kp_sigignore; 6004 6005 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 6006 6007 DPRINTF("Before forking process PID=%d\n", getpid()); 6008 SYSCALL_REQUIRE((child = fork()) != -1); 6009 if (child == 0) { 6010 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6011 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6012 6013 if (masked) { 6014 sigemptyset(&intmask); 6015 sigaddset(&intmask, SIGTRAP); 6016 sigprocmask(SIG_BLOCK, &intmask, NULL); 6017 } 6018 6019 if (ignored) { 6020 memset(&sa, 0, sizeof(sa)); 6021 sa.sa_handler = SIG_IGN; 6022 sigemptyset(&sa.sa_mask); 6023 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 6024 } 6025 6026 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6027 FORKEE_ASSERT(raise(sigval) == 0); 6028 6029 if (strcmp(fn, "spawn") == 0) { 6030 FORKEE_ASSERT_EQ(posix_spawn(&child2, 6031 arg[0], NULL, NULL, arg, NULL), 0); 6032 } else { 6033 if (strcmp(fn, "fork") == 0) { 6034 FORKEE_ASSERT((child2 = fork()) != -1); 6035 } else { 6036 FORKEE_ASSERT((child2 = vfork()) != -1); 6037 } 6038 if (child2 == 0) 6039 _exit(exitval2); 6040 } 6041 6042 FORKEE_REQUIRE_SUCCESS 6043 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6044 6045 forkee_status_exited(status, exitval2); 6046 6047 DPRINTF("Before exiting of the child process\n"); 6048 _exit(exitval); 6049 } 6050 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6051 6052 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6053 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6054 6055 validate_status_stopped(status, sigval); 6056 6057 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6058 SYSCALL_REQUIRE( 6059 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6060 6061 DPRINTF("Before checking siginfo_t\n"); 6062 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6063 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6064 6065 name[0] = CTL_KERN, 6066 name[1] = KERN_PROC2, 6067 name[2] = KERN_PROC_PID; 6068 name[3] = child; 6069 name[4] = sizeof(kp); 6070 name[5] = 1; 6071 6072 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6073 6074 if (masked) 6075 kp_sigmask = kp.p_sigmask; 6076 6077 if (ignored) 6078 kp_sigignore = kp.p_sigignore; 6079 6080 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 6081 strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "", 6082 strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "", 6083 strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "", 6084 strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child); 6085 event.pe_set_event = 0; 6086 if (strcmp(fn, "spawn") == 0) 6087 event.pe_set_event |= PTRACE_POSIX_SPAWN; 6088 if (strcmp(fn, "fork") == 0) 6089 event.pe_set_event |= PTRACE_FORK; 6090 if (strcmp(fn, "vfork") == 0) 6091 event.pe_set_event |= PTRACE_VFORK; 6092 if (strcmp(fn, "vforkdone") == 0) 6093 event.pe_set_event |= PTRACE_VFORK_DONE; 6094 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6095 6096 DPRINTF("Before resuming the child process where it left off and " 6097 "without signal to be sent\n"); 6098 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6099 6100 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6101 strcmp(fn, "vfork") == 0) { 6102 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6103 child); 6104 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6105 child); 6106 6107 validate_status_stopped(status, SIGTRAP); 6108 6109 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6110 6111 if (masked) { 6112 DPRINTF("kp_sigmask=" 6113 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6114 PRIx32 "\n", 6115 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6116 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6117 6118 DPRINTF("kp.p_sigmask=" 6119 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6120 PRIx32 "\n", 6121 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6122 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6123 6124 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6125 sizeof(kp_sigmask))); 6126 } 6127 6128 if (ignored) { 6129 DPRINTF("kp_sigignore=" 6130 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6131 PRIx32 "\n", 6132 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6133 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6134 6135 DPRINTF("kp.p_sigignore=" 6136 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6137 PRIx32 "\n", 6138 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6139 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6140 6141 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6142 sizeof(kp_sigignore))); 6143 } 6144 6145 SYSCALL_REQUIRE( 6146 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6147 if (strcmp(fn, "spawn") == 0) { 6148 ATF_REQUIRE_EQ( 6149 state.pe_report_event & PTRACE_POSIX_SPAWN, 6150 PTRACE_POSIX_SPAWN); 6151 } 6152 if (strcmp(fn, "fork") == 0) { 6153 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6154 PTRACE_FORK); 6155 } 6156 if (strcmp(fn, "vfork") == 0) { 6157 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6158 PTRACE_VFORK); 6159 } 6160 6161 child2 = state.pe_other_pid; 6162 DPRINTF("Reported ptrace event with forkee %d\n", child2); 6163 6164 DPRINTF("Before calling %s() for the forkee %d of the child " 6165 "%d\n", TWAIT_FNAME, child2, child); 6166 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 6167 child2); 6168 6169 validate_status_stopped(status, SIGTRAP); 6170 6171 name[3] = child2; 6172 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6173 6174 if (masked) { 6175 DPRINTF("kp_sigmask=" 6176 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6177 PRIx32 "\n", 6178 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6179 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6180 6181 DPRINTF("kp.p_sigmask=" 6182 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6183 PRIx32 "\n", 6184 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6185 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6186 6187 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6188 sizeof(kp_sigmask))); 6189 } 6190 6191 if (ignored) { 6192 DPRINTF("kp_sigignore=" 6193 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6194 PRIx32 "\n", 6195 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6196 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6197 6198 DPRINTF("kp.p_sigignore=" 6199 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6200 PRIx32 "\n", 6201 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6202 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6203 6204 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6205 sizeof(kp_sigignore))); 6206 } 6207 6208 SYSCALL_REQUIRE( 6209 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 6210 if (strcmp(fn, "spawn") == 0) { 6211 ATF_REQUIRE_EQ( 6212 state.pe_report_event & PTRACE_POSIX_SPAWN, 6213 PTRACE_POSIX_SPAWN); 6214 } 6215 if (strcmp(fn, "fork") == 0) { 6216 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6217 PTRACE_FORK); 6218 } 6219 if (strcmp(fn, "vfork") == 0) { 6220 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6221 PTRACE_VFORK); 6222 } 6223 6224 ATF_REQUIRE_EQ(state.pe_other_pid, child); 6225 6226 DPRINTF("Before resuming the forkee process where it left off " 6227 "and without signal to be sent\n"); 6228 SYSCALL_REQUIRE( 6229 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6230 6231 DPRINTF("Before resuming the child process where it left off " 6232 "and without signal to be sent\n"); 6233 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6234 } 6235 6236 if (strcmp(fn, "vforkdone") == 0) { 6237 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6238 child); 6239 TWAIT_REQUIRE_SUCCESS( 6240 wpid = TWAIT_GENERIC(child, &status, 0), child); 6241 6242 validate_status_stopped(status, SIGTRAP); 6243 6244 name[3] = child; 6245 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6246 6247 /* 6248 * SIGCHLD is now pending in the signal queue and 6249 * the kernel presents it to userland as a masked signal. 6250 */ 6251 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 6252 6253 if (masked) { 6254 DPRINTF("kp_sigmask=" 6255 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6256 PRIx32 "\n", 6257 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6258 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6259 6260 DPRINTF("kp.p_sigmask=" 6261 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6262 PRIx32 "\n", 6263 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6264 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6265 6266 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6267 sizeof(kp_sigmask))); 6268 } 6269 6270 if (ignored) { 6271 DPRINTF("kp_sigignore=" 6272 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6273 PRIx32 "\n", 6274 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6275 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6276 6277 DPRINTF("kp.p_sigignore=" 6278 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6279 PRIx32 "\n", 6280 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6281 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6282 6283 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6284 sizeof(kp_sigignore))); 6285 } 6286 6287 SYSCALL_REQUIRE( 6288 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6289 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6290 6291 child2 = state.pe_other_pid; 6292 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6293 child2); 6294 6295 DPRINTF("Before resuming the child process where it left off " 6296 "and without signal to be sent\n"); 6297 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6298 } 6299 6300 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6301 strcmp(fn, "vfork") == 0) { 6302 DPRINTF("Before calling %s() for the forkee - expected exited" 6303 "\n", TWAIT_FNAME); 6304 TWAIT_REQUIRE_SUCCESS( 6305 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6306 6307 validate_status_exited(status, exitval2); 6308 6309 DPRINTF("Before calling %s() for the forkee - expected no " 6310 "process\n", TWAIT_FNAME); 6311 TWAIT_REQUIRE_FAILURE(ECHILD, 6312 wpid = TWAIT_GENERIC(child2, &status, 0)); 6313 } 6314 6315 DPRINTF("Before calling %s() for the child - expected stopped " 6316 "SIGCHLD\n", TWAIT_FNAME); 6317 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6318 6319 validate_status_stopped(status, SIGCHLD); 6320 6321 DPRINTF("Before resuming the child process where it left off and " 6322 "without signal to be sent\n"); 6323 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6324 6325 DPRINTF("Before calling %s() for the child - expected exited\n", 6326 TWAIT_FNAME); 6327 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6328 6329 validate_status_exited(status, exitval); 6330 6331 DPRINTF("Before calling %s() for the child - expected no process\n", 6332 TWAIT_FNAME); 6333 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6334} 6335 6336#define FORK2_TEST(name,fn,masked,ignored) \ 6337ATF_TC(name); \ 6338ATF_TC_HEAD(name, tc) \ 6339{ \ 6340 atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught " \ 6341 "regardless of signal %s%s", \ 6342 masked ? "masked" : "", ignored ? "ignored" : ""); \ 6343} \ 6344 \ 6345ATF_TC_BODY(name, tc) \ 6346{ \ 6347 \ 6348 fork2_body(fn, masked, ignored); \ 6349} 6350 6351FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false) 6352FORK2_TEST(posix_spawn_singalignored, "spawn", false, true) 6353FORK2_TEST(fork_singalmasked, "fork", true, false) 6354FORK2_TEST(fork_singalignored, "fork", false, true) 6355FORK2_TEST(vfork_singalmasked, "vfork", true, false) 6356FORK2_TEST(vfork_singalignored, "vfork", false, true) 6357FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false) 6358FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true) 6359#endif 6360 6361/// ---------------------------------------------------------------------------- 6362 6363volatile lwpid_t the_lwp_id = 0; 6364 6365static void 6366lwp_main_func(void *arg) 6367{ 6368 the_lwp_id = _lwp_self(); 6369 _lwp_exit(); 6370} 6371 6372ATF_TC(signal9); 6373ATF_TC_HEAD(signal9, tc) 6374{ 6375 atf_tc_set_md_var(tc, "descr", 6376 "Verify that masking SIGTRAP in tracee does not stop tracer from " 6377 "catching PTRACE_LWP_CREATE breakpoint"); 6378} 6379 6380ATF_TC_BODY(signal9, tc) 6381{ 6382 const int exitval = 5; 6383 const int sigval = SIGSTOP; 6384 const int sigmasked = SIGTRAP; 6385 pid_t child, wpid; 6386#if defined(TWAIT_HAVE_STATUS) 6387 int status; 6388#endif 6389 sigset_t intmask; 6390 ptrace_state_t state; 6391 const int slen = sizeof(state); 6392 ptrace_event_t event; 6393 const int elen = sizeof(event); 6394 ucontext_t uc; 6395 lwpid_t lid; 6396 static const size_t ssize = 16*1024; 6397 void *stack; 6398 6399 DPRINTF("Before forking process PID=%d\n", getpid()); 6400 SYSCALL_REQUIRE((child = fork()) != -1); 6401 if (child == 0) { 6402 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6403 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6404 6405 sigemptyset(&intmask); 6406 sigaddset(&intmask, sigmasked); 6407 sigprocmask(SIG_BLOCK, &intmask, NULL); 6408 6409 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6410 FORKEE_ASSERT(raise(sigval) == 0); 6411 6412 DPRINTF("Before allocating memory for stack in child\n"); 6413 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6414 6415 DPRINTF("Before making context for new lwp in child\n"); 6416 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 6417 6418 DPRINTF("Before creating new in child\n"); 6419 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6420 6421 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6422 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6423 6424 DPRINTF("Before verifying that reported %d and running lid %d " 6425 "are the same\n", lid, the_lwp_id); 6426 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6427 6428 DPRINTF("Before exiting of the child process\n"); 6429 _exit(exitval); 6430 } 6431 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6432 6433 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6434 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6435 6436 validate_status_stopped(status, sigval); 6437 6438 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 6439 event.pe_set_event = PTRACE_LWP_CREATE; 6440 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6441 6442 DPRINTF("Before resuming the child process where it left off and " 6443 "without signal to be sent\n"); 6444 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6445 6446 DPRINTF("Before calling %s() for the child - expected stopped " 6447 "SIGTRAP\n", TWAIT_FNAME); 6448 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6449 6450 validate_status_stopped(status, sigmasked); 6451 6452 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6453 6454 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 6455 6456 lid = state.pe_lwp; 6457 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 6458 6459 DPRINTF("Before resuming the child process where it left off and " 6460 "without signal to be sent\n"); 6461 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6462 6463 DPRINTF("Before calling %s() for the child - expected exited\n", 6464 TWAIT_FNAME); 6465 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6466 6467 validate_status_exited(status, exitval); 6468 6469 DPRINTF("Before calling %s() for the child - expected no process\n", 6470 TWAIT_FNAME); 6471 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6472} 6473 6474ATF_TC(signal10); 6475ATF_TC_HEAD(signal10, tc) 6476{ 6477 atf_tc_set_md_var(tc, "descr", 6478 "Verify that masking SIGTRAP in tracee does not stop tracer from " 6479 "catching PTRACE_LWP_EXIT breakpoint"); 6480} 6481 6482ATF_TC_BODY(signal10, tc) 6483{ 6484 const int exitval = 5; 6485 const int sigval = SIGSTOP; 6486 const int sigmasked = SIGTRAP; 6487 pid_t child, wpid; 6488#if defined(TWAIT_HAVE_STATUS) 6489 int status; 6490#endif 6491 sigset_t intmask; 6492 ptrace_state_t state; 6493 const int slen = sizeof(state); 6494 ptrace_event_t event; 6495 const int elen = sizeof(event); 6496 ucontext_t uc; 6497 lwpid_t lid; 6498 static const size_t ssize = 16*1024; 6499 void *stack; 6500 6501 DPRINTF("Before forking process PID=%d\n", getpid()); 6502 SYSCALL_REQUIRE((child = fork()) != -1); 6503 if (child == 0) { 6504 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6505 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6506 6507 sigemptyset(&intmask); 6508 sigaddset(&intmask, sigmasked); 6509 sigprocmask(SIG_BLOCK, &intmask, NULL); 6510 6511 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6512 FORKEE_ASSERT(raise(sigval) == 0); 6513 6514 DPRINTF("Before allocating memory for stack in child\n"); 6515 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6516 6517 DPRINTF("Before making context for new lwp in child\n"); 6518 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 6519 6520 DPRINTF("Before creating new in child\n"); 6521 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6522 6523 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6524 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6525 6526 DPRINTF("Before verifying that reported %d and running lid %d " 6527 "are the same\n", lid, the_lwp_id); 6528 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6529 6530 DPRINTF("Before exiting of the child process\n"); 6531 _exit(exitval); 6532 } 6533 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6534 6535 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6536 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6537 6538 validate_status_stopped(status, sigval); 6539 6540 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 6541 event.pe_set_event = PTRACE_LWP_EXIT; 6542 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6543 6544 DPRINTF("Before resuming the child process where it left off and " 6545 "without signal to be sent\n"); 6546 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6547 6548 DPRINTF("Before calling %s() for the child - expected stopped " 6549 "SIGTRAP\n", TWAIT_FNAME); 6550 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6551 6552 validate_status_stopped(status, sigmasked); 6553 6554 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6555 6556 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 6557 6558 lid = state.pe_lwp; 6559 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 6560 6561 DPRINTF("Before resuming the child process where it left off and " 6562 "without signal to be sent\n"); 6563 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6564 6565 DPRINTF("Before calling %s() for the child - expected exited\n", 6566 TWAIT_FNAME); 6567 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6568 6569 validate_status_exited(status, exitval); 6570 6571 DPRINTF("Before calling %s() for the child - expected no process\n", 6572 TWAIT_FNAME); 6573 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6574} 6575 6576static void 6577lwp_main_stop(void *arg) 6578{ 6579 the_lwp_id = _lwp_self(); 6580 6581 raise(SIGTRAP); 6582 6583 _lwp_exit(); 6584} 6585 6586ATF_TC(suspend2); 6587ATF_TC_HEAD(suspend2, tc) 6588{ 6589 atf_tc_set_md_var(tc, "descr", 6590 "Verify that the while the only thread within a process is " 6591 "suspended, the whole process cannot be unstopped"); 6592} 6593 6594ATF_TC_BODY(suspend2, tc) 6595{ 6596 const int exitval = 5; 6597 const int sigval = SIGSTOP; 6598 pid_t child, wpid; 6599#if defined(TWAIT_HAVE_STATUS) 6600 int status; 6601#endif 6602 struct ptrace_siginfo psi; 6603 6604 DPRINTF("Before forking process PID=%d\n", getpid()); 6605 SYSCALL_REQUIRE((child = fork()) != -1); 6606 if (child == 0) { 6607 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6608 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6609 6610 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6611 FORKEE_ASSERT(raise(sigval) == 0); 6612 6613 DPRINTF("Before exiting of the child process\n"); 6614 _exit(exitval); 6615 } 6616 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6617 6618 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6619 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6620 6621 validate_status_stopped(status, sigval); 6622 6623 DPRINTF("Before reading siginfo and lwpid_t\n"); 6624 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6625 6626 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6627 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6628 6629 DPRINTF("Before resuming the child process where it left off and " 6630 "without signal to be sent\n"); 6631 ATF_REQUIRE_ERRNO(EDEADLK, 6632 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 6633 6634 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6635 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6636 6637 DPRINTF("Before resuming the child process where it left off and " 6638 "without signal to be sent\n"); 6639 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6640 6641 DPRINTF("Before calling %s() for the child - expected exited\n", 6642 TWAIT_FNAME); 6643 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6644 6645 validate_status_exited(status, exitval); 6646 6647 DPRINTF("Before calling %s() for the child - expected no process\n", 6648 TWAIT_FNAME); 6649 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6650} 6651 6652ATF_TC(resume1); 6653ATF_TC_HEAD(resume1, tc) 6654{ 6655 atf_tc_set_md_var(tc, "descr", 6656 "Verify that a thread can be suspended by a debugger and later " 6657 "resumed by the debugger"); 6658} 6659 6660ATF_TC_BODY(resume1, tc) 6661{ 6662 struct msg_fds fds; 6663 const int exitval = 5; 6664 const int sigval = SIGSTOP; 6665 pid_t child, wpid; 6666 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 6667#if defined(TWAIT_HAVE_STATUS) 6668 int status; 6669#endif 6670 ucontext_t uc; 6671 lwpid_t lid; 6672 static const size_t ssize = 16*1024; 6673 void *stack; 6674 struct ptrace_lwpinfo pl; 6675 struct ptrace_siginfo psi; 6676 6677 SYSCALL_REQUIRE(msg_open(&fds) == 0); 6678 6679 DPRINTF("Before forking process PID=%d\n", getpid()); 6680 SYSCALL_REQUIRE((child = fork()) != -1); 6681 if (child == 0) { 6682 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6683 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6684 6685 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6686 FORKEE_ASSERT(raise(sigval) == 0); 6687 6688 DPRINTF("Before allocating memory for stack in child\n"); 6689 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6690 6691 DPRINTF("Before making context for new lwp in child\n"); 6692 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 6693 6694 DPRINTF("Before creating new in child\n"); 6695 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6696 6697 CHILD_TO_PARENT("Message", fds, msg); 6698 6699 raise(SIGINT); 6700 6701 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6702 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6703 6704 DPRINTF("Before verifying that reported %d and running lid %d " 6705 "are the same\n", lid, the_lwp_id); 6706 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6707 6708 DPRINTF("Before exiting of the child process\n"); 6709 _exit(exitval); 6710 } 6711 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6712 6713 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6714 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6715 6716 validate_status_stopped(status, sigval); 6717 6718 DPRINTF("Before resuming the child process where it left off and " 6719 "without signal to be sent\n"); 6720 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6721 6722 DPRINTF("Before calling %s() for the child - expected stopped " 6723 "SIGTRAP\n", TWAIT_FNAME); 6724 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6725 6726 validate_status_stopped(status, SIGTRAP); 6727 6728 DPRINTF("Before reading siginfo and lwpid_t\n"); 6729 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6730 6731 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6732 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6733 6734 PARENT_FROM_CHILD("Message", fds, msg); 6735 6736 DPRINTF("Before resuming the child process where it left off and " 6737 "without signal to be sent\n"); 6738 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6739 6740 DPRINTF("Before calling %s() for the child - expected stopped " 6741 "SIGINT\n", TWAIT_FNAME); 6742 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6743 6744 validate_status_stopped(status, SIGINT); 6745 6746 pl.pl_lwpid = 0; 6747 6748 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6749 while (pl.pl_lwpid != 0) { 6750 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6751 switch (pl.pl_lwpid) { 6752 case 1: 6753 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 6754 break; 6755 case 2: 6756 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 6757 break; 6758 } 6759 } 6760 6761 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6762 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6763 6764 DPRINTF("Before resuming the child process where it left off and " 6765 "without signal to be sent\n"); 6766 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6767 6768 DPRINTF("Before calling %s() for the child - expected exited\n", 6769 TWAIT_FNAME); 6770 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6771 6772 validate_status_exited(status, exitval); 6773 6774 DPRINTF("Before calling %s() for the child - expected no process\n", 6775 TWAIT_FNAME); 6776 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6777 6778 msg_close(&fds); 6779} 6780 6781ATF_TC(syscall1); 6782ATF_TC_HEAD(syscall1, tc) 6783{ 6784 atf_tc_set_md_var(tc, "descr", 6785 "Verify that getpid(2) can be traced with PT_SYSCALL"); 6786} 6787 6788ATF_TC_BODY(syscall1, tc) 6789{ 6790 const int exitval = 5; 6791 const int sigval = SIGSTOP; 6792 pid_t child, wpid; 6793#if defined(TWAIT_HAVE_STATUS) 6794 int status; 6795#endif 6796 struct ptrace_siginfo info; 6797 memset(&info, 0, sizeof(info)); 6798 6799 DPRINTF("Before forking process PID=%d\n", getpid()); 6800 SYSCALL_REQUIRE((child = fork()) != -1); 6801 if (child == 0) { 6802 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6803 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6804 6805 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6806 FORKEE_ASSERT(raise(sigval) == 0); 6807 6808 syscall(SYS_getpid); 6809 6810 DPRINTF("Before exiting of the child process\n"); 6811 _exit(exitval); 6812 } 6813 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6814 6815 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6816 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6817 6818 validate_status_stopped(status, sigval); 6819 6820 DPRINTF("Before resuming the child process where it left off and " 6821 "without signal to be sent\n"); 6822 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6823 6824 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6825 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6826 6827 validate_status_stopped(status, SIGTRAP); 6828 6829 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6830 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6831 6832 DPRINTF("Before checking siginfo_t and lwpid\n"); 6833 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6834 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6835 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 6836 6837 DPRINTF("Before resuming the child process where it left off and " 6838 "without signal to be sent\n"); 6839 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6840 6841 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6842 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6843 6844 validate_status_stopped(status, SIGTRAP); 6845 6846 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6847 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6848 6849 DPRINTF("Before checking siginfo_t and lwpid\n"); 6850 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6851 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6852 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 6853 6854 DPRINTF("Before resuming the child process where it left off and " 6855 "without signal to be sent\n"); 6856 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6857 6858 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6859 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6860 6861 validate_status_exited(status, exitval); 6862 6863 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6864 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6865} 6866 6867ATF_TC(syscallemu1); 6868ATF_TC_HEAD(syscallemu1, tc) 6869{ 6870 atf_tc_set_md_var(tc, "descr", 6871 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 6872} 6873 6874ATF_TC_BODY(syscallemu1, tc) 6875{ 6876 const int exitval = 5; 6877 const int sigval = SIGSTOP; 6878 pid_t child, wpid; 6879#if defined(TWAIT_HAVE_STATUS) 6880 int status; 6881#endif 6882 6883#if defined(__sparc__) && !defined(__sparc64__) 6884 /* syscallemu does not work on sparc (32-bit) */ 6885 atf_tc_expect_fail("PR kern/52166"); 6886#endif 6887 6888 DPRINTF("Before forking process PID=%d\n", getpid()); 6889 SYSCALL_REQUIRE((child = fork()) != -1); 6890 if (child == 0) { 6891 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6892 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6893 6894 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6895 FORKEE_ASSERT(raise(sigval) == 0); 6896 6897 syscall(SYS_exit, 100); 6898 6899 DPRINTF("Before exiting of the child process\n"); 6900 _exit(exitval); 6901 } 6902 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6903 6904 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6905 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6906 6907 validate_status_stopped(status, sigval); 6908 6909 DPRINTF("Before resuming the child process where it left off and " 6910 "without signal to be sent\n"); 6911 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6912 6913 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6914 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6915 6916 validate_status_stopped(status, SIGTRAP); 6917 6918 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 6919 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 6920 6921 DPRINTF("Before resuming the child process where it left off and " 6922 "without signal to be sent\n"); 6923 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6924 6925 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6926 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6927 6928 validate_status_stopped(status, SIGTRAP); 6929 6930 DPRINTF("Before resuming the child process where it left off and " 6931 "without signal to be sent\n"); 6932 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6933 6934 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6935 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6936 6937 validate_status_exited(status, exitval); 6938 6939 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6940 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6941} 6942 6943/// ---------------------------------------------------------------------------- 6944 6945static void 6946clone_body(int flags, bool trackfork, bool trackvfork, 6947 bool trackvforkdone) 6948{ 6949 const int exitval = 5; 6950 const int exitval2 = 15; 6951 const int sigval = SIGSTOP; 6952 pid_t child, child2 = 0, wpid; 6953#if defined(TWAIT_HAVE_STATUS) 6954 int status; 6955#endif 6956 ptrace_state_t state; 6957 const int slen = sizeof(state); 6958 ptrace_event_t event; 6959 const int elen = sizeof(event); 6960 6961 const size_t stack_size = 1024 * 1024; 6962 void *stack, *stack_base; 6963 6964 stack = malloc(stack_size); 6965 ATF_REQUIRE(stack != NULL); 6966 6967#ifdef __MACHINE_STACK_GROWS_UP 6968 stack_base = stack; 6969#else 6970 stack_base = (char *)stack + stack_size; 6971#endif 6972 6973 DPRINTF("Before forking process PID=%d\n", getpid()); 6974 SYSCALL_REQUIRE((child = fork()) != -1); 6975 if (child == 0) { 6976 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6977 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6978 6979 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6980 FORKEE_ASSERT(raise(sigval) == 0); 6981 6982 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 6983 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 6984 6985 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 6986 child2); 6987 6988 // XXX WALLSIG? 6989 FORKEE_REQUIRE_SUCCESS 6990 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 6991 6992 forkee_status_exited(status, exitval2); 6993 6994 DPRINTF("Before exiting of the child process\n"); 6995 _exit(exitval); 6996 } 6997 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6998 6999 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7000 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7001 7002 validate_status_stopped(status, sigval); 7003 7004 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 7005 trackfork ? "|PTRACE_FORK" : "", 7006 trackvfork ? "|PTRACE_VFORK" : "", 7007 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 7008 event.pe_set_event = 0; 7009 if (trackfork) 7010 event.pe_set_event |= PTRACE_FORK; 7011 if (trackvfork) 7012 event.pe_set_event |= PTRACE_VFORK; 7013 if (trackvforkdone) 7014 event.pe_set_event |= PTRACE_VFORK_DONE; 7015 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7016 7017 DPRINTF("Before resuming the child process where it left off and " 7018 "without signal to be sent\n"); 7019 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7020 7021#if defined(TWAIT_HAVE_PID) 7022 if ((trackfork && !(flags & CLONE_VFORK)) || 7023 (trackvfork && (flags & CLONE_VFORK))) { 7024 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7025 child); 7026 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7027 child); 7028 7029 validate_status_stopped(status, SIGTRAP); 7030 7031 SYSCALL_REQUIRE( 7032 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7033 if (trackfork && !(flags & CLONE_VFORK)) { 7034 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7035 PTRACE_FORK); 7036 } 7037 if (trackvfork && (flags & CLONE_VFORK)) { 7038 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7039 PTRACE_VFORK); 7040 } 7041 7042 child2 = state.pe_other_pid; 7043 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7044 7045 DPRINTF("Before calling %s() for the forkee %d of the child " 7046 "%d\n", TWAIT_FNAME, child2, child); 7047 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7048 child2); 7049 7050 validate_status_stopped(status, SIGTRAP); 7051 7052 SYSCALL_REQUIRE( 7053 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7054 if (trackfork && !(flags & CLONE_VFORK)) { 7055 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7056 PTRACE_FORK); 7057 } 7058 if (trackvfork && (flags & CLONE_VFORK)) { 7059 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7060 PTRACE_VFORK); 7061 } 7062 7063 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7064 7065 DPRINTF("Before resuming the forkee process where it left off " 7066 "and without signal to be sent\n"); 7067 SYSCALL_REQUIRE( 7068 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7069 7070 DPRINTF("Before resuming the child process where it left off " 7071 "and without signal to be sent\n"); 7072 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7073 } 7074#endif 7075 7076 if (trackvforkdone && (flags & CLONE_VFORK)) { 7077 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7078 child); 7079 TWAIT_REQUIRE_SUCCESS( 7080 wpid = TWAIT_GENERIC(child, &status, 0), child); 7081 7082 validate_status_stopped(status, SIGTRAP); 7083 7084 SYSCALL_REQUIRE( 7085 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7086 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7087 7088 child2 = state.pe_other_pid; 7089 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7090 child2); 7091 7092 DPRINTF("Before resuming the child process where it left off " 7093 "and without signal to be sent\n"); 7094 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7095 } 7096 7097#if defined(TWAIT_HAVE_PID) 7098 if ((trackfork && !(flags & CLONE_VFORK)) || 7099 (trackvfork && (flags & CLONE_VFORK))) { 7100 DPRINTF("Before calling %s() for the forkee - expected exited" 7101 "\n", TWAIT_FNAME); 7102 TWAIT_REQUIRE_SUCCESS( 7103 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7104 7105 validate_status_exited(status, exitval2); 7106 7107 DPRINTF("Before calling %s() for the forkee - expected no " 7108 "process\n", TWAIT_FNAME); 7109 TWAIT_REQUIRE_FAILURE(ECHILD, 7110 wpid = TWAIT_GENERIC(child2, &status, 0)); 7111 } 7112#endif 7113 7114 DPRINTF("Before calling %s() for the child - expected stopped " 7115 "SIGCHLD\n", TWAIT_FNAME); 7116 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7117 7118 validate_status_stopped(status, SIGCHLD); 7119 7120 DPRINTF("Before resuming the child process where it left off and " 7121 "without signal to be sent\n"); 7122 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7123 7124 DPRINTF("Before calling %s() for the child - expected exited\n", 7125 TWAIT_FNAME); 7126 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7127 7128 validate_status_exited(status, exitval); 7129 7130 DPRINTF("Before calling %s() for the child - expected no process\n", 7131 TWAIT_FNAME); 7132 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7133} 7134 7135#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \ 7136ATF_TC(name); \ 7137ATF_TC_HEAD(name, tc) \ 7138{ \ 7139 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \ 7140 "called with 0%s%s%s in EVENT_MASK", \ 7141 #flags, \ 7142 tfork ? "|PTRACE_FORK" : "", \ 7143 tvfork ? "|PTRACE_VFORK" : "", \ 7144 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 7145} \ 7146 \ 7147ATF_TC_BODY(name, tc) \ 7148{ \ 7149 \ 7150 clone_body(flags, tfork, tvfork, tvforkdone); \ 7151} 7152 7153CLONE_TEST(clone1, 0, false, false, false) 7154#if defined(TWAIT_HAVE_PID) 7155CLONE_TEST(clone2, 0, true, false, false) 7156CLONE_TEST(clone3, 0, false, true, false) 7157CLONE_TEST(clone4, 0, true, true, false) 7158#endif 7159CLONE_TEST(clone5, 0, false, false, true) 7160#if defined(TWAIT_HAVE_PID) 7161CLONE_TEST(clone6, 0, true, false, true) 7162CLONE_TEST(clone7, 0, false, true, true) 7163CLONE_TEST(clone8, 0, true, true, true) 7164#endif 7165 7166CLONE_TEST(clone_vm1, CLONE_VM, false, false, false) 7167#if defined(TWAIT_HAVE_PID) 7168CLONE_TEST(clone_vm2, CLONE_VM, true, false, false) 7169CLONE_TEST(clone_vm3, CLONE_VM, false, true, false) 7170CLONE_TEST(clone_vm4, CLONE_VM, true, true, false) 7171#endif 7172CLONE_TEST(clone_vm5, CLONE_VM, false, false, true) 7173#if defined(TWAIT_HAVE_PID) 7174CLONE_TEST(clone_vm6, CLONE_VM, true, false, true) 7175CLONE_TEST(clone_vm7, CLONE_VM, false, true, true) 7176CLONE_TEST(clone_vm8, CLONE_VM, true, true, true) 7177#endif 7178 7179CLONE_TEST(clone_fs1, CLONE_FS, false, false, false) 7180#if defined(TWAIT_HAVE_PID) 7181CLONE_TEST(clone_fs2, CLONE_FS, true, false, false) 7182CLONE_TEST(clone_fs3, CLONE_FS, false, true, false) 7183CLONE_TEST(clone_fs4, CLONE_FS, true, true, false) 7184#endif 7185CLONE_TEST(clone_fs5, CLONE_FS, false, false, true) 7186#if defined(TWAIT_HAVE_PID) 7187CLONE_TEST(clone_fs6, CLONE_FS, true, false, true) 7188CLONE_TEST(clone_fs7, CLONE_FS, false, true, true) 7189CLONE_TEST(clone_fs8, CLONE_FS, true, true, true) 7190#endif 7191 7192CLONE_TEST(clone_files1, CLONE_FILES, false, false, false) 7193#if defined(TWAIT_HAVE_PID) 7194CLONE_TEST(clone_files2, CLONE_FILES, true, false, false) 7195CLONE_TEST(clone_files3, CLONE_FILES, false, true, false) 7196CLONE_TEST(clone_files4, CLONE_FILES, true, true, false) 7197#endif 7198CLONE_TEST(clone_files5, CLONE_FILES, false, false, true) 7199#if defined(TWAIT_HAVE_PID) 7200CLONE_TEST(clone_files6, CLONE_FILES, true, false, true) 7201CLONE_TEST(clone_files7, CLONE_FILES, false, true, true) 7202CLONE_TEST(clone_files8, CLONE_FILES, true, true, true) 7203#endif 7204 7205//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false) 7206#if defined(TWAIT_HAVE_PID) 7207//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false) 7208//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false) 7209//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false) 7210#endif 7211//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true) 7212#if defined(TWAIT_HAVE_PID) 7213//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true) 7214//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true) 7215//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true) 7216#endif 7217 7218CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false) 7219#if defined(TWAIT_HAVE_PID) 7220CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false) 7221CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false) 7222CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false) 7223#endif 7224CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true) 7225#if defined(TWAIT_HAVE_PID) 7226CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true) 7227CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true) 7228CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true) 7229#endif 7230 7231/// ---------------------------------------------------------------------------- 7232 7233#if defined(TWAIT_HAVE_PID) 7234static void 7235clone_body2(int flags, bool masked, bool ignored) 7236{ 7237 const int exitval = 5; 7238 const int exitval2 = 15; 7239 const int sigval = SIGSTOP; 7240 pid_t child, child2 = 0, wpid; 7241#if defined(TWAIT_HAVE_STATUS) 7242 int status; 7243#endif 7244 ptrace_state_t state; 7245 const int slen = sizeof(state); 7246 ptrace_event_t event; 7247 const int elen = sizeof(event); 7248 struct sigaction sa; 7249 struct ptrace_siginfo info; 7250 sigset_t intmask; 7251 struct kinfo_proc2 kp; 7252 size_t len = sizeof(kp); 7253 7254 int name[6]; 7255 const size_t namelen = __arraycount(name); 7256 ki_sigset_t kp_sigmask; 7257 ki_sigset_t kp_sigignore; 7258 7259 const size_t stack_size = 1024 * 1024; 7260 void *stack, *stack_base; 7261 7262 stack = malloc(stack_size); 7263 ATF_REQUIRE(stack != NULL); 7264 7265#ifdef __MACHINE_STACK_GROWS_UP 7266 stack_base = stack; 7267#else 7268 stack_base = (char *)stack + stack_size; 7269#endif 7270 7271 SYSCALL_REQUIRE((child = fork()) != -1); 7272 if (child == 0) { 7273 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7274 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7275 7276 if (masked) { 7277 sigemptyset(&intmask); 7278 sigaddset(&intmask, SIGTRAP); 7279 sigprocmask(SIG_BLOCK, &intmask, NULL); 7280 } 7281 7282 if (ignored) { 7283 memset(&sa, 0, sizeof(sa)); 7284 sa.sa_handler = SIG_IGN; 7285 sigemptyset(&sa.sa_mask); 7286 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 7287 } 7288 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7289 FORKEE_ASSERT(raise(sigval) == 0); 7290 7291 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7292 flags); 7293 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7294 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7295 7296 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7297 child2); 7298 7299 // XXX WALLSIG? 7300 FORKEE_REQUIRE_SUCCESS 7301 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7302 7303 forkee_status_exited(status, exitval2); 7304 7305 DPRINTF("Before exiting of the child process\n"); 7306 _exit(exitval); 7307 } 7308 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7309 7310 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7311 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7312 7313 validate_status_stopped(status, sigval); 7314 7315 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7316 SYSCALL_REQUIRE( 7317 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7318 7319 DPRINTF("Before checking siginfo_t\n"); 7320 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7321 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7322 7323 name[0] = CTL_KERN, 7324 name[1] = KERN_PROC2, 7325 name[2] = KERN_PROC_PID; 7326 name[3] = child; 7327 name[4] = sizeof(kp); 7328 name[5] = 1; 7329 7330 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7331 7332 if (masked) 7333 kp_sigmask = kp.p_sigmask; 7334 7335 if (ignored) 7336 kp_sigignore = kp.p_sigignore; 7337 7338 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in " 7339 "EVENT_MASK for the child %d\n", child); 7340 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; 7341 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7342 7343 DPRINTF("Before resuming the child process where it left off and " 7344 "without signal to be sent\n"); 7345 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7346 7347 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7348 child); 7349 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7350 child); 7351 7352 validate_status_stopped(status, SIGTRAP); 7353 7354 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7355 7356 if (masked) { 7357 DPRINTF("kp_sigmask=" 7358 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7359 PRIx32 "\n", 7360 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7361 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7362 7363 DPRINTF("kp.p_sigmask=" 7364 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7365 PRIx32 "\n", 7366 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7367 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7368 7369 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7370 sizeof(kp_sigmask))); 7371 } 7372 7373 if (ignored) { 7374 DPRINTF("kp_sigignore=" 7375 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7376 PRIx32 "\n", 7377 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7378 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7379 7380 DPRINTF("kp.p_sigignore=" 7381 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7382 PRIx32 "\n", 7383 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7384 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7385 7386 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7387 sizeof(kp_sigignore))); 7388 } 7389 7390 SYSCALL_REQUIRE( 7391 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7392 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event, 7393 child2); 7394 if (!(flags & CLONE_VFORK)) { 7395 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7396 PTRACE_FORK); 7397 } else { 7398 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7399 PTRACE_VFORK); 7400 } 7401 7402 child2 = state.pe_other_pid; 7403 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7404 7405 DPRINTF("Before calling %s() for the forkee %d of the child " 7406 "%d\n", TWAIT_FNAME, child2, child); 7407 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7408 child2); 7409 7410 validate_status_stopped(status, SIGTRAP); 7411 7412 name[3] = child2; 7413 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7414 7415 if (masked) { 7416 DPRINTF("kp_sigmask=" 7417 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7418 PRIx32 "\n", 7419 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7420 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7421 7422 DPRINTF("kp.p_sigmask=" 7423 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7424 PRIx32 "\n", 7425 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7426 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7427 7428 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7429 sizeof(kp_sigmask))); 7430 } 7431 7432 if (ignored) { 7433 DPRINTF("kp_sigignore=" 7434 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7435 PRIx32 "\n", 7436 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7437 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7438 7439 DPRINTF("kp.p_sigignore=" 7440 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7441 PRIx32 "\n", 7442 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7443 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7444 7445 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7446 sizeof(kp_sigignore))); 7447 } 7448 7449 SYSCALL_REQUIRE( 7450 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7451 if (!(flags & CLONE_VFORK)) { 7452 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7453 PTRACE_FORK); 7454 } else { 7455 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7456 PTRACE_VFORK); 7457 } 7458 7459 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7460 7461 DPRINTF("Before resuming the forkee process where it left off " 7462 "and without signal to be sent\n"); 7463 SYSCALL_REQUIRE( 7464 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7465 7466 DPRINTF("Before resuming the child process where it left off " 7467 "and without signal to be sent\n"); 7468 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7469 7470 if (flags & CLONE_VFORK) { 7471 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7472 child); 7473 TWAIT_REQUIRE_SUCCESS( 7474 wpid = TWAIT_GENERIC(child, &status, 0), child); 7475 7476 validate_status_stopped(status, SIGTRAP); 7477 7478 name[3] = child; 7479 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7480 7481 /* 7482 * SIGCHLD is now pending in the signal queue and 7483 * the kernel presents it to userland as a masked signal. 7484 */ 7485 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 7486 7487 if (masked) { 7488 DPRINTF("kp_sigmask=" 7489 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7490 PRIx32 "\n", 7491 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7492 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7493 7494 DPRINTF("kp.p_sigmask=" 7495 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7496 PRIx32 "\n", 7497 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7498 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7499 7500 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7501 sizeof(kp_sigmask))); 7502 } 7503 7504 if (ignored) { 7505 DPRINTF("kp_sigignore=" 7506 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7507 PRIx32 "\n", 7508 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7509 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7510 7511 DPRINTF("kp.p_sigignore=" 7512 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7513 PRIx32 "\n", 7514 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7515 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7516 7517 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7518 sizeof(kp_sigignore))); 7519 } 7520 7521 SYSCALL_REQUIRE( 7522 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7523 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7524 7525 child2 = state.pe_other_pid; 7526 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7527 child2); 7528 7529 DPRINTF("Before resuming the child process where it left off " 7530 "and without signal to be sent\n"); 7531 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7532 } 7533 7534 DPRINTF("Before calling %s() for the forkee - expected exited" 7535 "\n", TWAIT_FNAME); 7536 TWAIT_REQUIRE_SUCCESS( 7537 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7538 7539 validate_status_exited(status, exitval2); 7540 7541 DPRINTF("Before calling %s() for the forkee - expected no " 7542 "process\n", TWAIT_FNAME); 7543 TWAIT_REQUIRE_FAILURE(ECHILD, 7544 wpid = TWAIT_GENERIC(child2, &status, 0)); 7545 7546 DPRINTF("Before calling %s() for the child - expected stopped " 7547 "SIGCHLD\n", TWAIT_FNAME); 7548 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7549 7550 validate_status_stopped(status, SIGCHLD); 7551 7552 DPRINTF("Before resuming the child process where it left off and " 7553 "without signal to be sent\n"); 7554 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7555 7556 DPRINTF("Before calling %s() for the child - expected exited\n", 7557 TWAIT_FNAME); 7558 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7559 7560 validate_status_exited(status, exitval); 7561 7562 DPRINTF("Before calling %s() for the child - expected no process\n", 7563 TWAIT_FNAME); 7564 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7565} 7566 7567#define CLONE_TEST2(name,flags,masked,ignored) \ 7568ATF_TC(name); \ 7569ATF_TC_HEAD(name, tc) \ 7570{ \ 7571 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\ 7572 " regardless of signal %s%s", \ 7573 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \ 7574} \ 7575 \ 7576ATF_TC_BODY(name, tc) \ 7577{ \ 7578 \ 7579 clone_body2(flags, masked, ignored); \ 7580} 7581 7582CLONE_TEST2(clone_signalignored, 0, true, false) 7583CLONE_TEST2(clone_signalmasked, 0, false, true) 7584CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false) 7585CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true) 7586CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false) 7587CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true) 7588CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false) 7589CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true) 7590//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX 7591//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX 7592CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false) 7593CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true) 7594#endif 7595 7596/// ---------------------------------------------------------------------------- 7597 7598#if defined(TWAIT_HAVE_PID) 7599static void 7600traceme_vfork_clone_body(int flags) 7601{ 7602 const int exitval = 5; 7603 const int exitval2 = 15; 7604 pid_t child, child2 = 0, wpid; 7605#if defined(TWAIT_HAVE_STATUS) 7606 int status; 7607#endif 7608 7609 const size_t stack_size = 1024 * 1024; 7610 void *stack, *stack_base; 7611 7612 stack = malloc(stack_size); 7613 ATF_REQUIRE(stack != NULL); 7614 7615#ifdef __MACHINE_STACK_GROWS_UP 7616 stack_base = stack; 7617#else 7618 stack_base = (char *)stack + stack_size; 7619#endif 7620 7621 SYSCALL_REQUIRE((child = vfork()) != -1); 7622 if (child == 0) { 7623 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7624 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7625 7626 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7627 flags); 7628 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7629 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7630 7631 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7632 child2); 7633 7634 // XXX WALLSIG? 7635 FORKEE_REQUIRE_SUCCESS 7636 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7637 7638 forkee_status_exited(status, exitval2); 7639 7640 DPRINTF("Before exiting of the child process\n"); 7641 _exit(exitval); 7642 } 7643 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7644 7645 DPRINTF("Before calling %s() for the child - expected exited\n", 7646 TWAIT_FNAME); 7647 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7648 7649 validate_status_exited(status, exitval); 7650 7651 DPRINTF("Before calling %s() for the child - expected no process\n", 7652 TWAIT_FNAME); 7653 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7654} 7655 7656#define TRACEME_VFORK_CLONE_TEST(name,flags) \ 7657ATF_TC(name); \ 7658ATF_TC_HEAD(name, tc) \ 7659{ \ 7660 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \ 7661 "handled correctly with vfork(2)ed tracer", \ 7662 #flags); \ 7663} \ 7664 \ 7665ATF_TC_BODY(name, tc) \ 7666{ \ 7667 \ 7668 traceme_vfork_clone_body(flags); \ 7669} 7670 7671TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0) 7672TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM) 7673TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS) 7674TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES) 7675//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX 7676TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK) 7677#endif 7678 7679/// ---------------------------------------------------------------------------- 7680 7681static void 7682user_va0_disable(int operation) 7683{ 7684 pid_t child, wpid; 7685#if defined(TWAIT_HAVE_STATUS) 7686 int status; 7687#endif 7688 const int sigval = SIGSTOP; 7689 int rv; 7690 7691 struct ptrace_siginfo info; 7692 7693 if (get_user_va0_disable() == 0) 7694 atf_tc_skip("vm.user_va0_disable is set to 0"); 7695 7696 memset(&info, 0, sizeof(info)); 7697 7698 DPRINTF("Before forking process PID=%d\n", getpid()); 7699 SYSCALL_REQUIRE((child = fork()) != -1); 7700 if (child == 0) { 7701 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7702 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7703 7704 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7705 FORKEE_ASSERT(raise(sigval) == 0); 7706 7707 /* NOTREACHED */ 7708 FORKEE_ASSERTX(0 && "This shall not be reached"); 7709 __unreachable(); 7710 } 7711 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7712 7713 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7714 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7715 7716 validate_status_stopped(status, sigval); 7717 7718 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7719 "child\n"); 7720 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 7721 sizeof(info)) != -1); 7722 7723 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7724 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7725 "si_errno=%#x\n", 7726 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7727 info.psi_siginfo.si_errno); 7728 7729 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7730 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7731 7732 DPRINTF("Before resuming the child process in PC=0x0 " 7733 "and without signal to be sent\n"); 7734 errno = 0; 7735 rv = ptrace(operation, child, (void *)0, 0); 7736 ATF_REQUIRE_EQ(errno, EINVAL); 7737 ATF_REQUIRE_EQ(rv, -1); 7738 7739 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 7740 7741 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7742 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7743 validate_status_signaled(status, SIGKILL, 0); 7744 7745 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7746 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7747} 7748 7749#define USER_VA0_DISABLE(test, operation) \ 7750ATF_TC(test); \ 7751ATF_TC_HEAD(test, tc) \ 7752{ \ 7753 atf_tc_set_md_var(tc, "descr", \ 7754 "Verify behavior of " #operation " with PC set to 0x0"); \ 7755} \ 7756 \ 7757ATF_TC_BODY(test, tc) \ 7758{ \ 7759 \ 7760 user_va0_disable(operation); \ 7761} 7762 7763USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 7764USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 7765USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 7766 7767/// ---------------------------------------------------------------------------- 7768 7769/* 7770 * Parse the core file and find the requested note. If the reading or parsing 7771 * fails, the test is failed. If the note is found, it is read onto buf, up to 7772 * buf_len. The actual length of the note is returned (which can be greater 7773 * than buf_len, indicating that it has been truncated). If the note is not 7774 * found, -1 is returned. 7775 */ 7776static ssize_t core_find_note(const char *core_path, 7777 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 7778{ 7779 int core_fd; 7780 Elf *core_elf; 7781 size_t core_numhdr, i; 7782 ssize_t ret = -1; 7783 /* note: we assume note name will be null-terminated */ 7784 size_t name_len = strlen(note_name) + 1; 7785 7786 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 7787 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 7788 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 7789 7790 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 7791 for (i = 0; i < core_numhdr && ret == -1; i++) { 7792 GElf_Phdr core_hdr; 7793 size_t offset; 7794 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 7795 if (core_hdr.p_type != PT_NOTE) 7796 continue; 7797 7798 for (offset = core_hdr.p_offset; 7799 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 7800 Elf64_Nhdr note_hdr; 7801 char name_buf[64]; 7802 7803 switch (gelf_getclass(core_elf)) { 7804 case ELFCLASS64: 7805 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 7806 sizeof(note_hdr), offset) 7807 == sizeof(note_hdr)); 7808 offset += sizeof(note_hdr); 7809 break; 7810 case ELFCLASS32: 7811 { 7812 Elf32_Nhdr tmp_hdr; 7813 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 7814 sizeof(tmp_hdr), offset) 7815 == sizeof(tmp_hdr)); 7816 offset += sizeof(tmp_hdr); 7817 note_hdr.n_namesz = tmp_hdr.n_namesz; 7818 note_hdr.n_descsz = tmp_hdr.n_descsz; 7819 note_hdr.n_type = tmp_hdr.n_type; 7820 } 7821 break; 7822 } 7823 7824 /* indicates end of notes */ 7825 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 7826 break; 7827 if (note_hdr.n_namesz == name_len && 7828 note_hdr.n_namesz <= sizeof(name_buf)) { 7829 SYSCALL_REQUIRE(pread(core_fd, name_buf, 7830 note_hdr.n_namesz, offset) 7831 == (ssize_t)(size_t)note_hdr.n_namesz); 7832 7833 if (!strncmp(note_name, name_buf, name_len) && 7834 note_hdr.n_type == note_type) 7835 ret = note_hdr.n_descsz; 7836 } 7837 7838 offset += note_hdr.n_namesz; 7839 /* fix to alignment */ 7840 offset = ((offset + core_hdr.p_align - 1) 7841 / core_hdr.p_align) * core_hdr.p_align; 7842 7843 /* if name & type matched above */ 7844 if (ret != -1) { 7845 ssize_t read_len = MIN(buf_len, 7846 note_hdr.n_descsz); 7847 SYSCALL_REQUIRE(pread(core_fd, buf, 7848 read_len, offset) == read_len); 7849 break; 7850 } 7851 7852 offset += note_hdr.n_descsz; 7853 } 7854 } 7855 7856 elf_end(core_elf); 7857 close(core_fd); 7858 7859 return ret; 7860} 7861 7862ATF_TC(core_dump_procinfo); 7863ATF_TC_HEAD(core_dump_procinfo, tc) 7864{ 7865 atf_tc_set_md_var(tc, "descr", 7866 "Trigger a core dump and verify its contents."); 7867} 7868 7869ATF_TC_BODY(core_dump_procinfo, tc) 7870{ 7871 const int exitval = 5; 7872 pid_t child, wpid; 7873#if defined(TWAIT_HAVE_STATUS) 7874 const int sigval = SIGTRAP; 7875 int status; 7876#endif 7877 char core_path[] = "/tmp/core.XXXXXX"; 7878 int core_fd; 7879 struct netbsd_elfcore_procinfo procinfo; 7880 7881 DPRINTF("Before forking process PID=%d\n", getpid()); 7882 SYSCALL_REQUIRE((child = fork()) != -1); 7883 if (child == 0) { 7884 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7885 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7886 7887 DPRINTF("Before triggering SIGTRAP\n"); 7888 trigger_trap(); 7889 7890 DPRINTF("Before exiting of the child process\n"); 7891 _exit(exitval); 7892 } 7893 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7894 7895 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7896 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7897 7898 validate_status_stopped(status, sigval); 7899 7900 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 7901 close(core_fd); 7902 7903 DPRINTF("Call DUMPCORE for the child process\n"); 7904 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 7905 != -1); 7906 7907 DPRINTF("Read core file\n"); 7908 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 7909 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 7910 sizeof(procinfo)); 7911 7912 ATF_CHECK_EQ(procinfo.cpi_version, 1); 7913 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 7914 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 7915 ATF_CHECK_EQ(procinfo.cpi_pid, child); 7916 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 7917 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 7918 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 7919 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 7920 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 7921 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 7922 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 7923 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 7924 ATF_CHECK_EQ(procinfo.cpi_siglwp, 1); 7925 7926 unlink(core_path); 7927 7928 DPRINTF("Before resuming the child process where it left off and " 7929 "without signal to be sent\n"); 7930 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7931 7932 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7933 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7934 7935 validate_status_exited(status, exitval); 7936 7937 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7938 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7939} 7940 7941/// ---------------------------------------------------------------------------- 7942 7943#if defined(TWAIT_HAVE_STATUS) 7944 7945ATF_TC(thread_concurrent_signals); 7946ATF_TC_HEAD(thread_concurrent_signals, tc) 7947{ 7948 atf_tc_set_md_var(tc, "descr", 7949 "Verify that concurrent signals issued to a single thread " 7950 "are reported correctly"); 7951} 7952 7953/* List of signals to use for the test */ 7954const int thread_concurrent_signals_list[] = { 7955 SIGIO, 7956 SIGXCPU, 7957 SIGXFSZ, 7958 SIGVTALRM, 7959 SIGPROF, 7960 SIGWINCH, 7961 SIGINFO, 7962 SIGUSR1, 7963 SIGUSR2 7964}; 7965 7966pthread_barrier_t thread_concurrent_signals_barrier; 7967 7968static void * 7969thread_concurrent_signals_thread(void *arg) 7970{ 7971 int sigval = thread_concurrent_signals_list[ 7972 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 7973 pthread_barrier_wait(&thread_concurrent_signals_barrier); 7974 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 7975 _lwp_self()); 7976 pthread_kill(pthread_self(), sigval); 7977 return NULL; 7978} 7979 7980#define THREAD_CONCURRENT_SIGNALS_NUM 50 7981 7982ATF_TC_BODY(thread_concurrent_signals, tc) 7983{ 7984 const int exitval = 5; 7985 const int sigval = SIGSTOP; 7986 pid_t child, wpid; 7987 int status; 7988 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 7989 = {{0, 0}}; 7990 unsigned int i; 7991 7992 DPRINTF("Before forking process PID=%d\n", getpid()); 7993 SYSCALL_REQUIRE((child = fork()) != -1); 7994 if (child == 0) { 7995 pthread_t threads[THREAD_CONCURRENT_SIGNALS_NUM]; 7996 7997 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7998 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7999 8000 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8001 FORKEE_ASSERT(raise(sigval) == 0); 8002 8003 DPRINTF("Before starting threads from the child\n"); 8004 FORKEE_ASSERT(pthread_barrier_init( 8005 &thread_concurrent_signals_barrier, NULL, 8006 __arraycount(threads)) == 0); 8007 8008 for (i = 0; i < __arraycount(threads); i++) { 8009 FORKEE_ASSERT(pthread_create(&threads[i], NULL, 8010 thread_concurrent_signals_thread, NULL) == 0); 8011 } 8012 8013 DPRINTF("Before joining threads from the child\n"); 8014 for (i = 0; i < __arraycount(threads); i++) { 8015 FORKEE_ASSERT(pthread_join(threads[i], NULL) == 0); 8016 } 8017 8018 FORKEE_ASSERT(pthread_barrier_destroy( 8019 &thread_concurrent_signals_barrier) == 0); 8020 8021 DPRINTF("Before exiting of the child process\n"); 8022 _exit(exitval); 8023 } 8024 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8025 8026 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8027 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8028 8029 validate_status_stopped(status, sigval); 8030 8031 DPRINTF("Before resuming the child process where it left off\n"); 8032 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8033 8034 DPRINTF("Before entering signal collection loop\n"); 8035 while (1) { 8036 ptrace_siginfo_t info; 8037 int expected_sig; 8038 8039 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8040 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 8041 child); 8042 if (WIFEXITED(status)) 8043 break; 8044 /* Note: we use validate_status_stopped() to get nice error 8045 * message. Signal is irrelevant since it won't be reached. 8046 */ 8047 else if (!WIFSTOPPED(status)) 8048 validate_status_stopped(status, 0); 8049 8050 DPRINTF("Before calling PT_GET_SIGINFO\n"); 8051 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 8052 sizeof(info)) != -1); 8053 8054 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 8055 info.psi_siginfo.si_signo, info.psi_lwpid, 8056 WSTOPSIG(status)); 8057 8058 expected_sig = thread_concurrent_signals_list[info.psi_lwpid % 8059 __arraycount(thread_concurrent_signals_list)]; 8060 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, expected_sig, 8061 "lwp=%d, expected %d, got %d", info.psi_lwpid, 8062 expected_sig, info.psi_siginfo.si_signo); 8063 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 8064 "lwp=%d, expected %d, got %d", info.psi_lwpid, 8065 expected_sig, WSTOPSIG(status)); 8066 8067 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 8068 8069 DPRINTF("Before resuming the child process\n"); 8070 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8071 } 8072 8073 for (i = 0; i < __arraycount(signal_counts); i++) 8074 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 8075 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 8076 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 8077 8078 validate_status_exited(status, exitval); 8079} 8080 8081#endif /*defined(TWAIT_HAVE_STATUS)*/ 8082 8083/// ---------------------------------------------------------------------------- 8084 8085#include "t_ptrace_amd64_wait.h" 8086#include "t_ptrace_i386_wait.h" 8087#include "t_ptrace_x86_wait.h" 8088 8089ATF_TP_ADD_TCS(tp) 8090{ 8091 setvbuf(stdout, NULL, _IONBF, 0); 8092 setvbuf(stderr, NULL, _IONBF, 0); 8093 8094 ATF_TP_ADD_TC(tp, traceme_raise1); 8095 ATF_TP_ADD_TC(tp, traceme_raise2); 8096 ATF_TP_ADD_TC(tp, traceme_raise3); 8097 ATF_TP_ADD_TC(tp, traceme_raise4); 8098 ATF_TP_ADD_TC(tp, traceme_raise5); 8099 ATF_TP_ADD_TC(tp, traceme_raise6); 8100 ATF_TP_ADD_TC(tp, traceme_raise7); 8101 ATF_TP_ADD_TC(tp, traceme_raise8); 8102 ATF_TP_ADD_TC(tp, traceme_raise9); 8103 ATF_TP_ADD_TC(tp, traceme_raise10); 8104 8105 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 8106 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 8107 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 8108 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 8109 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 8110 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 8111 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 8112 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 8113 8114 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 8115 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 8116 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 8117 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 8118 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 8119 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 8120 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 8121 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 8122 8123 ATF_TP_ADD_TC(tp, traceme_crash_trap); 8124 ATF_TP_ADD_TC(tp, traceme_crash_segv); 8125 ATF_TP_ADD_TC(tp, traceme_crash_ill); 8126 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 8127 ATF_TP_ADD_TC(tp, traceme_crash_bus); 8128 8129 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 8130 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 8131 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 8132 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 8133 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 8134 8135 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 8136 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 8137 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 8138 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 8139 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 8140 8141 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 8142 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 8143 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 8144 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 8145 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 8146 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 8147 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 8148 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 8149 8150 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 8151 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 8152 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 8153 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 8154 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 8155 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 8156 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 8157 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 8158 8159 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 8160 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 8161 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 8162 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 8163 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 8164 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 8165 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 8166 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 8167 8168 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 8169 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 8170 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 8171 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 8172 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 8173 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 8174 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 8175 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 8176 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 8177 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 8178 8179 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 8180 8181 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 8182 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 8183 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 8184 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 8185 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 8186 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 8187 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 8188 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 8189 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 8190 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 8191 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 8192 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 8193 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 8194 8195 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 8196 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 8197 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 8198 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 8199 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 8200 8201 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 8202 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 8203 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 8204 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 8205 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 8206 8207 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 8208 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 8209 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 8210 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 8211 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 8212 8213 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 8214 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 8215 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 8216 8217 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 8218 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 8219 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 8220 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 8221 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 8222 8223 ATF_TP_ADD_TC_HAVE_PID(tp, 8224 unrelated_tracer_sees_signalmasked_crash_trap); 8225 ATF_TP_ADD_TC_HAVE_PID(tp, 8226 unrelated_tracer_sees_signalmasked_crash_segv); 8227 ATF_TP_ADD_TC_HAVE_PID(tp, 8228 unrelated_tracer_sees_signalmasked_crash_ill); 8229 ATF_TP_ADD_TC_HAVE_PID(tp, 8230 unrelated_tracer_sees_signalmasked_crash_fpe); 8231 ATF_TP_ADD_TC_HAVE_PID(tp, 8232 unrelated_tracer_sees_signalmasked_crash_bus); 8233 8234 ATF_TP_ADD_TC_HAVE_PID(tp, 8235 unrelated_tracer_sees_signalignored_crash_trap); 8236 ATF_TP_ADD_TC_HAVE_PID(tp, 8237 unrelated_tracer_sees_signalignored_crash_segv); 8238 ATF_TP_ADD_TC_HAVE_PID(tp, 8239 unrelated_tracer_sees_signalignored_crash_ill); 8240 ATF_TP_ADD_TC_HAVE_PID(tp, 8241 unrelated_tracer_sees_signalignored_crash_fpe); 8242 ATF_TP_ADD_TC_HAVE_PID(tp, 8243 unrelated_tracer_sees_signalignored_crash_bus); 8244 8245 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 8246 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 8247 ATF_TP_ADD_TC_HAVE_PID(tp, 8248 unrelated_tracer_sees_terminaton_before_the_parent); 8249 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 8250 8251 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 8252 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 8253 8254 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 8255 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 8256 8257 ATF_TP_ADD_TC_HAVE_PID(tp, 8258 tracee_sees_its_original_parent_getppid); 8259 ATF_TP_ADD_TC_HAVE_PID(tp, 8260 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 8261 ATF_TP_ADD_TC_HAVE_PID(tp, 8262 tracee_sees_its_original_parent_procfs_status); 8263 8264 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 8265 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 8266 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 8267 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 8268 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 8269 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 8270 ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn); 8271 8272 ATF_TP_ADD_TC(tp, fork1); 8273 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 8274 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 8275 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 8276 ATF_TP_ADD_TC(tp, fork5); 8277 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 8278 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 8279 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 8280 ATF_TP_ADD_TC(tp, fork9); 8281 ATF_TP_ADD_TC_HAVE_PID(tp, fork10); 8282 ATF_TP_ADD_TC_HAVE_PID(tp, fork11); 8283 ATF_TP_ADD_TC_HAVE_PID(tp, fork12); 8284 ATF_TP_ADD_TC(tp, fork13); 8285 ATF_TP_ADD_TC_HAVE_PID(tp, fork14); 8286 ATF_TP_ADD_TC_HAVE_PID(tp, fork15); 8287 ATF_TP_ADD_TC_HAVE_PID(tp, fork16); 8288 8289 ATF_TP_ADD_TC(tp, vfork1); 8290 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 8291 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 8292 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 8293 ATF_TP_ADD_TC(tp, vfork5); 8294 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 8295 ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 8296 ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 8297 ATF_TP_ADD_TC(tp, vfork9); 8298 ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); 8299 ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); 8300 ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); 8301 ATF_TP_ADD_TC(tp, vfork13); 8302 ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); 8303 ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); 8304 ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); 8305 8306 ATF_TP_ADD_TC(tp, posix_spawn1); 8307 ATF_TP_ADD_TC(tp, posix_spawn2); 8308 ATF_TP_ADD_TC(tp, posix_spawn3); 8309 ATF_TP_ADD_TC(tp, posix_spawn4); 8310 ATF_TP_ADD_TC(tp, posix_spawn5); 8311 ATF_TP_ADD_TC(tp, posix_spawn6); 8312 ATF_TP_ADD_TC(tp, posix_spawn7); 8313 ATF_TP_ADD_TC(tp, posix_spawn8); 8314 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); 8315 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); 8316 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); 8317 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); 8318 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); 8319 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); 8320 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); 8321 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); 8322 8323 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); 8324 ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); 8325 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); 8326 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); 8327 8328 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); 8329 ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); 8330 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); 8331 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); 8332 8333 ATF_TP_ADD_TC(tp, traceme_vfork_fork); 8334 ATF_TP_ADD_TC(tp, traceme_vfork_vfork); 8335 8336 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 8337 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 8338 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 8339 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 8340 8341 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 8342 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 8343 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 8344 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 8345 8346 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 8347 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 8348 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 8349 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 8350 8351 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 8352 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 8353 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 8354 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 8355 8356 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 8357 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 8358 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 8359 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 8360 8361 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 8362 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 8363 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 8364 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 8365 8366 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 8367 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 8368 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 8369 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 8370 8371 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 8372 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 8373 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 8374 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 8375 8376 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 8377 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 8378 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 8379 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 8380 8381 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 8382 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 8383 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 8384 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 8385 8386 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 8387 8388 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); 8389 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); 8390 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); 8391 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); 8392 8393 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); 8394 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); 8395 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); 8396 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); 8397 8398 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); 8399 8400 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); 8401 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); 8402 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); 8403 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); 8404 8405 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); 8406 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); 8407 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); 8408 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d); 8409 8410 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 8411 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 8412 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 8413 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 8414 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 8415 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 8416 8417 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 8418 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 8419 8420 ATF_TP_ADD_TC_PT_STEP(tp, step1); 8421 ATF_TP_ADD_TC_PT_STEP(tp, step2); 8422 ATF_TP_ADD_TC_PT_STEP(tp, step3); 8423 ATF_TP_ADD_TC_PT_STEP(tp, step4); 8424 8425 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 8426 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 8427 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 8428 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 8429 8430 ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked); 8431 ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored); 8432 8433 ATF_TP_ADD_TC(tp, kill1); 8434 ATF_TP_ADD_TC(tp, kill2); 8435 ATF_TP_ADD_TC(tp, kill3); 8436 8437 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 8438 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 8439 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 8440 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 8441 8442 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus); 8443 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus); 8444 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus); 8445 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus); 8446 8447 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask); 8448 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask); 8449 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask); 8450 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask); 8451 8452 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name); 8453 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name); 8454 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name); 8455 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name); 8456 8457 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private); 8458 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private); 8459 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private); 8460 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private); 8461 8462 ATF_TP_ADD_TC(tp, traceme_lwpnext0); 8463 ATF_TP_ADD_TC(tp, traceme_lwpnext1); 8464 ATF_TP_ADD_TC(tp, traceme_lwpnext2); 8465 ATF_TP_ADD_TC(tp, traceme_lwpnext3); 8466 8467 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask); 8468 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask); 8469 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask); 8470 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask); 8471 8472 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name); 8473 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name); 8474 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name); 8475 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name); 8476 8477 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private); 8478 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private); 8479 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private); 8480 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private); 8481 8482 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 8483 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 8484 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 8485 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 8486 8487 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 8488 ATF_TP_ADD_TC(tp, siginfo_set_faked); 8489 8490 ATF_TP_ADD_TC(tp, traceme_exec); 8491 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 8492 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 8493 8494 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 8495 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 8496 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 8497 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 8498 8499 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 8500 8501 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked); 8502 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored); 8503 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked); 8504 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored); 8505 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked); 8506 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored); 8507 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked); 8508 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored); 8509 8510 ATF_TP_ADD_TC(tp, signal9); 8511 ATF_TP_ADD_TC(tp, signal10); 8512 8513 ATF_TP_ADD_TC(tp, suspend2); 8514 8515 ATF_TP_ADD_TC(tp, resume1); 8516 8517 ATF_TP_ADD_TC(tp, syscall1); 8518 8519 ATF_TP_ADD_TC(tp, syscallemu1); 8520 8521 ATF_TP_ADD_TC(tp, clone1); 8522 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); 8523 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); 8524 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); 8525 ATF_TP_ADD_TC(tp, clone5); 8526 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); 8527 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); 8528 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); 8529 8530 ATF_TP_ADD_TC(tp, clone_vm1); 8531 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); 8532 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); 8533 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); 8534 ATF_TP_ADD_TC(tp, clone_vm5); 8535 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); 8536 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); 8537 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); 8538 8539 ATF_TP_ADD_TC(tp, clone_fs1); 8540 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); 8541 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); 8542 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); 8543 ATF_TP_ADD_TC(tp, clone_fs5); 8544 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); 8545 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); 8546 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); 8547 8548 ATF_TP_ADD_TC(tp, clone_files1); 8549 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); 8550 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); 8551 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); 8552 ATF_TP_ADD_TC(tp, clone_files5); 8553 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); 8554 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); 8555 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); 8556 8557// ATF_TP_ADD_TC(tp, clone_sighand1); // XXX 8558// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX 8559// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX 8560// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX 8561// ATF_TP_ADD_TC(tp, clone_sighand5); // XXX 8562// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX 8563// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX 8564// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX 8565 8566 ATF_TP_ADD_TC(tp, clone_vfork1); 8567 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); 8568 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); 8569 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); 8570 ATF_TP_ADD_TC(tp, clone_vfork5); 8571 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); 8572 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); 8573 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); 8574 8575 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); 8576 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); 8577 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); 8578 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); 8579 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); 8580 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); 8581 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); 8582 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); 8583// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX 8584// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX 8585 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); 8586 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); 8587 8588 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); 8589 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); 8590 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); 8591 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); 8592// ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX 8593 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork); 8594 8595 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 8596 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 8597 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 8598 8599 ATF_TP_ADD_TC(tp, core_dump_procinfo); 8600 8601#if defined(TWAIT_HAVE_STATUS) 8602 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 8603#endif 8604 8605 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 8606 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 8607 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 8608 8609 return atf_no_error(); 8610} 8611