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