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