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