t_ptrace_wait.c revision 1.135
1/* $NetBSD: t_ptrace_wait.c,v 1.135 2019/10/13 04:00:12 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.135 2019/10/13 04:00:12 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 5458#define TRACE_THREADS_NUM 100 5459 5460static volatile int done; 5461 5462static void * 5463trace_threads_cb(void *arg __unused) 5464{ 5465 5466 done++; 5467 5468 while (done < TRACE_THREADS_NUM) 5469 sched_yield(); 5470 5471 return NULL; 5472} 5473 5474static void 5475trace_threads(bool trace_create, bool trace_exit) 5476{ 5477 const int sigval = SIGSTOP; 5478 pid_t child, wpid; 5479#if defined(TWAIT_HAVE_STATUS) 5480 int status; 5481#endif 5482 ptrace_state_t state; 5483 const int slen = sizeof(state); 5484 ptrace_event_t event; 5485 const int elen = sizeof(event); 5486 struct ptrace_siginfo info; 5487 5488 pthread_t t[TRACE_THREADS_NUM]; 5489 int rv; 5490 size_t n; 5491 lwpid_t lid; 5492 5493 /* Track created and exited threads */ 5494 bool traced_lwps[__arraycount(t)]; 5495 5496#if !TEST_LWP_ENABLED 5497 if (trace_create || trace_exit) 5498 atf_tc_skip("PR kern/51995"); 5499#endif 5500 5501 DPRINTF("Before forking process PID=%d\n", getpid()); 5502 SYSCALL_REQUIRE((child = fork()) != -1); 5503 if (child == 0) { 5504 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5505 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5506 5507 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5508 FORKEE_ASSERT(raise(sigval) == 0); 5509 5510 for (n = 0; n < __arraycount(t); n++) { 5511 rv = pthread_create(&t[n], NULL, trace_threads_cb, 5512 NULL); 5513 FORKEE_ASSERT(rv == 0); 5514 } 5515 5516 for (n = 0; n < __arraycount(t); n++) { 5517 rv = pthread_join(t[n], NULL); 5518 FORKEE_ASSERT(rv == 0); 5519 } 5520 5521 /* 5522 * There is race between _exit() and pthread_join() detaching 5523 * a thread. For simplicity kill the process after detecting 5524 * LWP events. 5525 */ 5526 while (true) 5527 continue; 5528 5529 FORKEE_ASSERT(0 && "Not reached"); 5530 } 5531 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5532 5533 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5534 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5535 5536 validate_status_stopped(status, sigval); 5537 5538 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5539 SYSCALL_REQUIRE( 5540 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5541 5542 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5543 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5544 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5545 info.psi_siginfo.si_errno); 5546 5547 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5548 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5549 5550 DPRINTF("Set LWP event mask for the child %d\n", child); 5551 memset(&event, 0, sizeof(event)); 5552 if (trace_create) 5553 event.pe_set_event |= PTRACE_LWP_CREATE; 5554 if (trace_exit) 5555 event.pe_set_event |= PTRACE_LWP_EXIT; 5556 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5557 5558 DPRINTF("Before resuming the child process where it left off and " 5559 "without signal to be sent\n"); 5560 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5561 5562 memset(traced_lwps, 0, sizeof(traced_lwps)); 5563 5564 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 5565 DPRINTF("Before calling %s() for the child - expected stopped " 5566 "SIGTRAP\n", TWAIT_FNAME); 5567 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5568 child); 5569 5570 validate_status_stopped(status, SIGTRAP); 5571 5572 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5573 "child\n"); 5574 SYSCALL_REQUIRE( 5575 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5576 5577 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5578 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5579 "si_errno=%#x\n", 5580 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5581 info.psi_siginfo.si_errno); 5582 5583 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5584 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5585 5586 SYSCALL_REQUIRE( 5587 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5588 5589 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 5590 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 5591 5592 lid = state.pe_lwp; 5593 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 5594 5595 traced_lwps[lid - 1] = true; 5596 5597 DPRINTF("Before resuming the child process where it left off " 5598 "and without signal to be sent\n"); 5599 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5600 } 5601 5602 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 5603 DPRINTF("Before calling %s() for the child - expected stopped " 5604 "SIGTRAP\n", TWAIT_FNAME); 5605 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5606 child); 5607 5608 validate_status_stopped(status, SIGTRAP); 5609 5610 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 5611 "child\n"); 5612 SYSCALL_REQUIRE( 5613 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5614 5615 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5616 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 5617 "si_errno=%#x\n", 5618 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5619 info.psi_siginfo.si_errno); 5620 5621 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5622 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 5623 5624 SYSCALL_REQUIRE( 5625 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5626 5627 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 5628 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 5629 5630 lid = state.pe_lwp; 5631 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 5632 5633 if (trace_create) { 5634 ATF_REQUIRE(traced_lwps[lid - 1] == true); 5635 traced_lwps[lid - 1] = false; 5636 } 5637 5638 DPRINTF("Before resuming the child process where it left off " 5639 "and without signal to be sent\n"); 5640 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5641 } 5642 5643 kill(child, SIGKILL); 5644 5645 DPRINTF("Before calling %s() for the child - expected exited\n", 5646 TWAIT_FNAME); 5647 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5648 5649 validate_status_signaled(status, SIGKILL, 0); 5650 5651 DPRINTF("Before calling %s() for the child - expected no process\n", 5652 TWAIT_FNAME); 5653 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5654} 5655 5656#define TRACE_THREADS(test, trace_create, trace_exit) \ 5657ATF_TC(test); \ 5658ATF_TC_HEAD(test, tc) \ 5659{ \ 5660 atf_tc_set_md_var(tc, "descr", \ 5661 "Verify spawning threads with%s tracing LWP create and" \ 5662 "with%s tracing LWP exit", trace_create ? "" : "out", \ 5663 trace_exit ? "" : "out"); \ 5664} \ 5665 \ 5666ATF_TC_BODY(test, tc) \ 5667{ \ 5668 \ 5669 trace_threads(trace_create, trace_exit); \ 5670} 5671 5672TRACE_THREADS(trace_thread_nolwpevents, false, false) 5673TRACE_THREADS(trace_thread_lwpexit, false, true) 5674TRACE_THREADS(trace_thread_lwpcreate, true, false) 5675TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true) 5676 5677/// ---------------------------------------------------------------------------- 5678 5679ATF_TC(signal_mask_unrelated); 5680ATF_TC_HEAD(signal_mask_unrelated, tc) 5681{ 5682 atf_tc_set_md_var(tc, "descr", 5683 "Verify that masking single unrelated signal does not stop tracer " 5684 "from catching other signals"); 5685} 5686 5687ATF_TC_BODY(signal_mask_unrelated, tc) 5688{ 5689 const int exitval = 5; 5690 const int sigval = SIGSTOP; 5691 const int sigmasked = SIGTRAP; 5692 const int signotmasked = SIGINT; 5693 pid_t child, wpid; 5694#if defined(TWAIT_HAVE_STATUS) 5695 int status; 5696#endif 5697 sigset_t intmask; 5698 5699 DPRINTF("Before forking process PID=%d\n", getpid()); 5700 SYSCALL_REQUIRE((child = fork()) != -1); 5701 if (child == 0) { 5702 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5703 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5704 5705 sigemptyset(&intmask); 5706 sigaddset(&intmask, sigmasked); 5707 sigprocmask(SIG_BLOCK, &intmask, NULL); 5708 5709 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5710 FORKEE_ASSERT(raise(sigval) == 0); 5711 5712 DPRINTF("Before raising %s from child\n", 5713 strsignal(signotmasked)); 5714 FORKEE_ASSERT(raise(signotmasked) == 0); 5715 5716 DPRINTF("Before exiting of the child process\n"); 5717 _exit(exitval); 5718 } 5719 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5720 5721 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5722 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5723 5724 validate_status_stopped(status, sigval); 5725 5726 DPRINTF("Before resuming the child process where it left off and " 5727 "without signal to be sent\n"); 5728 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5729 5730 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5731 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5732 5733 validate_status_stopped(status, signotmasked); 5734 5735 DPRINTF("Before resuming the child process where it left off and " 5736 "without signal to be sent\n"); 5737 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5738 5739 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5740 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5741 5742 validate_status_exited(status, exitval); 5743 5744 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5745 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5746} 5747 5748/// ---------------------------------------------------------------------------- 5749 5750#if defined(TWAIT_HAVE_PID) 5751static void 5752fork2_body(const char *fn, bool masked, bool ignored) 5753{ 5754 const int exitval = 5; 5755 const int exitval2 = 0; /* Match exit status from /bin/echo */ 5756 const int sigval = SIGSTOP; 5757 pid_t child, child2 = 0, wpid; 5758#if defined(TWAIT_HAVE_STATUS) 5759 int status; 5760#endif 5761 ptrace_state_t state; 5762 const int slen = sizeof(state); 5763 ptrace_event_t event; 5764 const int elen = sizeof(event); 5765 struct sigaction sa; 5766 struct ptrace_siginfo info; 5767 sigset_t intmask; 5768 struct kinfo_proc2 kp; 5769 size_t len = sizeof(kp); 5770 5771 int name[6]; 5772 const size_t namelen = __arraycount(name); 5773 ki_sigset_t kp_sigmask; 5774 ki_sigset_t kp_sigignore; 5775 5776 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 5777 5778 DPRINTF("Before forking process PID=%d\n", getpid()); 5779 SYSCALL_REQUIRE((child = fork()) != -1); 5780 if (child == 0) { 5781 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5782 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5783 5784 if (masked) { 5785 sigemptyset(&intmask); 5786 sigaddset(&intmask, SIGTRAP); 5787 sigprocmask(SIG_BLOCK, &intmask, NULL); 5788 } 5789 5790 if (ignored) { 5791 memset(&sa, 0, sizeof(sa)); 5792 sa.sa_handler = SIG_IGN; 5793 sigemptyset(&sa.sa_mask); 5794 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 5795 } 5796 5797 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5798 FORKEE_ASSERT(raise(sigval) == 0); 5799 5800 if (strcmp(fn, "spawn") == 0) { 5801 FORKEE_ASSERT_EQ(posix_spawn(&child2, 5802 arg[0], NULL, NULL, arg, NULL), 0); 5803 } else { 5804 if (strcmp(fn, "fork") == 0) { 5805 FORKEE_ASSERT((child2 = fork()) != -1); 5806 } else { 5807 FORKEE_ASSERT((child2 = vfork()) != -1); 5808 } 5809 if (child2 == 0) 5810 _exit(exitval2); 5811 } 5812 5813 FORKEE_REQUIRE_SUCCESS 5814 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 5815 5816 forkee_status_exited(status, exitval2); 5817 5818 DPRINTF("Before exiting of the child process\n"); 5819 _exit(exitval); 5820 } 5821 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5822 5823 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5824 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5825 5826 validate_status_stopped(status, sigval); 5827 5828 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5829 SYSCALL_REQUIRE( 5830 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5831 5832 DPRINTF("Before checking siginfo_t\n"); 5833 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5834 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5835 5836 name[0] = CTL_KERN, 5837 name[1] = KERN_PROC2, 5838 name[2] = KERN_PROC_PID; 5839 name[3] = child; 5840 name[4] = sizeof(kp); 5841 name[5] = 1; 5842 5843 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5844 5845 if (masked) 5846 kp_sigmask = kp.p_sigmask; 5847 5848 if (ignored) 5849 kp_sigignore = kp.p_sigignore; 5850 5851 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 5852 strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "", 5853 strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "", 5854 strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "", 5855 strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child); 5856 event.pe_set_event = 0; 5857 if (strcmp(fn, "spawn") == 0) 5858 event.pe_set_event |= PTRACE_POSIX_SPAWN; 5859 if (strcmp(fn, "fork") == 0) 5860 event.pe_set_event |= PTRACE_FORK; 5861 if (strcmp(fn, "vfork") == 0) 5862 event.pe_set_event |= PTRACE_VFORK; 5863 if (strcmp(fn, "vforkdone") == 0) 5864 event.pe_set_event |= PTRACE_VFORK_DONE; 5865 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 5866 5867 DPRINTF("Before resuming the child process where it left off and " 5868 "without signal to be sent\n"); 5869 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5870 5871 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 5872 strcmp(fn, "vfork") == 0) { 5873 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 5874 child); 5875 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 5876 child); 5877 5878 validate_status_stopped(status, SIGTRAP); 5879 5880 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5881 5882 if (masked) { 5883 DPRINTF("kp_sigmask=" 5884 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5885 PRIx32 "\n", 5886 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5887 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5888 5889 DPRINTF("kp.p_sigmask=" 5890 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5891 PRIx32 "\n", 5892 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5893 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5894 5895 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5896 sizeof(kp_sigmask))); 5897 } 5898 5899 if (ignored) { 5900 DPRINTF("kp_sigignore=" 5901 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5902 PRIx32 "\n", 5903 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5904 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5905 5906 DPRINTF("kp.p_sigignore=" 5907 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5908 PRIx32 "\n", 5909 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5910 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5911 5912 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5913 sizeof(kp_sigignore))); 5914 } 5915 5916 SYSCALL_REQUIRE( 5917 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 5918 if (strcmp(fn, "spawn") == 0) { 5919 ATF_REQUIRE_EQ( 5920 state.pe_report_event & PTRACE_POSIX_SPAWN, 5921 PTRACE_POSIX_SPAWN); 5922 } 5923 if (strcmp(fn, "fork") == 0) { 5924 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 5925 PTRACE_FORK); 5926 } 5927 if (strcmp(fn, "vfork") == 0) { 5928 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 5929 PTRACE_VFORK); 5930 } 5931 5932 child2 = state.pe_other_pid; 5933 DPRINTF("Reported ptrace event with forkee %d\n", child2); 5934 5935 DPRINTF("Before calling %s() for the forkee %d of the child " 5936 "%d\n", TWAIT_FNAME, child2, child); 5937 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 5938 child2); 5939 5940 validate_status_stopped(status, SIGTRAP); 5941 5942 name[3] = child2; 5943 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5944 5945 if (masked) { 5946 DPRINTF("kp_sigmask=" 5947 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5948 PRIx32 "\n", 5949 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 5950 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 5951 5952 DPRINTF("kp.p_sigmask=" 5953 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5954 PRIx32 "\n", 5955 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 5956 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 5957 5958 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 5959 sizeof(kp_sigmask))); 5960 } 5961 5962 if (ignored) { 5963 DPRINTF("kp_sigignore=" 5964 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5965 PRIx32 "\n", 5966 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 5967 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 5968 5969 DPRINTF("kp.p_sigignore=" 5970 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 5971 PRIx32 "\n", 5972 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 5973 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 5974 5975 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 5976 sizeof(kp_sigignore))); 5977 } 5978 5979 SYSCALL_REQUIRE( 5980 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 5981 if (strcmp(fn, "spawn") == 0) { 5982 ATF_REQUIRE_EQ( 5983 state.pe_report_event & PTRACE_POSIX_SPAWN, 5984 PTRACE_POSIX_SPAWN); 5985 } 5986 if (strcmp(fn, "fork") == 0) { 5987 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 5988 PTRACE_FORK); 5989 } 5990 if (strcmp(fn, "vfork") == 0) { 5991 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 5992 PTRACE_VFORK); 5993 } 5994 5995 ATF_REQUIRE_EQ(state.pe_other_pid, child); 5996 5997 DPRINTF("Before resuming the forkee process where it left off " 5998 "and without signal to be sent\n"); 5999 SYSCALL_REQUIRE( 6000 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6001 6002 DPRINTF("Before resuming the child process where it left off " 6003 "and without signal to be sent\n"); 6004 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6005 } 6006 6007 if (strcmp(fn, "vforkdone") == 0) { 6008 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6009 child); 6010 TWAIT_REQUIRE_SUCCESS( 6011 wpid = TWAIT_GENERIC(child, &status, 0), child); 6012 6013 validate_status_stopped(status, SIGTRAP); 6014 6015 name[3] = child; 6016 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6017 6018 /* 6019 * SIGCHLD is now pending in the signal queue and 6020 * the kernel presents it to userland as a masked signal. 6021 */ 6022 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 6023 6024 if (masked) { 6025 DPRINTF("kp_sigmask=" 6026 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6027 PRIx32 "\n", 6028 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 6029 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 6030 6031 DPRINTF("kp.p_sigmask=" 6032 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6033 PRIx32 "\n", 6034 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6035 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6036 6037 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 6038 sizeof(kp_sigmask))); 6039 } 6040 6041 if (ignored) { 6042 DPRINTF("kp_sigignore=" 6043 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6044 PRIx32 "\n", 6045 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 6046 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 6047 6048 DPRINTF("kp.p_sigignore=" 6049 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 6050 PRIx32 "\n", 6051 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 6052 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 6053 6054 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 6055 sizeof(kp_sigignore))); 6056 } 6057 6058 SYSCALL_REQUIRE( 6059 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6060 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6061 6062 child2 = state.pe_other_pid; 6063 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6064 child2); 6065 6066 DPRINTF("Before resuming the child process where it left off " 6067 "and without signal to be sent\n"); 6068 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6069 } 6070 6071 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 6072 strcmp(fn, "vfork") == 0) { 6073 DPRINTF("Before calling %s() for the forkee - expected exited" 6074 "\n", TWAIT_FNAME); 6075 TWAIT_REQUIRE_SUCCESS( 6076 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6077 6078 validate_status_exited(status, exitval2); 6079 6080 DPRINTF("Before calling %s() for the forkee - expected no " 6081 "process\n", TWAIT_FNAME); 6082 TWAIT_REQUIRE_FAILURE(ECHILD, 6083 wpid = TWAIT_GENERIC(child2, &status, 0)); 6084 } 6085 6086 DPRINTF("Before calling %s() for the child - expected stopped " 6087 "SIGCHLD\n", TWAIT_FNAME); 6088 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6089 6090 validate_status_stopped(status, SIGCHLD); 6091 6092 DPRINTF("Before resuming the child process where it left off and " 6093 "without signal to be sent\n"); 6094 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6095 6096 DPRINTF("Before calling %s() for the child - expected exited\n", 6097 TWAIT_FNAME); 6098 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6099 6100 validate_status_exited(status, exitval); 6101 6102 DPRINTF("Before calling %s() for the child - expected no process\n", 6103 TWAIT_FNAME); 6104 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6105} 6106 6107#define FORK2_TEST(name,fn,masked,ignored) \ 6108ATF_TC(name); \ 6109ATF_TC_HEAD(name, tc) \ 6110{ \ 6111 atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught " \ 6112 "regardless of signal %s%s", \ 6113 masked ? "masked" : "", ignored ? "ignored" : ""); \ 6114} \ 6115 \ 6116ATF_TC_BODY(name, tc) \ 6117{ \ 6118 \ 6119 fork2_body(fn, masked, ignored); \ 6120} 6121 6122FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false) 6123FORK2_TEST(posix_spawn_singalignored, "spawn", false, true) 6124FORK2_TEST(fork_singalmasked, "fork", true, false) 6125FORK2_TEST(fork_singalignored, "fork", false, true) 6126#if TEST_VFORK_ENABLED 6127FORK2_TEST(vfork_singalmasked, "vfork", true, false) 6128FORK2_TEST(vfork_singalignored, "vfork", false, true) 6129FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false) 6130FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true) 6131#endif 6132#endif 6133 6134/// ---------------------------------------------------------------------------- 6135 6136volatile lwpid_t the_lwp_id = 0; 6137 6138static void 6139lwp_main_func(void *arg) 6140{ 6141 the_lwp_id = _lwp_self(); 6142 _lwp_exit(); 6143} 6144 6145ATF_TC(signal9); 6146ATF_TC_HEAD(signal9, tc) 6147{ 6148 atf_tc_set_md_var(tc, "descr", 6149 "Verify that masking SIGTRAP in tracee does not stop tracer from " 6150 "catching PTRACE_LWP_CREATE breakpoint"); 6151} 6152 6153ATF_TC_BODY(signal9, tc) 6154{ 6155 const int exitval = 5; 6156 const int sigval = SIGSTOP; 6157 const int sigmasked = SIGTRAP; 6158 pid_t child, wpid; 6159#if defined(TWAIT_HAVE_STATUS) 6160 int status; 6161#endif 6162 sigset_t intmask; 6163 ptrace_state_t state; 6164 const int slen = sizeof(state); 6165 ptrace_event_t event; 6166 const int elen = sizeof(event); 6167 ucontext_t uc; 6168 lwpid_t lid; 6169 static const size_t ssize = 16*1024; 6170 void *stack; 6171 6172 DPRINTF("Before forking process PID=%d\n", getpid()); 6173 SYSCALL_REQUIRE((child = fork()) != -1); 6174 if (child == 0) { 6175 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6176 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6177 6178 sigemptyset(&intmask); 6179 sigaddset(&intmask, sigmasked); 6180 sigprocmask(SIG_BLOCK, &intmask, NULL); 6181 6182 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6183 FORKEE_ASSERT(raise(sigval) == 0); 6184 6185 DPRINTF("Before allocating memory for stack in child\n"); 6186 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6187 6188 DPRINTF("Before making context for new lwp in child\n"); 6189 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 6190 6191 DPRINTF("Before creating new in child\n"); 6192 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6193 6194 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6195 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6196 6197 DPRINTF("Before verifying that reported %d and running lid %d " 6198 "are the same\n", lid, the_lwp_id); 6199 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6200 6201 DPRINTF("Before exiting of the child process\n"); 6202 _exit(exitval); 6203 } 6204 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6205 6206 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6207 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6208 6209 validate_status_stopped(status, sigval); 6210 6211 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 6212 event.pe_set_event = PTRACE_LWP_CREATE; 6213 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6214 6215 DPRINTF("Before resuming the child process where it left off and " 6216 "without signal to be sent\n"); 6217 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6218 6219 DPRINTF("Before calling %s() for the child - expected stopped " 6220 "SIGTRAP\n", TWAIT_FNAME); 6221 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6222 6223 validate_status_stopped(status, sigmasked); 6224 6225 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6226 6227 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 6228 6229 lid = state.pe_lwp; 6230 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 6231 6232 DPRINTF("Before resuming the child process where it left off and " 6233 "without signal to be sent\n"); 6234 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6235 6236 DPRINTF("Before calling %s() for the child - expected exited\n", 6237 TWAIT_FNAME); 6238 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6239 6240 validate_status_exited(status, exitval); 6241 6242 DPRINTF("Before calling %s() for the child - expected no process\n", 6243 TWAIT_FNAME); 6244 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6245} 6246 6247ATF_TC(signal10); 6248ATF_TC_HEAD(signal10, tc) 6249{ 6250 atf_tc_set_md_var(tc, "descr", 6251 "Verify that masking SIGTRAP in tracee does not stop tracer from " 6252 "catching PTRACE_LWP_EXIT breakpoint"); 6253} 6254 6255ATF_TC_BODY(signal10, tc) 6256{ 6257 const int exitval = 5; 6258 const int sigval = SIGSTOP; 6259 const int sigmasked = SIGTRAP; 6260 pid_t child, wpid; 6261#if defined(TWAIT_HAVE_STATUS) 6262 int status; 6263#endif 6264 sigset_t intmask; 6265 ptrace_state_t state; 6266 const int slen = sizeof(state); 6267 ptrace_event_t event; 6268 const int elen = sizeof(event); 6269 ucontext_t uc; 6270 lwpid_t lid; 6271 static const size_t ssize = 16*1024; 6272 void *stack; 6273 6274 DPRINTF("Before forking process PID=%d\n", getpid()); 6275 SYSCALL_REQUIRE((child = fork()) != -1); 6276 if (child == 0) { 6277 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6278 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6279 6280 sigemptyset(&intmask); 6281 sigaddset(&intmask, sigmasked); 6282 sigprocmask(SIG_BLOCK, &intmask, NULL); 6283 6284 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6285 FORKEE_ASSERT(raise(sigval) == 0); 6286 6287 DPRINTF("Before allocating memory for stack in child\n"); 6288 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6289 6290 DPRINTF("Before making context for new lwp in child\n"); 6291 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 6292 6293 DPRINTF("Before creating new in child\n"); 6294 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6295 6296 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6297 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6298 6299 DPRINTF("Before verifying that reported %d and running lid %d " 6300 "are the same\n", lid, the_lwp_id); 6301 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6302 6303 DPRINTF("Before exiting of the child process\n"); 6304 _exit(exitval); 6305 } 6306 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6307 6308 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6309 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6310 6311 validate_status_stopped(status, sigval); 6312 6313 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 6314 event.pe_set_event = PTRACE_LWP_EXIT; 6315 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6316 6317 DPRINTF("Before resuming the child process where it left off and " 6318 "without signal to be sent\n"); 6319 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6320 6321 DPRINTF("Before calling %s() for the child - expected stopped " 6322 "SIGTRAP\n", TWAIT_FNAME); 6323 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6324 6325 validate_status_stopped(status, sigmasked); 6326 6327 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6328 6329 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 6330 6331 lid = state.pe_lwp; 6332 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 6333 6334 DPRINTF("Before resuming the child process where it left off and " 6335 "without signal to be sent\n"); 6336 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6337 6338 DPRINTF("Before calling %s() for the child - expected exited\n", 6339 TWAIT_FNAME); 6340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6341 6342 validate_status_exited(status, exitval); 6343 6344 DPRINTF("Before calling %s() for the child - expected no process\n", 6345 TWAIT_FNAME); 6346 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6347} 6348 6349static void 6350lwp_main_stop(void *arg) 6351{ 6352 the_lwp_id = _lwp_self(); 6353 6354 raise(SIGTRAP); 6355 6356 _lwp_exit(); 6357} 6358 6359ATF_TC(suspend2); 6360ATF_TC_HEAD(suspend2, tc) 6361{ 6362 atf_tc_set_md_var(tc, "descr", 6363 "Verify that the while the only thread within a process is " 6364 "suspended, the whole process cannot be unstopped"); 6365} 6366 6367ATF_TC_BODY(suspend2, tc) 6368{ 6369 const int exitval = 5; 6370 const int sigval = SIGSTOP; 6371 pid_t child, wpid; 6372#if defined(TWAIT_HAVE_STATUS) 6373 int status; 6374#endif 6375 struct ptrace_siginfo psi; 6376 6377 DPRINTF("Before forking process PID=%d\n", getpid()); 6378 SYSCALL_REQUIRE((child = fork()) != -1); 6379 if (child == 0) { 6380 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6381 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6382 6383 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6384 FORKEE_ASSERT(raise(sigval) == 0); 6385 6386 DPRINTF("Before exiting of the child process\n"); 6387 _exit(exitval); 6388 } 6389 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6390 6391 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6392 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6393 6394 validate_status_stopped(status, sigval); 6395 6396 DPRINTF("Before reading siginfo and lwpid_t\n"); 6397 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6398 6399 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6400 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6401 6402 DPRINTF("Before resuming the child process where it left off and " 6403 "without signal to be sent\n"); 6404 ATF_REQUIRE_ERRNO(EDEADLK, 6405 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 6406 6407 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6408 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6409 6410 DPRINTF("Before resuming the child process where it left off and " 6411 "without signal to be sent\n"); 6412 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6413 6414 DPRINTF("Before calling %s() for the child - expected exited\n", 6415 TWAIT_FNAME); 6416 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6417 6418 validate_status_exited(status, exitval); 6419 6420 DPRINTF("Before calling %s() for the child - expected no process\n", 6421 TWAIT_FNAME); 6422 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6423} 6424 6425ATF_TC(resume1); 6426ATF_TC_HEAD(resume1, tc) 6427{ 6428 atf_tc_set_md_var(tc, "descr", 6429 "Verify that a thread can be suspended by a debugger and later " 6430 "resumed by the debugger"); 6431} 6432 6433ATF_TC_BODY(resume1, tc) 6434{ 6435 struct msg_fds fds; 6436 const int exitval = 5; 6437 const int sigval = SIGSTOP; 6438 pid_t child, wpid; 6439 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 6440#if defined(TWAIT_HAVE_STATUS) 6441 int status; 6442#endif 6443 ucontext_t uc; 6444 lwpid_t lid; 6445 static const size_t ssize = 16*1024; 6446 void *stack; 6447 struct ptrace_lwpinfo pl; 6448 struct ptrace_siginfo psi; 6449 6450 SYSCALL_REQUIRE(msg_open(&fds) == 0); 6451 6452 DPRINTF("Before forking process PID=%d\n", getpid()); 6453 SYSCALL_REQUIRE((child = fork()) != -1); 6454 if (child == 0) { 6455 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6456 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6457 6458 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6459 FORKEE_ASSERT(raise(sigval) == 0); 6460 6461 DPRINTF("Before allocating memory for stack in child\n"); 6462 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 6463 6464 DPRINTF("Before making context for new lwp in child\n"); 6465 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 6466 6467 DPRINTF("Before creating new in child\n"); 6468 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 6469 6470 CHILD_TO_PARENT("Message", fds, msg); 6471 6472 raise(SIGINT); 6473 6474 DPRINTF("Before waiting for lwp %d to exit\n", lid); 6475 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 6476 6477 DPRINTF("Before verifying that reported %d and running lid %d " 6478 "are the same\n", lid, the_lwp_id); 6479 FORKEE_ASSERT_EQ(lid, the_lwp_id); 6480 6481 DPRINTF("Before exiting of the child process\n"); 6482 _exit(exitval); 6483 } 6484 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6485 6486 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6487 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6488 6489 validate_status_stopped(status, sigval); 6490 6491 DPRINTF("Before resuming the child process where it left off and " 6492 "without signal to be sent\n"); 6493 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6494 6495 DPRINTF("Before calling %s() for the child - expected stopped " 6496 "SIGTRAP\n", TWAIT_FNAME); 6497 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6498 6499 validate_status_stopped(status, SIGTRAP); 6500 6501 DPRINTF("Before reading siginfo and lwpid_t\n"); 6502 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 6503 6504 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 6505 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 6506 6507 PARENT_FROM_CHILD("Message", fds, msg); 6508 6509 DPRINTF("Before resuming the child process where it left off and " 6510 "without signal to be sent\n"); 6511 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6512 6513 DPRINTF("Before calling %s() for the child - expected stopped " 6514 "SIGINT\n", TWAIT_FNAME); 6515 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6516 6517 validate_status_stopped(status, SIGINT); 6518 6519 pl.pl_lwpid = 0; 6520 6521 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6522 while (pl.pl_lwpid != 0) { 6523 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 6524 switch (pl.pl_lwpid) { 6525 case 1: 6526 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 6527 break; 6528 case 2: 6529 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 6530 break; 6531 } 6532 } 6533 6534 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 6535 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 6536 6537 DPRINTF("Before resuming the child process where it left off and " 6538 "without signal to be sent\n"); 6539 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6540 6541 DPRINTF("Before calling %s() for the child - expected exited\n", 6542 TWAIT_FNAME); 6543 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6544 6545 validate_status_exited(status, exitval); 6546 6547 DPRINTF("Before calling %s() for the child - expected no process\n", 6548 TWAIT_FNAME); 6549 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6550 6551 msg_close(&fds); 6552} 6553 6554ATF_TC(syscall1); 6555ATF_TC_HEAD(syscall1, tc) 6556{ 6557 atf_tc_set_md_var(tc, "descr", 6558 "Verify that getpid(2) can be traced with PT_SYSCALL"); 6559} 6560 6561ATF_TC_BODY(syscall1, tc) 6562{ 6563 const int exitval = 5; 6564 const int sigval = SIGSTOP; 6565 pid_t child, wpid; 6566#if defined(TWAIT_HAVE_STATUS) 6567 int status; 6568#endif 6569 struct ptrace_siginfo info; 6570 memset(&info, 0, sizeof(info)); 6571 6572 DPRINTF("Before forking process PID=%d\n", getpid()); 6573 SYSCALL_REQUIRE((child = fork()) != -1); 6574 if (child == 0) { 6575 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6576 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6577 6578 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6579 FORKEE_ASSERT(raise(sigval) == 0); 6580 6581 syscall(SYS_getpid); 6582 6583 DPRINTF("Before exiting of the child process\n"); 6584 _exit(exitval); 6585 } 6586 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6587 6588 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6589 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6590 6591 validate_status_stopped(status, sigval); 6592 6593 DPRINTF("Before resuming the child process where it left off and " 6594 "without signal to be sent\n"); 6595 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6596 6597 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6598 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6599 6600 validate_status_stopped(status, SIGTRAP); 6601 6602 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6603 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6604 6605 DPRINTF("Before checking siginfo_t and lwpid\n"); 6606 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6607 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6608 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 6609 6610 DPRINTF("Before resuming the child process where it left off and " 6611 "without signal to be sent\n"); 6612 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6613 6614 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6615 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6616 6617 validate_status_stopped(status, SIGTRAP); 6618 6619 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6620 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6621 6622 DPRINTF("Before checking siginfo_t and lwpid\n"); 6623 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 6624 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 6625 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 6626 6627 DPRINTF("Before resuming the child process where it left off and " 6628 "without signal to be sent\n"); 6629 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6630 6631 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6632 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6633 6634 validate_status_exited(status, exitval); 6635 6636 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6637 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6638} 6639 6640ATF_TC(syscallemu1); 6641ATF_TC_HEAD(syscallemu1, tc) 6642{ 6643 atf_tc_set_md_var(tc, "descr", 6644 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 6645} 6646 6647ATF_TC_BODY(syscallemu1, tc) 6648{ 6649 const int exitval = 5; 6650 const int sigval = SIGSTOP; 6651 pid_t child, wpid; 6652#if defined(TWAIT_HAVE_STATUS) 6653 int status; 6654#endif 6655 6656#if defined(__sparc__) && !defined(__sparc64__) 6657 /* syscallemu does not work on sparc (32-bit) */ 6658 atf_tc_expect_fail("PR kern/52166"); 6659#endif 6660 6661 DPRINTF("Before forking process PID=%d\n", getpid()); 6662 SYSCALL_REQUIRE((child = fork()) != -1); 6663 if (child == 0) { 6664 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6665 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6666 6667 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6668 FORKEE_ASSERT(raise(sigval) == 0); 6669 6670 syscall(SYS_exit, 100); 6671 6672 DPRINTF("Before exiting of the child process\n"); 6673 _exit(exitval); 6674 } 6675 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6676 6677 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6678 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6679 6680 validate_status_stopped(status, sigval); 6681 6682 DPRINTF("Before resuming the child process where it left off and " 6683 "without signal to be sent\n"); 6684 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6685 6686 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6687 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6688 6689 validate_status_stopped(status, SIGTRAP); 6690 6691 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 6692 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 6693 6694 DPRINTF("Before resuming the child process where it left off and " 6695 "without signal to be sent\n"); 6696 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 6697 6698 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6699 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6700 6701 validate_status_stopped(status, SIGTRAP); 6702 6703 DPRINTF("Before resuming the child process where it left off and " 6704 "without signal to be sent\n"); 6705 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6706 6707 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6708 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6709 6710 validate_status_exited(status, exitval); 6711 6712 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6713 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6714} 6715 6716/// ---------------------------------------------------------------------------- 6717 6718static void 6719clone_body(int flags, bool trackfork, bool trackvfork, 6720 bool trackvforkdone) 6721{ 6722 const int exitval = 5; 6723 const int exitval2 = 15; 6724 const int sigval = SIGSTOP; 6725 pid_t child, child2 = 0, wpid; 6726#if defined(TWAIT_HAVE_STATUS) 6727 int status; 6728#endif 6729 ptrace_state_t state; 6730 const int slen = sizeof(state); 6731 ptrace_event_t event; 6732 const int elen = sizeof(event); 6733 6734 const size_t stack_size = 1024 * 1024; 6735 void *stack, *stack_base; 6736 6737 stack = malloc(stack_size); 6738 ATF_REQUIRE(stack != NULL); 6739 6740#ifdef __MACHINE_STACK_GROWS_UP 6741 stack_base = stack; 6742#else 6743 stack_base = (char *)stack + stack_size; 6744#endif 6745 6746 DPRINTF("Before forking process PID=%d\n", getpid()); 6747 SYSCALL_REQUIRE((child = fork()) != -1); 6748 if (child == 0) { 6749 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6750 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6751 6752 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6753 FORKEE_ASSERT(raise(sigval) == 0); 6754 6755 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 6756 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 6757 6758 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 6759 child2); 6760 6761 // XXX WALLSIG? 6762 FORKEE_REQUIRE_SUCCESS 6763 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 6764 6765 forkee_status_exited(status, exitval2); 6766 6767 DPRINTF("Before exiting of the child process\n"); 6768 _exit(exitval); 6769 } 6770 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6771 6772 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6773 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6774 6775 validate_status_stopped(status, sigval); 6776 6777 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 6778 trackfork ? "|PTRACE_FORK" : "", 6779 trackvfork ? "|PTRACE_VFORK" : "", 6780 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 6781 event.pe_set_event = 0; 6782 if (trackfork) 6783 event.pe_set_event |= PTRACE_FORK; 6784 if (trackvfork) 6785 event.pe_set_event |= PTRACE_VFORK; 6786 if (trackvforkdone) 6787 event.pe_set_event |= PTRACE_VFORK_DONE; 6788 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 6789 6790 DPRINTF("Before resuming the child process where it left off and " 6791 "without signal to be sent\n"); 6792 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6793 6794#if defined(TWAIT_HAVE_PID) 6795 if ((trackfork && !(flags & CLONE_VFORK)) || 6796 (trackvfork && (flags & CLONE_VFORK))) { 6797 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6798 child); 6799 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 6800 child); 6801 6802 validate_status_stopped(status, SIGTRAP); 6803 6804 SYSCALL_REQUIRE( 6805 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6806 if (trackfork && !(flags & CLONE_VFORK)) { 6807 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6808 PTRACE_FORK); 6809 } 6810 if (trackvfork && (flags & CLONE_VFORK)) { 6811 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6812 PTRACE_VFORK); 6813 } 6814 6815 child2 = state.pe_other_pid; 6816 DPRINTF("Reported ptrace event with forkee %d\n", child2); 6817 6818 DPRINTF("Before calling %s() for the forkee %d of the child " 6819 "%d\n", TWAIT_FNAME, child2, child); 6820 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 6821 child2); 6822 6823 validate_status_stopped(status, SIGTRAP); 6824 6825 SYSCALL_REQUIRE( 6826 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 6827 if (trackfork && !(flags & CLONE_VFORK)) { 6828 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 6829 PTRACE_FORK); 6830 } 6831 if (trackvfork && (flags & CLONE_VFORK)) { 6832 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 6833 PTRACE_VFORK); 6834 } 6835 6836 ATF_REQUIRE_EQ(state.pe_other_pid, child); 6837 6838 DPRINTF("Before resuming the forkee process where it left off " 6839 "and without signal to be sent\n"); 6840 SYSCALL_REQUIRE( 6841 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 6842 6843 DPRINTF("Before resuming the child process where it left off " 6844 "and without signal to be sent\n"); 6845 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6846 } 6847#endif 6848 6849 if (trackvforkdone && (flags & CLONE_VFORK)) { 6850 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 6851 child); 6852 TWAIT_REQUIRE_SUCCESS( 6853 wpid = TWAIT_GENERIC(child, &status, 0), child); 6854 6855 validate_status_stopped(status, SIGTRAP); 6856 6857 SYSCALL_REQUIRE( 6858 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 6859 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 6860 6861 child2 = state.pe_other_pid; 6862 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 6863 child2); 6864 6865 DPRINTF("Before resuming the child process where it left off " 6866 "and without signal to be sent\n"); 6867 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6868 } 6869 6870#if defined(TWAIT_HAVE_PID) 6871 if ((trackfork && !(flags & CLONE_VFORK)) || 6872 (trackvfork && (flags & CLONE_VFORK))) { 6873 DPRINTF("Before calling %s() for the forkee - expected exited" 6874 "\n", TWAIT_FNAME); 6875 TWAIT_REQUIRE_SUCCESS( 6876 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 6877 6878 validate_status_exited(status, exitval2); 6879 6880 DPRINTF("Before calling %s() for the forkee - expected no " 6881 "process\n", TWAIT_FNAME); 6882 TWAIT_REQUIRE_FAILURE(ECHILD, 6883 wpid = TWAIT_GENERIC(child2, &status, 0)); 6884 } 6885#endif 6886 6887 DPRINTF("Before calling %s() for the child - expected stopped " 6888 "SIGCHLD\n", TWAIT_FNAME); 6889 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6890 6891 validate_status_stopped(status, SIGCHLD); 6892 6893 DPRINTF("Before resuming the child process where it left off and " 6894 "without signal to be sent\n"); 6895 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6896 6897 DPRINTF("Before calling %s() for the child - expected exited\n", 6898 TWAIT_FNAME); 6899 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6900 6901 validate_status_exited(status, exitval); 6902 6903 DPRINTF("Before calling %s() for the child - expected no process\n", 6904 TWAIT_FNAME); 6905 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6906} 6907 6908#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \ 6909ATF_TC(name); \ 6910ATF_TC_HEAD(name, tc) \ 6911{ \ 6912 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \ 6913 "called with 0%s%s%s in EVENT_MASK", \ 6914 #flags, \ 6915 tfork ? "|PTRACE_FORK" : "", \ 6916 tvfork ? "|PTRACE_VFORK" : "", \ 6917 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 6918} \ 6919 \ 6920ATF_TC_BODY(name, tc) \ 6921{ \ 6922 \ 6923 clone_body(flags, tfork, tvfork, tvforkdone); \ 6924} 6925 6926CLONE_TEST(clone1, 0, false, false, false) 6927#if defined(TWAIT_HAVE_PID) 6928CLONE_TEST(clone2, 0, true, false, false) 6929CLONE_TEST(clone3, 0, false, true, false) 6930CLONE_TEST(clone4, 0, true, true, false) 6931#endif 6932CLONE_TEST(clone5, 0, false, false, true) 6933#if defined(TWAIT_HAVE_PID) 6934CLONE_TEST(clone6, 0, true, false, true) 6935CLONE_TEST(clone7, 0, false, true, true) 6936CLONE_TEST(clone8, 0, true, true, true) 6937#endif 6938 6939CLONE_TEST(clone_vm1, CLONE_VM, false, false, false) 6940#if defined(TWAIT_HAVE_PID) 6941CLONE_TEST(clone_vm2, CLONE_VM, true, false, false) 6942CLONE_TEST(clone_vm3, CLONE_VM, false, true, false) 6943CLONE_TEST(clone_vm4, CLONE_VM, true, true, false) 6944#endif 6945CLONE_TEST(clone_vm5, CLONE_VM, false, false, true) 6946#if defined(TWAIT_HAVE_PID) 6947CLONE_TEST(clone_vm6, CLONE_VM, true, false, true) 6948CLONE_TEST(clone_vm7, CLONE_VM, false, true, true) 6949CLONE_TEST(clone_vm8, CLONE_VM, true, true, true) 6950#endif 6951 6952CLONE_TEST(clone_fs1, CLONE_FS, false, false, false) 6953#if defined(TWAIT_HAVE_PID) 6954CLONE_TEST(clone_fs2, CLONE_FS, true, false, false) 6955CLONE_TEST(clone_fs3, CLONE_FS, false, true, false) 6956CLONE_TEST(clone_fs4, CLONE_FS, true, true, false) 6957#endif 6958CLONE_TEST(clone_fs5, CLONE_FS, false, false, true) 6959#if defined(TWAIT_HAVE_PID) 6960CLONE_TEST(clone_fs6, CLONE_FS, true, false, true) 6961CLONE_TEST(clone_fs7, CLONE_FS, false, true, true) 6962CLONE_TEST(clone_fs8, CLONE_FS, true, true, true) 6963#endif 6964 6965CLONE_TEST(clone_files1, CLONE_FILES, false, false, false) 6966#if defined(TWAIT_HAVE_PID) 6967CLONE_TEST(clone_files2, CLONE_FILES, true, false, false) 6968CLONE_TEST(clone_files3, CLONE_FILES, false, true, false) 6969CLONE_TEST(clone_files4, CLONE_FILES, true, true, false) 6970#endif 6971CLONE_TEST(clone_files5, CLONE_FILES, false, false, true) 6972#if defined(TWAIT_HAVE_PID) 6973CLONE_TEST(clone_files6, CLONE_FILES, true, false, true) 6974CLONE_TEST(clone_files7, CLONE_FILES, false, true, true) 6975CLONE_TEST(clone_files8, CLONE_FILES, true, true, true) 6976#endif 6977 6978//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false) 6979#if defined(TWAIT_HAVE_PID) 6980//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false) 6981//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false) 6982//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false) 6983#endif 6984//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true) 6985#if defined(TWAIT_HAVE_PID) 6986//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true) 6987//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true) 6988//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true) 6989#endif 6990 6991#if TEST_VFORK_ENABLED 6992CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false) 6993#if defined(TWAIT_HAVE_PID) 6994CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false) 6995CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false) 6996CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false) 6997#endif 6998CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true) 6999#if defined(TWAIT_HAVE_PID) 7000CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true) 7001CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true) 7002CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true) 7003#endif 7004#endif 7005 7006/// ---------------------------------------------------------------------------- 7007 7008#if defined(TWAIT_HAVE_PID) 7009static void 7010clone_body2(int flags, bool masked, bool ignored) 7011{ 7012 const int exitval = 5; 7013 const int exitval2 = 15; 7014 const int sigval = SIGSTOP; 7015 pid_t child, child2 = 0, wpid; 7016#if defined(TWAIT_HAVE_STATUS) 7017 int status; 7018#endif 7019 ptrace_state_t state; 7020 const int slen = sizeof(state); 7021 ptrace_event_t event; 7022 const int elen = sizeof(event); 7023 struct sigaction sa; 7024 struct ptrace_siginfo info; 7025 sigset_t intmask; 7026 struct kinfo_proc2 kp; 7027 size_t len = sizeof(kp); 7028 7029 int name[6]; 7030 const size_t namelen = __arraycount(name); 7031 ki_sigset_t kp_sigmask; 7032 ki_sigset_t kp_sigignore; 7033 7034 const size_t stack_size = 1024 * 1024; 7035 void *stack, *stack_base; 7036 7037 stack = malloc(stack_size); 7038 ATF_REQUIRE(stack != NULL); 7039 7040#ifdef __MACHINE_STACK_GROWS_UP 7041 stack_base = stack; 7042#else 7043 stack_base = (char *)stack + stack_size; 7044#endif 7045 7046 SYSCALL_REQUIRE((child = fork()) != -1); 7047 if (child == 0) { 7048 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7049 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7050 7051 if (masked) { 7052 sigemptyset(&intmask); 7053 sigaddset(&intmask, SIGTRAP); 7054 sigprocmask(SIG_BLOCK, &intmask, NULL); 7055 } 7056 7057 if (ignored) { 7058 memset(&sa, 0, sizeof(sa)); 7059 sa.sa_handler = SIG_IGN; 7060 sigemptyset(&sa.sa_mask); 7061 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 7062 } 7063 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7064 FORKEE_ASSERT(raise(sigval) == 0); 7065 7066 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7067 flags); 7068 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7069 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7070 7071 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7072 child2); 7073 7074 // XXX WALLSIG? 7075 FORKEE_REQUIRE_SUCCESS 7076 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7077 7078 forkee_status_exited(status, exitval2); 7079 7080 DPRINTF("Before exiting of the child process\n"); 7081 _exit(exitval); 7082 } 7083 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7084 7085 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7086 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7087 7088 validate_status_stopped(status, sigval); 7089 7090 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7091 SYSCALL_REQUIRE( 7092 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7093 7094 DPRINTF("Before checking siginfo_t\n"); 7095 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7096 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7097 7098 name[0] = CTL_KERN, 7099 name[1] = KERN_PROC2, 7100 name[2] = KERN_PROC_PID; 7101 name[3] = child; 7102 name[4] = sizeof(kp); 7103 name[5] = 1; 7104 7105 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7106 7107 if (masked) 7108 kp_sigmask = kp.p_sigmask; 7109 7110 if (ignored) 7111 kp_sigignore = kp.p_sigignore; 7112 7113 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in " 7114 "EVENT_MASK for the child %d\n", child); 7115 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; 7116 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 7117 7118 DPRINTF("Before resuming the child process where it left off and " 7119 "without signal to be sent\n"); 7120 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7121 7122 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7123 child); 7124 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7125 child); 7126 7127 validate_status_stopped(status, SIGTRAP); 7128 7129 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7130 7131 if (masked) { 7132 DPRINTF("kp_sigmask=" 7133 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7134 PRIx32 "\n", 7135 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7136 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7137 7138 DPRINTF("kp.p_sigmask=" 7139 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7140 PRIx32 "\n", 7141 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7142 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7143 7144 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7145 sizeof(kp_sigmask))); 7146 } 7147 7148 if (ignored) { 7149 DPRINTF("kp_sigignore=" 7150 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7151 PRIx32 "\n", 7152 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7153 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7154 7155 DPRINTF("kp.p_sigignore=" 7156 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7157 PRIx32 "\n", 7158 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7159 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7160 7161 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7162 sizeof(kp_sigignore))); 7163 } 7164 7165 SYSCALL_REQUIRE( 7166 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7167 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event, 7168 child2); 7169 if (!(flags & CLONE_VFORK)) { 7170 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7171 PTRACE_FORK); 7172 } else { 7173 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7174 PTRACE_VFORK); 7175 } 7176 7177 child2 = state.pe_other_pid; 7178 DPRINTF("Reported ptrace event with forkee %d\n", child2); 7179 7180 DPRINTF("Before calling %s() for the forkee %d of the child " 7181 "%d\n", TWAIT_FNAME, child2, child); 7182 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 7183 child2); 7184 7185 validate_status_stopped(status, SIGTRAP); 7186 7187 name[3] = child2; 7188 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7189 7190 if (masked) { 7191 DPRINTF("kp_sigmask=" 7192 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7193 PRIx32 "\n", 7194 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7195 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7196 7197 DPRINTF("kp.p_sigmask=" 7198 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7199 PRIx32 "\n", 7200 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7201 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7202 7203 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7204 sizeof(kp_sigmask))); 7205 } 7206 7207 if (ignored) { 7208 DPRINTF("kp_sigignore=" 7209 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7210 PRIx32 "\n", 7211 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7212 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7213 7214 DPRINTF("kp.p_sigignore=" 7215 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7216 PRIx32 "\n", 7217 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7218 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7219 7220 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7221 sizeof(kp_sigignore))); 7222 } 7223 7224 SYSCALL_REQUIRE( 7225 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 7226 if (!(flags & CLONE_VFORK)) { 7227 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 7228 PTRACE_FORK); 7229 } else { 7230 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 7231 PTRACE_VFORK); 7232 } 7233 7234 ATF_REQUIRE_EQ(state.pe_other_pid, child); 7235 7236 DPRINTF("Before resuming the forkee process where it left off " 7237 "and without signal to be sent\n"); 7238 SYSCALL_REQUIRE( 7239 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 7240 7241 DPRINTF("Before resuming the child process where it left off " 7242 "and without signal to be sent\n"); 7243 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7244 7245 if (flags & CLONE_VFORK) { 7246 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 7247 child); 7248 TWAIT_REQUIRE_SUCCESS( 7249 wpid = TWAIT_GENERIC(child, &status, 0), child); 7250 7251 validate_status_stopped(status, SIGTRAP); 7252 7253 name[3] = child; 7254 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7255 7256 /* 7257 * SIGCHLD is now pending in the signal queue and 7258 * the kernel presents it to userland as a masked signal. 7259 */ 7260 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 7261 7262 if (masked) { 7263 DPRINTF("kp_sigmask=" 7264 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7265 PRIx32 "\n", 7266 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 7267 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 7268 7269 DPRINTF("kp.p_sigmask=" 7270 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7271 PRIx32 "\n", 7272 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 7273 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 7274 7275 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 7276 sizeof(kp_sigmask))); 7277 } 7278 7279 if (ignored) { 7280 DPRINTF("kp_sigignore=" 7281 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7282 PRIx32 "\n", 7283 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 7284 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 7285 7286 DPRINTF("kp.p_sigignore=" 7287 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 7288 PRIx32 "\n", 7289 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 7290 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 7291 7292 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 7293 sizeof(kp_sigignore))); 7294 } 7295 7296 SYSCALL_REQUIRE( 7297 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 7298 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 7299 7300 child2 = state.pe_other_pid; 7301 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 7302 child2); 7303 7304 DPRINTF("Before resuming the child process where it left off " 7305 "and without signal to be sent\n"); 7306 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7307 } 7308 7309 DPRINTF("Before calling %s() for the forkee - expected exited" 7310 "\n", TWAIT_FNAME); 7311 TWAIT_REQUIRE_SUCCESS( 7312 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 7313 7314 validate_status_exited(status, exitval2); 7315 7316 DPRINTF("Before calling %s() for the forkee - expected no " 7317 "process\n", TWAIT_FNAME); 7318 TWAIT_REQUIRE_FAILURE(ECHILD, 7319 wpid = TWAIT_GENERIC(child2, &status, 0)); 7320 7321 DPRINTF("Before calling %s() for the child - expected stopped " 7322 "SIGCHLD\n", TWAIT_FNAME); 7323 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7324 7325 validate_status_stopped(status, SIGCHLD); 7326 7327 DPRINTF("Before resuming the child process where it left off and " 7328 "without signal to be sent\n"); 7329 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7330 7331 DPRINTF("Before calling %s() for the child - expected exited\n", 7332 TWAIT_FNAME); 7333 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7334 7335 validate_status_exited(status, exitval); 7336 7337 DPRINTF("Before calling %s() for the child - expected no process\n", 7338 TWAIT_FNAME); 7339 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7340} 7341 7342#define CLONE_TEST2(name,flags,masked,ignored) \ 7343ATF_TC(name); \ 7344ATF_TC_HEAD(name, tc) \ 7345{ \ 7346 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\ 7347 " regardless of signal %s%s", \ 7348 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \ 7349} \ 7350 \ 7351ATF_TC_BODY(name, tc) \ 7352{ \ 7353 \ 7354 clone_body2(flags, masked, ignored); \ 7355} 7356 7357CLONE_TEST2(clone_signalignored, 0, true, false) 7358CLONE_TEST2(clone_signalmasked, 0, false, true) 7359CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false) 7360CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true) 7361CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false) 7362CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true) 7363CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false) 7364CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true) 7365//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX 7366//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX 7367#if TEST_VFORK_ENABLED 7368CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false) 7369CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true) 7370#endif 7371#endif 7372 7373/// ---------------------------------------------------------------------------- 7374 7375#if TEST_VFORK_ENABLED 7376#if defined(TWAIT_HAVE_PID) 7377static void 7378traceme_vfork_clone_body(int flags) 7379{ 7380 const int exitval = 5; 7381 const int exitval2 = 15; 7382 pid_t child, child2 = 0, wpid; 7383#if defined(TWAIT_HAVE_STATUS) 7384 int status; 7385#endif 7386 7387 const size_t stack_size = 1024 * 1024; 7388 void *stack, *stack_base; 7389 7390 stack = malloc(stack_size); 7391 ATF_REQUIRE(stack != NULL); 7392 7393#ifdef __MACHINE_STACK_GROWS_UP 7394 stack_base = stack; 7395#else 7396 stack_base = (char *)stack + stack_size; 7397#endif 7398 7399 SYSCALL_REQUIRE((child = vfork()) != -1); 7400 if (child == 0) { 7401 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7402 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7403 7404 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 7405 flags); 7406 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 7407 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 7408 7409 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 7410 child2); 7411 7412 // XXX WALLSIG? 7413 FORKEE_REQUIRE_SUCCESS 7414 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 7415 7416 forkee_status_exited(status, exitval2); 7417 7418 DPRINTF("Before exiting of the child process\n"); 7419 _exit(exitval); 7420 } 7421 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7422 7423 DPRINTF("Before calling %s() for the child - expected exited\n", 7424 TWAIT_FNAME); 7425 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7426 7427 validate_status_exited(status, exitval); 7428 7429 DPRINTF("Before calling %s() for the child - expected no process\n", 7430 TWAIT_FNAME); 7431 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7432} 7433 7434#define TRACEME_VFORK_CLONE_TEST(name,flags) \ 7435ATF_TC(name); \ 7436ATF_TC_HEAD(name, tc) \ 7437{ \ 7438 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \ 7439 "handled correctly with vfork(2)ed tracer", \ 7440 #flags); \ 7441} \ 7442 \ 7443ATF_TC_BODY(name, tc) \ 7444{ \ 7445 \ 7446 traceme_vfork_clone_body(flags); \ 7447} 7448 7449TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0) 7450TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM) 7451TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS) 7452TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES) 7453//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX 7454TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK) 7455#endif 7456#endif 7457 7458/// ---------------------------------------------------------------------------- 7459 7460static void 7461user_va0_disable(int operation) 7462{ 7463 pid_t child, wpid; 7464#if defined(TWAIT_HAVE_STATUS) 7465 int status; 7466#endif 7467 const int sigval = SIGSTOP; 7468 int rv; 7469 7470 struct ptrace_siginfo info; 7471 7472 if (get_user_va0_disable() == 0) 7473 atf_tc_skip("vm.user_va0_disable is set to 0"); 7474 7475 memset(&info, 0, sizeof(info)); 7476 7477 DPRINTF("Before forking process PID=%d\n", getpid()); 7478 SYSCALL_REQUIRE((child = fork()) != -1); 7479 if (child == 0) { 7480 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7481 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7482 7483 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7484 FORKEE_ASSERT(raise(sigval) == 0); 7485 7486 /* NOTREACHED */ 7487 FORKEE_ASSERTX(0 && "This shall not be reached"); 7488 __unreachable(); 7489 } 7490 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7491 7492 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7493 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7494 7495 validate_status_stopped(status, sigval); 7496 7497 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7498 "child\n"); 7499 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 7500 sizeof(info)) != -1); 7501 7502 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7503 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7504 "si_errno=%#x\n", 7505 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7506 info.psi_siginfo.si_errno); 7507 7508 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7509 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7510 7511 DPRINTF("Before resuming the child process in PC=0x0 " 7512 "and without signal to be sent\n"); 7513 errno = 0; 7514 rv = ptrace(operation, child, (void *)0, 0); 7515 ATF_REQUIRE_EQ(errno, EINVAL); 7516 ATF_REQUIRE_EQ(rv, -1); 7517 7518 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 7519 7520 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7521 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7522 validate_status_signaled(status, SIGKILL, 0); 7523 7524 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7525 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7526} 7527 7528#define USER_VA0_DISABLE(test, operation) \ 7529ATF_TC(test); \ 7530ATF_TC_HEAD(test, tc) \ 7531{ \ 7532 atf_tc_set_md_var(tc, "descr", \ 7533 "Verify behavior of " #operation " with PC set to 0x0"); \ 7534} \ 7535 \ 7536ATF_TC_BODY(test, tc) \ 7537{ \ 7538 \ 7539 user_va0_disable(operation); \ 7540} 7541 7542USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 7543USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 7544USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 7545 7546/// ---------------------------------------------------------------------------- 7547 7548/* 7549 * Parse the core file and find the requested note. If the reading or parsing 7550 * fails, the test is failed. If the note is found, it is read onto buf, up to 7551 * buf_len. The actual length of the note is returned (which can be greater 7552 * than buf_len, indicating that it has been truncated). If the note is not 7553 * found, -1 is returned. 7554 */ 7555static ssize_t core_find_note(const char *core_path, 7556 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 7557{ 7558 int core_fd; 7559 Elf *core_elf; 7560 size_t core_numhdr, i; 7561 ssize_t ret = -1; 7562 /* note: we assume note name will be null-terminated */ 7563 size_t name_len = strlen(note_name) + 1; 7564 7565 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 7566 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 7567 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 7568 7569 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 7570 for (i = 0; i < core_numhdr && ret == -1; i++) { 7571 GElf_Phdr core_hdr; 7572 size_t offset; 7573 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 7574 if (core_hdr.p_type != PT_NOTE) 7575 continue; 7576 7577 for (offset = core_hdr.p_offset; 7578 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 7579 Elf64_Nhdr note_hdr; 7580 char name_buf[64]; 7581 7582 switch (gelf_getclass(core_elf)) { 7583 case ELFCLASS64: 7584 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 7585 sizeof(note_hdr), offset) 7586 == sizeof(note_hdr)); 7587 offset += sizeof(note_hdr); 7588 break; 7589 case ELFCLASS32: 7590 { 7591 Elf32_Nhdr tmp_hdr; 7592 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 7593 sizeof(tmp_hdr), offset) 7594 == sizeof(tmp_hdr)); 7595 offset += sizeof(tmp_hdr); 7596 note_hdr.n_namesz = tmp_hdr.n_namesz; 7597 note_hdr.n_descsz = tmp_hdr.n_descsz; 7598 note_hdr.n_type = tmp_hdr.n_type; 7599 } 7600 break; 7601 } 7602 7603 /* indicates end of notes */ 7604 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 7605 break; 7606 if (note_hdr.n_namesz == name_len && 7607 note_hdr.n_namesz <= sizeof(name_buf)) { 7608 SYSCALL_REQUIRE(pread(core_fd, name_buf, 7609 note_hdr.n_namesz, offset) 7610 == (ssize_t)(size_t)note_hdr.n_namesz); 7611 7612 if (!strncmp(note_name, name_buf, name_len) && 7613 note_hdr.n_type == note_type) 7614 ret = note_hdr.n_descsz; 7615 } 7616 7617 offset += note_hdr.n_namesz; 7618 /* fix to alignment */ 7619 offset = ((offset + core_hdr.p_align - 1) 7620 / core_hdr.p_align) * core_hdr.p_align; 7621 7622 /* if name & type matched above */ 7623 if (ret != -1) { 7624 ssize_t read_len = MIN(buf_len, 7625 note_hdr.n_descsz); 7626 SYSCALL_REQUIRE(pread(core_fd, buf, 7627 read_len, offset) == read_len); 7628 break; 7629 } 7630 7631 offset += note_hdr.n_descsz; 7632 } 7633 } 7634 7635 elf_end(core_elf); 7636 close(core_fd); 7637 7638 return ret; 7639} 7640 7641ATF_TC(core_dump_procinfo); 7642ATF_TC_HEAD(core_dump_procinfo, tc) 7643{ 7644 atf_tc_set_md_var(tc, "descr", 7645 "Trigger a core dump and verify its contents."); 7646} 7647 7648ATF_TC_BODY(core_dump_procinfo, tc) 7649{ 7650 const int exitval = 5; 7651 pid_t child, wpid; 7652#if defined(TWAIT_HAVE_STATUS) 7653 const int sigval = SIGTRAP; 7654 int status; 7655#endif 7656 char core_path[] = "/tmp/core.XXXXXX"; 7657 int core_fd; 7658 struct netbsd_elfcore_procinfo procinfo; 7659 7660 DPRINTF("Before forking process PID=%d\n", getpid()); 7661 SYSCALL_REQUIRE((child = fork()) != -1); 7662 if (child == 0) { 7663 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7664 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7665 7666 DPRINTF("Before triggering SIGTRAP\n"); 7667 trigger_trap(); 7668 7669 DPRINTF("Before exiting of the child process\n"); 7670 _exit(exitval); 7671 } 7672 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7673 7674 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7675 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7676 7677 validate_status_stopped(status, sigval); 7678 7679 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 7680 close(core_fd); 7681 7682 DPRINTF("Call DUMPCORE for the child process\n"); 7683 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 7684 != -1); 7685 7686 DPRINTF("Read core file\n"); 7687 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 7688 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 7689 sizeof(procinfo)); 7690 7691 ATF_CHECK_EQ(procinfo.cpi_version, 1); 7692 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 7693 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 7694 ATF_CHECK_EQ(procinfo.cpi_pid, child); 7695 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 7696 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 7697 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 7698 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 7699 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 7700 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 7701 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 7702 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 7703 ATF_CHECK_EQ(procinfo.cpi_siglwp, 1); 7704 7705 unlink(core_path); 7706 7707 DPRINTF("Before resuming the child process where it left off and " 7708 "without signal to be sent\n"); 7709 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7710 7711 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7712 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7713 7714 validate_status_exited(status, exitval); 7715 7716 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7717 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7718} 7719 7720/// ---------------------------------------------------------------------------- 7721 7722#include "t_ptrace_amd64_wait.h" 7723#include "t_ptrace_i386_wait.h" 7724#include "t_ptrace_x86_wait.h" 7725 7726ATF_TP_ADD_TCS(tp) 7727{ 7728 setvbuf(stdout, NULL, _IONBF, 0); 7729 setvbuf(stderr, NULL, _IONBF, 0); 7730 7731 ATF_TP_ADD_TC(tp, traceme_raise1); 7732 ATF_TP_ADD_TC(tp, traceme_raise2); 7733 ATF_TP_ADD_TC(tp, traceme_raise3); 7734 ATF_TP_ADD_TC(tp, traceme_raise4); 7735 ATF_TP_ADD_TC(tp, traceme_raise5); 7736 ATF_TP_ADD_TC(tp, traceme_raise6); 7737 ATF_TP_ADD_TC(tp, traceme_raise7); 7738 ATF_TP_ADD_TC(tp, traceme_raise8); 7739 ATF_TP_ADD_TC(tp, traceme_raise9); 7740 ATF_TP_ADD_TC(tp, traceme_raise10); 7741 7742 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 7743 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 7744 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 7745 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 7746 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 7747 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 7748 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 7749 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 7750 7751 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 7752 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 7753 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 7754 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 7755 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 7756 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 7757 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 7758 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 7759 7760 ATF_TP_ADD_TC(tp, traceme_crash_trap); 7761 ATF_TP_ADD_TC(tp, traceme_crash_segv); 7762 ATF_TP_ADD_TC(tp, traceme_crash_ill); 7763 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 7764 ATF_TP_ADD_TC(tp, traceme_crash_bus); 7765 7766 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 7767 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 7768 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 7769 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 7770 ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 7771 7772 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 7773 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 7774 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 7775 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 7776 ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 7777 7778 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 7779 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 7780 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 7781 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 7782 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 7783 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 7784 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 7785 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 7786 7787 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 7788 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 7789 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 7790 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 7791 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 7792 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 7793 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 7794 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 7795 7796 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 7797 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 7798 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 7799 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 7800 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 7801 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 7802 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 7803 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 7804 7805 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 7806 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 7807 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 7808 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 7809 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 7810 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 7811 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 7812 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 7813 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 7814 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 7815 7816 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 7817 7818 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 7819 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 7820 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 7821 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 7822 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 7823 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 7824 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 7825 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 7826 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 7827 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 7828 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 7829 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 7830 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 7831 7832 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 7833 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 7834 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 7835 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 7836 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 7837 7838 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 7839 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 7840 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 7841 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 7842 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 7843 7844 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 7845 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 7846 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 7847 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 7848 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 7849 7850 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 7851 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 7852 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 7853 7854 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 7855 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 7856 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 7857 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 7858 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 7859 7860 ATF_TP_ADD_TC_HAVE_PID(tp, 7861 unrelated_tracer_sees_signalmasked_crash_trap); 7862 ATF_TP_ADD_TC_HAVE_PID(tp, 7863 unrelated_tracer_sees_signalmasked_crash_segv); 7864 ATF_TP_ADD_TC_HAVE_PID(tp, 7865 unrelated_tracer_sees_signalmasked_crash_ill); 7866 ATF_TP_ADD_TC_HAVE_PID(tp, 7867 unrelated_tracer_sees_signalmasked_crash_fpe); 7868 ATF_TP_ADD_TC_HAVE_PID(tp, 7869 unrelated_tracer_sees_signalmasked_crash_bus); 7870 7871 ATF_TP_ADD_TC_HAVE_PID(tp, 7872 unrelated_tracer_sees_signalignored_crash_trap); 7873 ATF_TP_ADD_TC_HAVE_PID(tp, 7874 unrelated_tracer_sees_signalignored_crash_segv); 7875 ATF_TP_ADD_TC_HAVE_PID(tp, 7876 unrelated_tracer_sees_signalignored_crash_ill); 7877 ATF_TP_ADD_TC_HAVE_PID(tp, 7878 unrelated_tracer_sees_signalignored_crash_fpe); 7879 ATF_TP_ADD_TC_HAVE_PID(tp, 7880 unrelated_tracer_sees_signalignored_crash_bus); 7881 7882 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 7883 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 7884 ATF_TP_ADD_TC_HAVE_PID(tp, 7885 unrelated_tracer_sees_terminaton_before_the_parent); 7886 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 7887 7888 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 7889 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 7890 7891 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 7892 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 7893 7894 ATF_TP_ADD_TC_HAVE_PID(tp, 7895 tracee_sees_its_original_parent_getppid); 7896 ATF_TP_ADD_TC_HAVE_PID(tp, 7897 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 7898 ATF_TP_ADD_TC_HAVE_PID(tp, 7899 tracee_sees_its_original_parent_procfs_status); 7900 7901 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 7902 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 7903 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 7904 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 7905 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 7906 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 7907 ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn); 7908 7909 ATF_TP_ADD_TC(tp, fork1); 7910 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 7911 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 7912 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 7913 ATF_TP_ADD_TC(tp, fork5); 7914 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 7915 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 7916 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 7917 ATF_TP_ADD_TC(tp, fork9); 7918 ATF_TP_ADD_TC_HAVE_PID(tp, fork10); 7919 ATF_TP_ADD_TC_HAVE_PID(tp, fork11); 7920 ATF_TP_ADD_TC_HAVE_PID(tp, fork12); 7921 ATF_TP_ADD_TC(tp, fork13); 7922 ATF_TP_ADD_TC_HAVE_PID(tp, fork14); 7923 ATF_TP_ADD_TC_HAVE_PID(tp, fork15); 7924 ATF_TP_ADD_TC_HAVE_PID(tp, fork16); 7925 7926#if TEST_VFORK_ENABLED 7927 ATF_TP_ADD_TC(tp, vfork1); 7928 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 7929 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 7930 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 7931 ATF_TP_ADD_TC(tp, vfork5); 7932 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 7933 ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 7934 ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 7935 ATF_TP_ADD_TC(tp, vfork9); 7936 ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); 7937 ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); 7938 ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); 7939 ATF_TP_ADD_TC(tp, vfork13); 7940 ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); 7941 ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); 7942 ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); 7943#endif 7944 7945 ATF_TP_ADD_TC(tp, posix_spawn1); 7946 ATF_TP_ADD_TC(tp, posix_spawn2); 7947 ATF_TP_ADD_TC(tp, posix_spawn3); 7948 ATF_TP_ADD_TC(tp, posix_spawn4); 7949 ATF_TP_ADD_TC(tp, posix_spawn5); 7950 ATF_TP_ADD_TC(tp, posix_spawn6); 7951 ATF_TP_ADD_TC(tp, posix_spawn7); 7952 ATF_TP_ADD_TC(tp, posix_spawn8); 7953 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); 7954 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); 7955 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); 7956 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); 7957 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); 7958 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); 7959 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); 7960 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); 7961 7962 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); 7963 ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); 7964#if TEST_VFORK_ENABLED 7965 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); 7966 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); 7967#endif 7968 7969 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); 7970 ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); 7971#if TEST_VFORK_ENABLED 7972 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); 7973 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); 7974#endif 7975 7976#if TEST_VFORK_ENABLED 7977 ATF_TP_ADD_TC(tp, traceme_vfork_fork); 7978 ATF_TP_ADD_TC(tp, traceme_vfork_vfork); 7979#endif 7980 7981 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 7982 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 7983 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 7984 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 7985 7986 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 7987 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 7988 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 7989 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 7990 7991 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 7992 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 7993 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 7994 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 7995 7996 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 7997 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 7998 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 7999 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 8000 8001 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 8002 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 8003 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 8004 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 8005 8006 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 8007 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 8008 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 8009 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 8010 8011 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 8012 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 8013 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 8014 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 8015 8016 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 8017 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 8018 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 8019 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 8020 8021 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 8022 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 8023 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 8024 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 8025 8026 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 8027 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 8028 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 8029 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 8030 8031 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 8032 8033 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); 8034 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); 8035 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); 8036 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); 8037 8038 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); 8039 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); 8040 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); 8041 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); 8042 8043 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); 8044 8045 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); 8046 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); 8047 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); 8048 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); 8049 8050 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); 8051 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); 8052 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); 8053 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d); 8054 8055 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 8056 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 8057 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 8058 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 8059 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 8060 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 8061 8062 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 8063 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 8064 8065 ATF_TP_ADD_TC_PT_STEP(tp, step1); 8066 ATF_TP_ADD_TC_PT_STEP(tp, step2); 8067 ATF_TP_ADD_TC_PT_STEP(tp, step3); 8068 ATF_TP_ADD_TC_PT_STEP(tp, step4); 8069 8070 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 8071 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 8072 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 8073 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 8074 8075 ATF_TP_ADD_TC_PT_STEP(tp, step_signalmasked); 8076 ATF_TP_ADD_TC_PT_STEP(tp, step_signalignored); 8077 8078 ATF_TP_ADD_TC(tp, kill1); 8079 ATF_TP_ADD_TC(tp, kill2); 8080 ATF_TP_ADD_TC(tp, kill3); 8081 8082 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 8083 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 8084 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 8085 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 8086 8087 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 8088 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 8089 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 8090 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 8091 8092 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 8093 ATF_TP_ADD_TC(tp, siginfo_set_faked); 8094 8095 ATF_TP_ADD_TC(tp, traceme_exec); 8096 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 8097 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 8098 8099 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 8100 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 8101 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 8102 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 8103 8104 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 8105 8106 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked); 8107 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored); 8108 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked); 8109 ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored); 8110#if TEST_VFORK_ENABLED 8111 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked); 8112 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored); 8113 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked); 8114 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored); 8115#endif 8116 8117 ATF_TP_ADD_TC(tp, signal9); 8118 ATF_TP_ADD_TC(tp, signal10); 8119 8120 ATF_TP_ADD_TC(tp, suspend2); 8121 8122 ATF_TP_ADD_TC(tp, resume1); 8123 8124 ATF_TP_ADD_TC(tp, syscall1); 8125 8126 ATF_TP_ADD_TC(tp, syscallemu1); 8127 8128 ATF_TP_ADD_TC(tp, clone1); 8129 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); 8130 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); 8131 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); 8132 ATF_TP_ADD_TC(tp, clone5); 8133 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); 8134 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); 8135 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); 8136 8137 ATF_TP_ADD_TC(tp, clone_vm1); 8138 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); 8139 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); 8140 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); 8141 ATF_TP_ADD_TC(tp, clone_vm5); 8142 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); 8143 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); 8144 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); 8145 8146 ATF_TP_ADD_TC(tp, clone_fs1); 8147 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); 8148 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); 8149 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); 8150 ATF_TP_ADD_TC(tp, clone_fs5); 8151 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); 8152 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); 8153 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); 8154 8155 ATF_TP_ADD_TC(tp, clone_files1); 8156 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); 8157 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); 8158 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); 8159 ATF_TP_ADD_TC(tp, clone_files5); 8160 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); 8161 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); 8162 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); 8163 8164// ATF_TP_ADD_TC(tp, clone_sighand1); // XXX 8165// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX 8166// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX 8167// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX 8168// ATF_TP_ADD_TC(tp, clone_sighand5); // XXX 8169// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX 8170// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX 8171// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX 8172 8173#if TEST_VFORK_ENABLED 8174 ATF_TP_ADD_TC(tp, clone_vfork1); 8175 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); 8176 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); 8177 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); 8178 ATF_TP_ADD_TC(tp, clone_vfork5); 8179 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); 8180 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); 8181 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); 8182#endif 8183 8184 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); 8185 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); 8186 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); 8187 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); 8188 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); 8189 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); 8190 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); 8191 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); 8192// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX 8193// ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX 8194#if TEST_VFORK_ENABLED 8195 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); 8196 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); 8197#endif 8198 8199#if TEST_VFORK_ENABLED 8200 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); 8201 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); 8202 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); 8203 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); 8204// ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX 8205 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork); 8206#endif 8207 8208 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 8209 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 8210 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 8211 8212 ATF_TP_ADD_TC(tp, core_dump_procinfo); 8213 8214 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 8215 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 8216 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 8217 8218 return atf_no_error(); 8219} 8220