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