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