t_ptrace_wait.c revision 1.87
1/* $NetBSD: t_ptrace_wait.c,v 1.87 2019/02/15 04:11:39 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.87 2019/02/15 04:11:39 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 <atf-c.h> 57 58#include "h_macros.h" 59 60#include "t_ptrace_wait.h" 61#include "msg.h" 62 63#define PARENT_TO_CHILD(info, fds, msg) \ 64 SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, \ 65 sizeof(msg)) == 0) 66 67#define CHILD_FROM_PARENT(info, fds, msg) \ 68 FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, \ 69 sizeof(msg)) == 0) 70 71#define CHILD_TO_PARENT(info, fds, msg) \ 72 FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, \ 73 sizeof(msg)) == 0) 74 75#define PARENT_FROM_CHILD(info, fds, msg) \ 76 SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, \ 77 sizeof(msg)) == 0) 78 79#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 80 strerror(errno)) 81#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 82 "%d(%s) != %d", res, strerror(res), exp) 83 84static int debug = 0; 85 86#define DPRINTF(a, ...) do \ 87 if (debug) printf(a, ##__VA_ARGS__); \ 88 while (/*CONSTCOND*/0) 89 90/// ---------------------------------------------------------------------------- 91 92static void 93traceme_raise(int sigval) 94{ 95 const int exitval = 5; 96 pid_t child, wpid; 97#if defined(TWAIT_HAVE_STATUS) 98 int status; 99#endif 100 101 struct ptrace_siginfo info; 102 memset(&info, 0, sizeof(info)); 103 104 DPRINTF("Before forking process PID=%d\n", getpid()); 105 SYSCALL_REQUIRE((child = fork()) != -1); 106 if (child == 0) { 107 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 108 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 109 110 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 111 FORKEE_ASSERT(raise(sigval) == 0); 112 113 switch (sigval) { 114 case SIGKILL: 115 /* NOTREACHED */ 116 FORKEE_ASSERTX(0 && "This shall not be reached"); 117 __unreachable(); 118 default: 119 DPRINTF("Before exiting of the child process\n"); 120 _exit(exitval); 121 } 122 } 123 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 124 125 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 126 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 127 128 switch (sigval) { 129 case SIGKILL: 130 validate_status_signaled(status, sigval, 0); 131 break; 132 default: 133 validate_status_stopped(status, sigval); 134 135 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 136 "child\n"); 137 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 138 sizeof(info)) != -1); 139 140 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 141 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 142 "si_errno=%#x\n", 143 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 144 info.psi_siginfo.si_errno); 145 146 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 147 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 148 149 DPRINTF("Before resuming the child process where it left off " 150 "and without signal to be sent\n"); 151 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 152 153 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 154 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 155 child); 156 break; 157 } 158 159 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 160 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 161} 162 163#define TRACEME_RAISE(test, sig) \ 164ATF_TC(test); \ 165ATF_TC_HEAD(test, tc) \ 166{ \ 167 atf_tc_set_md_var(tc, "descr", \ 168 "Verify " #sig " followed by _exit(2) in a child"); \ 169} \ 170 \ 171ATF_TC_BODY(test, tc) \ 172{ \ 173 \ 174 traceme_raise(sig); \ 175} 176 177TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ 178TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */ 179TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */ 180TRACEME_RAISE(traceme_raise4, SIGHUP) /* hangup */ 181TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */ 182TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */ 183TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */ 184TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */ 185TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */ 186TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */ 187 188/// ---------------------------------------------------------------------------- 189 190static void 191traceme_raisesignal_ignored(int sigignored) 192{ 193 const int exitval = 5; 194 const int sigval = SIGSTOP; 195 pid_t child, wpid; 196 struct sigaction sa; 197#if defined(TWAIT_HAVE_STATUS) 198 int status; 199#endif 200 struct ptrace_siginfo info; 201 202 memset(&info, 0, sizeof(info)); 203 204 DPRINTF("Before forking process PID=%d\n", getpid()); 205 SYSCALL_REQUIRE((child = fork()) != -1); 206 if (child == 0) { 207 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 208 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 209 210 memset(&sa, 0, sizeof(sa)); 211 sa.sa_handler = SIG_IGN; 212 sigemptyset(&sa.sa_mask); 213 FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1); 214 215 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 216 FORKEE_ASSERT(raise(sigval) == 0); 217 218 DPRINTF("Before raising %s from child\n", 219 strsignal(sigignored)); 220 FORKEE_ASSERT(raise(sigignored) == 0); 221 222 DPRINTF("Before exiting of the child process\n"); 223 _exit(exitval); 224 } 225 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 226 227 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 228 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 229 230 validate_status_stopped(status, sigval); 231 232 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 233 SYSCALL_REQUIRE( 234 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 235 236 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 237 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 238 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 239 info.psi_siginfo.si_errno); 240 241 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 242 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 243 244 DPRINTF("Before resuming the child process where it left off and " 245 "without signal to be sent\n"); 246 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 247 248 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 249 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 250 251 validate_status_stopped(status, sigignored); 252 253 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 254 SYSCALL_REQUIRE( 255 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 256 257 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 258 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 259 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 260 info.psi_siginfo.si_errno); 261 262 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored); 263 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 264 265 DPRINTF("Before resuming the child process where it left off and " 266 "without signal to be sent\n"); 267 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 268 269 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 270 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 271 272 validate_status_exited(status, exitval); 273 274 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 275 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 276} 277 278#define TRACEME_RAISESIGNAL_IGNORED(test, sig) \ 279ATF_TC(test); \ 280ATF_TC_HEAD(test, tc) \ 281{ \ 282 atf_tc_set_md_var(tc, "descr", \ 283 "Verify that ignoring (with SIG_IGN) " #sig " in tracee " \ 284 "does not stop tracer from catching this raised signal"); \ 285} \ 286 \ 287ATF_TC_BODY(test, tc) \ 288{ \ 289 \ 290 traceme_raisesignal_ignored(sig); \ 291} 292 293// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 294TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */ 295TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP) /* hangup */ 296TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */ 297TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */ 298TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */ 299TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */ 300TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */ 301TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */ 302 303/// ---------------------------------------------------------------------------- 304 305static void 306traceme_raisesignal_masked(int sigmasked) 307{ 308 const int exitval = 5; 309 const int sigval = SIGSTOP; 310 pid_t child, wpid; 311#if defined(TWAIT_HAVE_STATUS) 312 int status; 313#endif 314 sigset_t intmask; 315 struct ptrace_siginfo info; 316 317 memset(&info, 0, sizeof(info)); 318 319 DPRINTF("Before forking process PID=%d\n", getpid()); 320 SYSCALL_REQUIRE((child = fork()) != -1); 321 if (child == 0) { 322 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 323 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 324 325 sigemptyset(&intmask); 326 sigaddset(&intmask, sigmasked); 327 sigprocmask(SIG_BLOCK, &intmask, NULL); 328 329 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 330 FORKEE_ASSERT(raise(sigval) == 0); 331 332 DPRINTF("Before raising %s breakpoint from child\n", 333 strsignal(sigmasked)); 334 FORKEE_ASSERT(raise(sigmasked) == 0); 335 336 DPRINTF("Before exiting of the child process\n"); 337 _exit(exitval); 338 } 339 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 340 341 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 342 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 343 344 validate_status_stopped(status, sigval); 345 346 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 347 SYSCALL_REQUIRE( 348 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 349 350 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 351 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 352 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 353 info.psi_siginfo.si_errno); 354 355 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 356 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 357 358 DPRINTF("Before resuming the child process where it left off and " 359 "without signal to be sent\n"); 360 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 361 362 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 363 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 364 365 validate_status_exited(status, exitval); 366 367 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 368 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 369} 370 371#define TRACEME_RAISESIGNAL_MASKED(test, sig) \ 372ATF_TC(test); \ 373ATF_TC_HEAD(test, tc) \ 374{ \ 375 atf_tc_set_md_var(tc, "descr", \ 376 "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \ 377 "stops tracer from catching this raised signal"); \ 378} \ 379 \ 380ATF_TC_BODY(test, tc) \ 381{ \ 382 \ 383 traceme_raisesignal_masked(sig); \ 384} 385 386// A signal handler for SIGKILL and SIGSTOP cannot be masked. 387TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */ 388TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */ 389TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */ 390TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */ 391TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */ 392TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */ 393TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */ 394TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */ 395 396/// ---------------------------------------------------------------------------- 397 398static void 399traceme_crash(int sig) 400{ 401 pid_t child, wpid; 402#if defined(TWAIT_HAVE_STATUS) 403 int status; 404#endif 405 struct ptrace_siginfo info; 406 407#ifndef PTRACE_ILLEGAL_ASM 408 if (sig == SIGILL) 409 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 410#endif 411 412 memset(&info, 0, sizeof(info)); 413 414 DPRINTF("Before forking process PID=%d\n", getpid()); 415 SYSCALL_REQUIRE((child = fork()) != -1); 416 if (child == 0) { 417 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 418 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 419 420 DPRINTF("Before executing a trap\n"); 421 switch (sig) { 422 case SIGTRAP: 423 trigger_trap(); 424 break; 425 case SIGSEGV: 426 trigger_segv(); 427 break; 428 case SIGILL: 429 trigger_ill(); 430 break; 431 case SIGFPE: 432 trigger_fpe(); 433 break; 434 case SIGBUS: 435 trigger_bus(); 436 break; 437 default: 438 /* NOTREACHED */ 439 FORKEE_ASSERTX(0 && "This shall not be reached"); 440 } 441 442 /* NOTREACHED */ 443 FORKEE_ASSERTX(0 && "This shall not be reached"); 444 } 445 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 446 447 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 448 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 449 450 validate_status_stopped(status, sig); 451 452 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 453 SYSCALL_REQUIRE( 454 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 455 456 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 457 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 458 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 459 info.psi_siginfo.si_errno); 460 461 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 462 switch (sig) { 463 case SIGTRAP: 464 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 465 break; 466 case SIGSEGV: 467 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 468 break; 469 case SIGILL: 470 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 471 break; 472 case SIGFPE: 473 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 474 break; 475 case SIGBUS: 476 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 477 break; 478 } 479 480 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 481 482 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 483 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 484 485 validate_status_signaled(status, SIGKILL, 0); 486 487 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 488 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 489} 490 491#define TRACEME_CRASH(test, sig) \ 492ATF_TC(test); \ 493ATF_TC_HEAD(test, tc) \ 494{ \ 495 atf_tc_set_md_var(tc, "descr", \ 496 "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \ 497} \ 498 \ 499ATF_TC_BODY(test, tc) \ 500{ \ 501 \ 502 traceme_crash(sig); \ 503} 504 505TRACEME_CRASH(traceme_crash_trap, SIGTRAP) 506TRACEME_CRASH(traceme_crash_segv, SIGSEGV) 507TRACEME_CRASH(traceme_crash_ill, SIGILL) 508TRACEME_CRASH(traceme_crash_fpe, SIGFPE) 509TRACEME_CRASH(traceme_crash_bus, SIGBUS) 510 511/// ---------------------------------------------------------------------------- 512 513static void 514traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 515{ 516 const int exitval = 5; 517 const int sigval = SIGSTOP; 518 pid_t child, wpid; 519 struct sigaction sa; 520#if defined(TWAIT_HAVE_STATUS) 521 int status; 522#endif 523 struct ptrace_siginfo info; 524 525 memset(&info, 0, sizeof(info)); 526 527 DPRINTF("Before forking process PID=%d\n", getpid()); 528 SYSCALL_REQUIRE((child = fork()) != -1); 529 if (child == 0) { 530 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 531 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 532 533 sa.sa_handler = sah; 534 sa.sa_flags = SA_SIGINFO; 535 sigemptyset(&sa.sa_mask); 536 537 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 538 539 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 540 FORKEE_ASSERT(raise(sigval) == 0); 541 542 FORKEE_ASSERT_EQ(*traceme_caught, 1); 543 544 DPRINTF("Before exiting of the child process\n"); 545 _exit(exitval); 546 } 547 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 548 549 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 550 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 551 552 validate_status_stopped(status, sigval); 553 554 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 555 SYSCALL_REQUIRE( 556 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 557 558 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 559 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 560 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 561 info.psi_siginfo.si_errno); 562 563 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 564 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 565 566 DPRINTF("Before resuming the child process where it left off and with " 567 "signal %s to be sent\n", strsignal(sigsent)); 568 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 569 570 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 571 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 572 573 validate_status_exited(status, exitval); 574 575 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 576 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 577} 578 579#define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 580ATF_TC(test); \ 581ATF_TC_HEAD(test, tc) \ 582{ \ 583 atf_tc_set_md_var(tc, "descr", \ 584 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 585 "handled correctly and caught by a signal handler"); \ 586} \ 587 \ 588static int test##_caught = 0; \ 589 \ 590static void \ 591test##_sighandler(int arg) \ 592{ \ 593 FORKEE_ASSERT_EQ(arg, sig); \ 594 \ 595 ++ test##_caught; \ 596} \ 597 \ 598ATF_TC_BODY(test, tc) \ 599{ \ 600 \ 601 traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 602} 603 604// A signal handler for SIGKILL and SIGSTOP cannot be registered. 605TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 606TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 607TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 608TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 609TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 610TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 611TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 612TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 613 614/// ---------------------------------------------------------------------------- 615 616static void 617traceme_sendsignal_masked(int sigsent) 618{ 619 const int exitval = 5; 620 const int sigval = SIGSTOP; 621 pid_t child, wpid; 622 sigset_t set; 623#if defined(TWAIT_HAVE_STATUS) 624 int status; 625#endif 626 struct ptrace_siginfo info; 627 628 memset(&info, 0, sizeof(info)); 629 630 DPRINTF("Before forking process PID=%d\n", getpid()); 631 SYSCALL_REQUIRE((child = fork()) != -1); 632 if (child == 0) { 633 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 634 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 635 636 sigemptyset(&set); 637 sigaddset(&set, sigsent); 638 FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 639 640 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 641 FORKEE_ASSERT(raise(sigval) == 0); 642 643 _exit(exitval); 644 } 645 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 646 647 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 648 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 649 650 validate_status_stopped(status, sigval); 651 652 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 653 SYSCALL_REQUIRE( 654 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 655 656 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 657 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 658 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 659 info.psi_siginfo.si_errno); 660 661 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 662 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 663 664 DPRINTF("Before resuming the child process where it left off and with " 665 "signal %s to be sent\n", strsignal(sigsent)); 666 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 667 668 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 669 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 670 671 validate_status_exited(status, exitval); 672 673 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 674 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 675} 676 677#define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 678ATF_TC(test); \ 679ATF_TC_HEAD(test, tc) \ 680{ \ 681 atf_tc_set_md_var(tc, "descr", \ 682 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 683 "handled correctly and the signal is masked by SIG_BLOCK"); \ 684} \ 685 \ 686ATF_TC_BODY(test, tc) \ 687{ \ 688 \ 689 traceme_sendsignal_masked(sig); \ 690} 691 692// A signal handler for SIGKILL and SIGSTOP cannot be masked. 693TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 694TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 695TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 696TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 697TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 698TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 699TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 700TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 701 702/// ---------------------------------------------------------------------------- 703 704static void 705traceme_sendsignal_ignored(int sigsent) 706{ 707 const int exitval = 5; 708 const int sigval = SIGSTOP; 709 pid_t child, wpid; 710 struct sigaction sa; 711#if defined(TWAIT_HAVE_STATUS) 712 int status; 713#endif 714 struct ptrace_siginfo info; 715 716 memset(&info, 0, sizeof(info)); 717 718 DPRINTF("Before forking process PID=%d\n", getpid()); 719 SYSCALL_REQUIRE((child = fork()) != -1); 720 if (child == 0) { 721 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 722 723 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 724 725 memset(&sa, 0, sizeof(sa)); 726 sa.sa_handler = SIG_IGN; 727 sigemptyset(&sa.sa_mask); 728 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 729 730 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 731 FORKEE_ASSERT(raise(sigval) == 0); 732 733 _exit(exitval); 734 } 735 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 736 737 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 738 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 739 740 validate_status_stopped(status, sigval); 741 742 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 743 SYSCALL_REQUIRE( 744 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 745 746 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 747 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 748 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 749 info.psi_siginfo.si_errno); 750 751 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 752 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 753 754 DPRINTF("Before resuming the child process where it left off and with " 755 "signal %s to be sent\n", strsignal(sigsent)); 756 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 757 758 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 759 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 760 761 validate_status_exited(status, exitval); 762 763 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 764 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 765} 766 767#define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 768ATF_TC(test); \ 769ATF_TC_HEAD(test, tc) \ 770{ \ 771 atf_tc_set_md_var(tc, "descr", \ 772 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 773 "handled correctly and the signal is masked by SIG_IGN"); \ 774} \ 775 \ 776ATF_TC_BODY(test, tc) \ 777{ \ 778 \ 779 traceme_sendsignal_ignored(sig); \ 780} 781 782// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 783TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 784TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 785TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 786TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 787TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 788TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 789TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 790TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 791 792/// ---------------------------------------------------------------------------- 793 794static void 795traceme_sendsignal_simple(int sigsent) 796{ 797 const int sigval = SIGSTOP; 798 int exitval = 0; 799 pid_t child, wpid; 800#if defined(TWAIT_HAVE_STATUS) 801 int status; 802 int expect_core; 803 804 switch (sigsent) { 805 case SIGABRT: 806 case SIGTRAP: 807 case SIGBUS: 808 case SIGILL: 809 case SIGFPE: 810 case SIGSEGV: 811 expect_core = 1; 812 break; 813 default: 814 expect_core = 0; 815 break; 816 } 817#endif 818 struct ptrace_siginfo info; 819 820 memset(&info, 0, sizeof(info)); 821 822 DPRINTF("Before forking process PID=%d\n", getpid()); 823 SYSCALL_REQUIRE((child = fork()) != -1); 824 if (child == 0) { 825 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 826 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 827 828 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 829 FORKEE_ASSERT(raise(sigval) == 0); 830 831 switch (sigsent) { 832 case SIGCONT: 833 case SIGSTOP: 834 _exit(exitval); 835 default: 836 /* NOTREACHED */ 837 FORKEE_ASSERTX(0 && "This shall not be reached"); 838 } 839 } 840 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 841 842 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 843 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 844 845 validate_status_stopped(status, sigval); 846 847 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 848 SYSCALL_REQUIRE( 849 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 850 851 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 852 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 853 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 854 info.psi_siginfo.si_errno); 855 856 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 857 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 858 859 DPRINTF("Before resuming the child process where it left off and with " 860 "signal %s to be sent\n", strsignal(sigsent)); 861 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -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 switch (sigsent) { 867 case SIGSTOP: 868 validate_status_stopped(status, sigsent); 869 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 870 "child\n"); 871 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 872 sizeof(info)) != -1); 873 874 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 875 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 876 "si_errno=%#x\n", 877 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 878 info.psi_siginfo.si_errno); 879 880 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 881 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 882 883 DPRINTF("Before resuming the child process where it left off " 884 "and with signal %s to be sent\n", strsignal(sigsent)); 885 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 886 887 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 888 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 889 child); 890 /* FALLTHROUGH */ 891 case SIGCONT: 892 validate_status_exited(status, exitval); 893 break; 894 default: 895 validate_status_signaled(status, sigsent, expect_core); 896 break; 897 } 898 899 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 900 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 901} 902 903#define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 904ATF_TC(test); \ 905ATF_TC_HEAD(test, tc) \ 906{ \ 907 atf_tc_set_md_var(tc, "descr", \ 908 "Verify that a signal " #sig " emitted by a tracer to a child is " \ 909 "handled correctly in a child without a signal handler"); \ 910} \ 911 \ 912ATF_TC_BODY(test, tc) \ 913{ \ 914 \ 915 traceme_sendsignal_simple(sig); \ 916} 917 918TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 919TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 920TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 921TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 922TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 923TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 924TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 925TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 926TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 927TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 928 929/// ---------------------------------------------------------------------------- 930 931ATF_TC(traceme_pid1_parent); 932ATF_TC_HEAD(traceme_pid1_parent, tc) 933{ 934 atf_tc_set_md_var(tc, "descr", 935 "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 936} 937 938ATF_TC_BODY(traceme_pid1_parent, tc) 939{ 940 struct msg_fds parent_child; 941 int exitval_child1 = 1, exitval_child2 = 2; 942 pid_t child1, child2, wpid; 943 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 944#if defined(TWAIT_HAVE_STATUS) 945 int status; 946#endif 947 948 SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 949 950 DPRINTF("Before forking process PID=%d\n", getpid()); 951 SYSCALL_REQUIRE((child1 = fork()) != -1); 952 if (child1 == 0) { 953 DPRINTF("Before forking process PID=%d\n", getpid()); 954 SYSCALL_REQUIRE((child2 = fork()) != -1); 955 if (child2 != 0) { 956 DPRINTF("Parent process PID=%d, child2's PID=%d\n", 957 getpid(), child2); 958 _exit(exitval_child1); 959 } 960 CHILD_FROM_PARENT("exit child1", parent_child, msg); 961 962 DPRINTF("Assert that our parent is PID1 (initproc)\n"); 963 FORKEE_ASSERT_EQ(getppid(), 1); 964 965 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 966 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 967 SYSCALL_REQUIRE_ERRNO(errno, EPERM); 968 969 CHILD_TO_PARENT("child2 exiting", parent_child, msg); 970 971 _exit(exitval_child2); 972 } 973 DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 974 975 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 976 TWAIT_REQUIRE_SUCCESS( 977 wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 978 979 validate_status_exited(status, exitval_child1); 980 981 DPRINTF("Notify that child1 is dead\n"); 982 PARENT_TO_CHILD("exit child1", parent_child, msg); 983 984 DPRINTF("Wait for exiting of child2\n"); 985 PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 986} 987 988/// ---------------------------------------------------------------------------- 989 990static void 991traceme_vfork_raise(int sigval) 992{ 993 const int exitval = 5, exitval_watcher = 10; 994 pid_t child, parent, watcher, wpid; 995 int rv; 996#if defined(TWAIT_HAVE_STATUS) 997 int status; 998 999 /* volatile workarounds GCC -Werror=clobbered */ 1000 volatile int expect_core; 1001 1002 switch (sigval) { 1003 case SIGABRT: 1004 case SIGTRAP: 1005 case SIGBUS: 1006 case SIGILL: 1007 case SIGFPE: 1008 case SIGSEGV: 1009 expect_core = 1; 1010 break; 1011 default: 1012 expect_core = 0; 1013 break; 1014 } 1015#endif 1016 1017 /* 1018 * Spawn a dedicated thread to watch for a stopped child and emit 1019 * the SIGKILL signal to it. 1020 * 1021 * vfork(2) might clobber watcher, this means that it's safer and 1022 * simpler to reparent this process to initproc and forget about it. 1023 */ 1024 if (sigval == SIGSTOP) { 1025 parent = getpid(); 1026 1027 watcher = fork(); 1028 ATF_REQUIRE(watcher != 1); 1029 if (watcher == 0) { 1030 /* Double fork(2) trick to reparent to initproc */ 1031 watcher = fork(); 1032 FORKEE_ASSERT_NEQ(watcher, -1); 1033 if (watcher != 0) 1034 _exit(exitval_watcher); 1035 1036 child = await_stopped_child(parent); 1037 1038 errno = 0; 1039 rv = kill(child, SIGKILL); 1040 FORKEE_ASSERT_EQ(rv, 0); 1041 FORKEE_ASSERT_EQ(errno, 0); 1042 1043 /* This exit value will be collected by initproc */ 1044 _exit(0); 1045 } 1046 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1047 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 1048 watcher); 1049 1050 validate_status_exited(status, exitval_watcher); 1051 1052 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1053 TWAIT_REQUIRE_FAILURE(ECHILD, 1054 wpid = TWAIT_GENERIC(watcher, &status, 0)); 1055 } 1056 1057 DPRINTF("Before forking process PID=%d\n", getpid()); 1058 SYSCALL_REQUIRE((child = vfork()) != -1); 1059 if (child == 0) { 1060 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1061 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1062 1063 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1064 FORKEE_ASSERT(raise(sigval) == 0); 1065 1066 switch (sigval) { 1067 case SIGSTOP: 1068 case SIGKILL: 1069 case SIGABRT: 1070 case SIGHUP: 1071 case SIGTRAP: 1072 case SIGBUS: 1073 case SIGILL: 1074 case SIGFPE: 1075 case SIGSEGV: 1076 /* NOTREACHED */ 1077 FORKEE_ASSERTX(0 && "This shall not be reached"); 1078 __unreachable(); 1079 default: 1080 DPRINTF("Before exiting of the child process\n"); 1081 _exit(exitval); 1082 } 1083 } 1084 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1085 1086 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1087 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1088 1089 switch (sigval) { 1090 case SIGKILL: 1091 case SIGABRT: 1092 case SIGHUP: 1093 case SIGTRAP: 1094 case SIGBUS: 1095 case SIGILL: 1096 case SIGFPE: 1097 case SIGSEGV: 1098 validate_status_signaled(status, sigval, expect_core); 1099 break; 1100 case SIGSTOP: 1101 validate_status_signaled(status, SIGKILL, 0); 1102 break; 1103 case SIGCONT: 1104 case SIGTSTP: 1105 case SIGTTIN: 1106 case SIGTTOU: 1107 validate_status_exited(status, exitval); 1108 break; 1109 default: 1110 /* NOTREACHED */ 1111 ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 1112 break; 1113 } 1114 1115 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1116 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1117} 1118 1119#define TRACEME_VFORK_RAISE(test, sig) \ 1120ATF_TC(test); \ 1121ATF_TC_HEAD(test, tc) \ 1122{ \ 1123 atf_tc_set_md_var(tc, "descr", \ 1124 "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 1125 "vfork(2)ed child"); \ 1126} \ 1127 \ 1128ATF_TC_BODY(test, tc) \ 1129{ \ 1130 \ 1131 traceme_vfork_raise(sig); \ 1132} 1133 1134TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 1135TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 1136TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 1137TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 1138TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 1139TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 1140TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 1141TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 1142TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 1143TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 1144TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 1145TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 1146TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 1147 1148/// ---------------------------------------------------------------------------- 1149 1150static void 1151traceme_vfork_crash(int sig) 1152{ 1153 pid_t child, wpid; 1154#if defined(TWAIT_HAVE_STATUS) 1155 int status; 1156#endif 1157 1158#ifndef PTRACE_ILLEGAL_ASM 1159 if (sig == SIGILL) 1160 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1161#endif 1162 1163 DPRINTF("Before forking process PID=%d\n", getpid()); 1164 SYSCALL_REQUIRE((child = vfork()) != -1); 1165 if (child == 0) { 1166 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1167 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1168 1169 DPRINTF("Before executing a trap\n"); 1170 switch (sig) { 1171 case SIGTRAP: 1172 trigger_trap(); 1173 break; 1174 case SIGSEGV: 1175 trigger_segv(); 1176 break; 1177 case SIGILL: 1178 trigger_ill(); 1179 break; 1180 case SIGFPE: 1181 trigger_fpe(); 1182 break; 1183 case SIGBUS: 1184 trigger_bus(); 1185 break; 1186 default: 1187 /* NOTREACHED */ 1188 FORKEE_ASSERTX(0 && "This shall not be reached"); 1189 } 1190 1191 /* NOTREACHED */ 1192 FORKEE_ASSERTX(0 && "This shall not be reached"); 1193 } 1194 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1195 1196 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1197 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1198 1199 validate_status_signaled(status, sig, 1); 1200 1201 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1202 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1203} 1204 1205#define TRACEME_VFORK_CRASH(test, sig) \ 1206ATF_TC(test); \ 1207ATF_TC_HEAD(test, tc) \ 1208{ \ 1209 atf_tc_set_md_var(tc, "descr", \ 1210 "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 1211 "vfork(2)ed child"); \ 1212} \ 1213 \ 1214ATF_TC_BODY(test, tc) \ 1215{ \ 1216 \ 1217 traceme_vfork_crash(sig); \ 1218} 1219 1220TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 1221TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 1222TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 1223TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 1224TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 1225 1226/// ---------------------------------------------------------------------------- 1227 1228ATF_TC(traceme_vfork_exec); 1229ATF_TC_HEAD(traceme_vfork_exec, tc) 1230{ 1231 atf_tc_set_md_var(tc, "descr", 1232 "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child"); 1233} 1234 1235ATF_TC_BODY(traceme_vfork_exec, tc) 1236{ 1237 const int sigval = SIGTRAP; 1238 pid_t child, wpid; 1239#if defined(TWAIT_HAVE_STATUS) 1240 int status; 1241#endif 1242 struct ptrace_siginfo info; 1243 1244 memset(&info, 0, sizeof(info)); 1245 1246 DPRINTF("Before forking process PID=%d\n", getpid()); 1247 SYSCALL_REQUIRE((child = vfork()) != -1); 1248 if (child == 0) { 1249 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1250 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1251 1252 DPRINTF("Before calling execve(2) from child\n"); 1253 execlp("/bin/echo", "/bin/echo", NULL); 1254 1255 /* NOTREACHED */ 1256 FORKEE_ASSERTX(0 && "Not reached"); 1257 } 1258 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1259 1260 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1262 1263 validate_status_stopped(status, sigval); 1264 1265 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1266 SYSCALL_REQUIRE( 1267 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1268 1269 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1270 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1271 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1272 info.psi_siginfo.si_errno); 1273 1274 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1275 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1276 1277 DPRINTF("Before resuming the child process where it left off and " 1278 "without signal to be sent\n"); 1279 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1280 1281 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1282 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1283 1284 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1285 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1286} 1287 1288/// ---------------------------------------------------------------------------- 1289 1290#if defined(TWAIT_HAVE_PID) 1291static void 1292unrelated_tracer_sees_crash(int sig) 1293{ 1294 struct msg_fds parent_tracee, parent_tracer; 1295 const int exitval = 10; 1296 pid_t tracee, tracer, wpid; 1297 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1298#if defined(TWAIT_HAVE_STATUS) 1299 int status; 1300#endif 1301 struct ptrace_siginfo info; 1302 1303#ifndef PTRACE_ILLEGAL_ASM 1304 if (sig == SIGILL) 1305 atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 1306#endif 1307 1308 memset(&info, 0, sizeof(info)); 1309 1310 DPRINTF("Spawn tracee\n"); 1311 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1312 tracee = atf_utils_fork(); 1313 if (tracee == 0) { 1314 // Wait for parent to let us crash 1315 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 1316 1317 DPRINTF("Before executing a trap\n"); 1318 switch (sig) { 1319 case SIGTRAP: 1320 trigger_trap(); 1321 break; 1322 case SIGSEGV: 1323 trigger_segv(); 1324 break; 1325 case SIGILL: 1326 trigger_ill(); 1327 break; 1328 case SIGFPE: 1329 trigger_fpe(); 1330 break; 1331 case SIGBUS: 1332 trigger_bus(); 1333 break; 1334 default: 1335 /* NOTREACHED */ 1336 FORKEE_ASSERTX(0 && "This shall not be reached"); 1337 } 1338 1339 /* NOTREACHED */ 1340 FORKEE_ASSERTX(0 && "This shall not be reached"); 1341 } 1342 1343 DPRINTF("Spawn debugger\n"); 1344 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 1345 tracer = atf_utils_fork(); 1346 if (tracer == 0) { 1347 /* Fork again and drop parent to reattach to PID 1 */ 1348 tracer = atf_utils_fork(); 1349 if (tracer != 0) 1350 _exit(exitval); 1351 1352 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 1353 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 1354 1355 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 1356 FORKEE_REQUIRE_SUCCESS( 1357 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1358 1359 forkee_status_stopped(status, SIGSTOP); 1360 1361 /* Resume tracee with PT_CONTINUE */ 1362 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1363 1364 /* Inform parent that tracer has attached to tracee */ 1365 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 1366 1367 /* Wait for parent to tell use that tracee should have exited */ 1368 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 1369 1370 /* Wait for tracee and assert that it exited */ 1371 FORKEE_REQUIRE_SUCCESS( 1372 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1373 1374 validate_status_stopped(status, sig); 1375 1376 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 1377 "traced process\n"); 1378 SYSCALL_REQUIRE( 1379 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1380 1381 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1382 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1383 "si_errno=%#x\n", info.psi_siginfo.si_signo, 1384 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 1385 1386 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 1387 switch (sig) { 1388 case SIGTRAP: 1389 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 1390 break; 1391 case SIGSEGV: 1392 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 1393 break; 1394 case SIGILL: 1395 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 1396 break; 1397 case SIGFPE: 1398 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 1399 break; 1400 case SIGBUS: 1401 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 1402 break; 1403 } 1404 1405 FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 1406 DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 1407 TWAIT_REQUIRE_SUCCESS( 1408 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1409 1410 validate_status_signaled(status, SIGKILL, 0); 1411 1412 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 1413 TWAIT_REQUIRE_FAILURE(ECHILD, 1414 wpid = TWAIT_GENERIC(tracee, &status, 0)); 1415 1416 /* Inform parent that tracer is exiting normally */ 1417 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 1418 1419 DPRINTF("Before exiting of the tracer process\n"); 1420 _exit(0 /* collect by initproc */); 1421 } 1422 1423 DPRINTF("Wait for the tracer process (direct child) to exit " 1424 "calling %s()\n", TWAIT_FNAME); 1425 TWAIT_REQUIRE_SUCCESS( 1426 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 1427 1428 validate_status_exited(status, exitval); 1429 1430 DPRINTF("Wait for the non-exited tracee process with %s()\n", 1431 TWAIT_FNAME); 1432 TWAIT_REQUIRE_SUCCESS( 1433 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 1434 1435 DPRINTF("Wait for the tracer to attach to the tracee\n"); 1436 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 1437 1438 DPRINTF("Resume the tracee and let it crash\n"); 1439 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 1440 1441 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 1442 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 1443 1444 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 1445 TWAIT_FNAME); 1446 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1447 1448 validate_status_signaled(status, SIGKILL, 0); 1449 1450 DPRINTF("Await normal exit of tracer\n"); 1451 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 1452 1453 msg_close(&parent_tracer); 1454 msg_close(&parent_tracee); 1455} 1456 1457#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 1458ATF_TC(test); \ 1459ATF_TC_HEAD(test, tc) \ 1460{ \ 1461 atf_tc_set_md_var(tc, "descr", \ 1462 "Assert that an unrelated tracer sees crash signal from the " \ 1463 "debuggee"); \ 1464} \ 1465 \ 1466ATF_TC_BODY(test, tc) \ 1467{ \ 1468 \ 1469 unrelated_tracer_sees_crash(sig); \ 1470} 1471 1472UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 1473UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 1474UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 1475UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 1476UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 1477#endif 1478 1479/// ---------------------------------------------------------------------------- 1480 1481#if defined(TWAIT_HAVE_PID) 1482static void 1483tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 1484 bool stopped) 1485{ 1486 /* 1487 * notimeout - disable timeout in await zombie function 1488 * unrelated - attach from unrelated tracer reparented to initproc 1489 * stopped - attach to a stopped process 1490 */ 1491 1492 struct msg_fds parent_tracee, parent_tracer; 1493 const int exitval_tracee = 5; 1494 const int exitval_tracer = 10; 1495 pid_t tracee, tracer, wpid; 1496 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1497#if defined(TWAIT_HAVE_STATUS) 1498 int status; 1499#endif 1500 1501 /* 1502 * Only a subset of options are supported. 1503 */ 1504 ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 1505 (!notimeout && unrelated && !stopped) || 1506 (notimeout && !unrelated && !stopped) || 1507 (!notimeout && unrelated && stopped)); 1508 1509 DPRINTF("Spawn tracee\n"); 1510 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1511 tracee = atf_utils_fork(); 1512 if (tracee == 0) { 1513 if (stopped) { 1514 DPRINTF("Stop self PID %d\n", getpid()); 1515 raise(SIGSTOP); 1516 } 1517 1518 // Wait for parent to let us exit 1519 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 1520 _exit(exitval_tracee); 1521 } 1522 1523 DPRINTF("Spawn debugger\n"); 1524 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 1525 tracer = atf_utils_fork(); 1526 if (tracer == 0) { 1527 if(unrelated) { 1528 /* Fork again and drop parent to reattach to PID 1 */ 1529 tracer = atf_utils_fork(); 1530 if (tracer != 0) 1531 _exit(exitval_tracer); 1532 } 1533 1534 if (stopped) { 1535 DPRINTF("Await for a stopped parent PID %d\n", tracee); 1536 await_stopped(tracee); 1537 } 1538 1539 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 1540 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 1541 1542 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 1543 FORKEE_REQUIRE_SUCCESS( 1544 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1545 1546 forkee_status_stopped(status, SIGSTOP); 1547 1548 /* Resume tracee with PT_CONTINUE */ 1549 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1550 1551 /* Inform parent that tracer has attached to tracee */ 1552 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 1553 1554 /* Wait for parent to tell use that tracee should have exited */ 1555 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 1556 1557 /* Wait for tracee and assert that it exited */ 1558 FORKEE_REQUIRE_SUCCESS( 1559 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1560 1561 forkee_status_exited(status, exitval_tracee); 1562 DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 1563 1564 DPRINTF("Before exiting of the tracer process\n"); 1565 _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 1566 } 1567 1568 if (unrelated) { 1569 DPRINTF("Wait for the tracer process (direct child) to exit " 1570 "calling %s()\n", TWAIT_FNAME); 1571 TWAIT_REQUIRE_SUCCESS( 1572 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 1573 1574 validate_status_exited(status, exitval_tracer); 1575 1576 DPRINTF("Wait for the non-exited tracee process with %s()\n", 1577 TWAIT_FNAME); 1578 TWAIT_REQUIRE_SUCCESS( 1579 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 1580 } 1581 1582 DPRINTF("Wait for the tracer to attach to the tracee\n"); 1583 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 1584 1585 DPRINTF("Resume the tracee and let it exit\n"); 1586 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 1587 1588 DPRINTF("Detect that tracee is zombie\n"); 1589 if (notimeout) 1590 await_zombie_raw(tracee, 0); 1591 else 1592 await_zombie(tracee); 1593 1594 DPRINTF("Assert that there is no status about tracee %d - " 1595 "Tracer must detect zombie first - calling %s()\n", tracee, 1596 TWAIT_FNAME); 1597 TWAIT_REQUIRE_SUCCESS( 1598 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 1599 1600 if (unrelated) { 1601 DPRINTF("Resume the tracer and let it detect exited tracee\n"); 1602 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 1603 } else { 1604 DPRINTF("Tell the tracer child should have exited\n"); 1605 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 1606 DPRINTF("Wait for tracer to finish its job and exit - calling " 1607 "%s()\n", TWAIT_FNAME); 1608 1609 DPRINTF("Wait from tracer child to complete waiting for " 1610 "tracee\n"); 1611 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 1612 tracer); 1613 1614 validate_status_exited(status, exitval_tracer); 1615 } 1616 1617 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 1618 TWAIT_FNAME); 1619 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1620 1621 validate_status_exited(status, exitval_tracee); 1622 1623 msg_close(&parent_tracer); 1624 msg_close(&parent_tracee); 1625} 1626 1627ATF_TC(tracer_sees_terminaton_before_the_parent); 1628ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 1629{ 1630 atf_tc_set_md_var(tc, "descr", 1631 "Assert that tracer sees process termination before the parent"); 1632} 1633 1634ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 1635{ 1636 1637 tracer_sees_terminaton_before_the_parent_raw(false, false, false); 1638} 1639 1640ATF_TC(tracer_sysctl_lookup_without_duplicates); 1641ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 1642{ 1643 atf_tc_set_md_var(tc, "descr", 1644 "Assert that await_zombie() in attach1 always finds a single " 1645 "process and no other error is reported"); 1646} 1647 1648ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 1649{ 1650 time_t start, end; 1651 double diff; 1652 unsigned long N = 0; 1653 1654 /* 1655 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 1656 * This test body isn't specific to this race, however it's just good 1657 * enough for this purposes, no need to invent a dedicated code flow. 1658 */ 1659 1660 start = time(NULL); 1661 while (true) { 1662 DPRINTF("Step: %lu\n", N); 1663 tracer_sees_terminaton_before_the_parent_raw(true, false, 1664 false); 1665 end = time(NULL); 1666 diff = difftime(end, start); 1667 if (diff >= 5.0) 1668 break; 1669 ++N; 1670 } 1671 DPRINTF("Iterations: %lu\n", N); 1672} 1673 1674ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 1675ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 1676{ 1677 atf_tc_set_md_var(tc, "descr", 1678 "Assert that tracer sees process termination before the parent"); 1679} 1680 1681ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 1682{ 1683 1684 tracer_sees_terminaton_before_the_parent_raw(false, true, false); 1685} 1686 1687ATF_TC(tracer_attach_to_unrelated_stopped_process); 1688ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 1689{ 1690 atf_tc_set_md_var(tc, "descr", 1691 "Assert that tracer can attach to an unrelated stopped process"); 1692} 1693 1694ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 1695{ 1696 1697 tracer_sees_terminaton_before_the_parent_raw(false, true, true); 1698} 1699#endif 1700 1701/// ---------------------------------------------------------------------------- 1702 1703static void 1704parent_attach_to_its_child(bool stopped) 1705{ 1706 struct msg_fds parent_tracee; 1707 const int exitval_tracee = 5; 1708 pid_t tracee, wpid; 1709 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1710#if defined(TWAIT_HAVE_STATUS) 1711 int status; 1712#endif 1713 1714 DPRINTF("Spawn tracee\n"); 1715 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1716 tracee = atf_utils_fork(); 1717 if (tracee == 0) { 1718 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 1719 DPRINTF("Parent should now attach to tracee\n"); 1720 1721 if (stopped) { 1722 DPRINTF("Stop self PID %d\n", getpid()); 1723 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 1724 } 1725 1726 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 1727 /* Wait for message from the parent */ 1728 _exit(exitval_tracee); 1729 } 1730 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 1731 1732 if (stopped) { 1733 DPRINTF("Await for a stopped tracee PID %d\n", tracee); 1734 await_stopped(tracee); 1735 } 1736 1737 DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 1738 SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 1739 1740 DPRINTF("Wait for the stopped tracee process with %s()\n", 1741 TWAIT_FNAME); 1742 TWAIT_REQUIRE_SUCCESS( 1743 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1744 1745 validate_status_stopped(status, SIGSTOP); 1746 1747 DPRINTF("Resume tracee with PT_CONTINUE\n"); 1748 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1749 1750 DPRINTF("Let the tracee exit now\n"); 1751 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 1752 1753 DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 1754 TWAIT_REQUIRE_SUCCESS( 1755 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1756 1757 validate_status_exited(status, exitval_tracee); 1758 1759 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 1760 TWAIT_REQUIRE_FAILURE(ECHILD, 1761 wpid = TWAIT_GENERIC(tracee, &status, 0)); 1762 1763 msg_close(&parent_tracee); 1764} 1765 1766ATF_TC(parent_attach_to_its_child); 1767ATF_TC_HEAD(parent_attach_to_its_child, tc) 1768{ 1769 atf_tc_set_md_var(tc, "descr", 1770 "Assert that tracer parent can PT_ATTACH to its child"); 1771} 1772 1773ATF_TC_BODY(parent_attach_to_its_child, tc) 1774{ 1775 1776 parent_attach_to_its_child(false); 1777} 1778 1779ATF_TC(parent_attach_to_its_stopped_child); 1780ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 1781{ 1782 atf_tc_set_md_var(tc, "descr", 1783 "Assert that tracer parent can PT_ATTACH to its stopped child"); 1784} 1785 1786ATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 1787{ 1788 1789 parent_attach_to_its_child(true); 1790} 1791 1792/// ---------------------------------------------------------------------------- 1793 1794static void 1795child_attach_to_its_parent(bool stopped) 1796{ 1797 struct msg_fds parent_tracee; 1798 const int exitval_tracer = 5; 1799 pid_t tracer, wpid; 1800 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1801#if defined(TWAIT_HAVE_STATUS) 1802 int status; 1803#endif 1804 1805 DPRINTF("Spawn tracer\n"); 1806 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1807 tracer = atf_utils_fork(); 1808 if (tracer == 0) { 1809 /* Wait for message from the parent */ 1810 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 1811 1812 if (stopped) { 1813 DPRINTF("Await for a stopped parent PID %d\n", 1814 getppid()); 1815 await_stopped(getppid()); 1816 } 1817 1818 DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 1819 getppid()); 1820 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 1821 1822 DPRINTF("Wait for the stopped parent process with %s()\n", 1823 TWAIT_FNAME); 1824 FORKEE_REQUIRE_SUCCESS( 1825 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 1826 1827 forkee_status_stopped(status, SIGSTOP); 1828 1829 DPRINTF("Resume parent with PT_DETACH\n"); 1830 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 1831 != -1); 1832 1833 /* Tell parent we are ready */ 1834 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 1835 1836 _exit(exitval_tracer); 1837 } 1838 1839 DPRINTF("Wait for the tracer to become ready\n"); 1840 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 1841 1842 if (stopped) { 1843 DPRINTF("Stop self PID %d\n", getpid()); 1844 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 1845 } 1846 1847 DPRINTF("Allow the tracer to exit now\n"); 1848 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 1849 1850 DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 1851 TWAIT_REQUIRE_SUCCESS( 1852 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 1853 1854 validate_status_exited(status, exitval_tracer); 1855 1856 DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 1857 TWAIT_REQUIRE_FAILURE(ECHILD, 1858 wpid = TWAIT_GENERIC(tracer, &status, 0)); 1859 1860 msg_close(&parent_tracee); 1861} 1862 1863ATF_TC(child_attach_to_its_parent); 1864ATF_TC_HEAD(child_attach_to_its_parent, tc) 1865{ 1866 atf_tc_set_md_var(tc, "descr", 1867 "Assert that tracer child can PT_ATTACH to its parent"); 1868} 1869 1870ATF_TC_BODY(child_attach_to_its_parent, tc) 1871{ 1872 1873 child_attach_to_its_parent(false); 1874} 1875 1876ATF_TC(child_attach_to_its_stopped_parent); 1877ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 1878{ 1879 atf_tc_set_md_var(tc, "descr", 1880 "Assert that tracer child can PT_ATTACH to its stopped parent"); 1881} 1882 1883ATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 1884{ 1885 /* 1886 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 1887 * this causes a pipe (established from atf-run) to be broken. 1888 * atf-run uses this mechanism to monitor whether a test is alive. 1889 * 1890 * As a workaround spawn this test as a subprocess. 1891 */ 1892 1893 const int exitval = 15; 1894 pid_t child, wpid; 1895#if defined(TWAIT_HAVE_STATUS) 1896 int status; 1897#endif 1898 1899 SYSCALL_REQUIRE((child = fork()) != -1); 1900 if (child == 0) { 1901 child_attach_to_its_parent(true); 1902 _exit(exitval); 1903 } else { 1904 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1905 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1906 1907 validate_status_exited(status, exitval); 1908 1909 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 1910 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1911 } 1912} 1913 1914/// ---------------------------------------------------------------------------- 1915 1916#if defined(TWAIT_HAVE_PID) 1917 1918enum tracee_sees_its_original_parent_type { 1919 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 1920 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 1921 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 1922}; 1923 1924static void 1925tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 1926{ 1927 struct msg_fds parent_tracer, parent_tracee; 1928 const int exitval_tracee = 5; 1929 const int exitval_tracer = 10; 1930 pid_t parent, tracee, tracer, wpid; 1931 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1932#if defined(TWAIT_HAVE_STATUS) 1933 int status; 1934#endif 1935 /* sysctl(3) - kinfo_proc2 */ 1936 int name[CTL_MAXNAME]; 1937 struct kinfo_proc2 kp; 1938 size_t len = sizeof(kp); 1939 unsigned int namelen; 1940 1941 /* procfs - status */ 1942 FILE *fp; 1943 struct stat st; 1944 const char *fname = "/proc/curproc/status"; 1945 char s_executable[MAXPATHLEN]; 1946 int s_pid, s_ppid; 1947 int rv; 1948 1949 if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 1950 SYSCALL_REQUIRE( 1951 (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 1952 if (rv != 0) 1953 atf_tc_skip("/proc/curproc/status not found"); 1954 } 1955 1956 DPRINTF("Spawn tracee\n"); 1957 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 1958 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1959 tracee = atf_utils_fork(); 1960 if (tracee == 0) { 1961 parent = getppid(); 1962 1963 /* Emit message to the parent */ 1964 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 1965 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 1966 1967 switch (type) { 1968 case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 1969 FORKEE_ASSERT_EQ(parent, getppid()); 1970 break; 1971 case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 1972 namelen = 0; 1973 name[namelen++] = CTL_KERN; 1974 name[namelen++] = KERN_PROC2; 1975 name[namelen++] = KERN_PROC_PID; 1976 name[namelen++] = getpid(); 1977 name[namelen++] = len; 1978 name[namelen++] = 1; 1979 1980 FORKEE_ASSERT_EQ( 1981 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1982 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 1983 break; 1984 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 1985 /* 1986 * Format: 1987 * EXECUTABLE PID PPID ... 1988 */ 1989 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 1990 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 1991 FORKEE_ASSERT_EQ(fclose(fp), 0); 1992 FORKEE_ASSERT_EQ(parent, s_ppid); 1993 break; 1994 } 1995 1996 _exit(exitval_tracee); 1997 } 1998 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 1999 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 2000 2001 DPRINTF("Spawn debugger\n"); 2002 tracer = atf_utils_fork(); 2003 if (tracer == 0) { 2004 /* No IPC to communicate with the child */ 2005 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2006 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2007 2008 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2009 FORKEE_REQUIRE_SUCCESS( 2010 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2011 2012 forkee_status_stopped(status, SIGSTOP); 2013 2014 /* Resume tracee with PT_CONTINUE */ 2015 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2016 2017 /* Inform parent that tracer has attached to tracee */ 2018 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2019 2020 /* Wait for parent to tell use that tracee should have exited */ 2021 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2022 2023 /* Wait for tracee and assert that it exited */ 2024 FORKEE_REQUIRE_SUCCESS( 2025 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2026 2027 forkee_status_exited(status, exitval_tracee); 2028 2029 DPRINTF("Before exiting of the tracer process\n"); 2030 _exit(exitval_tracer); 2031 } 2032 2033 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2034 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2035 2036 DPRINTF("Resume the tracee and let it exit\n"); 2037 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2038 2039 DPRINTF("Detect that tracee is zombie\n"); 2040 await_zombie(tracee); 2041 2042 DPRINTF("Assert that there is no status about tracee - " 2043 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 2044 TWAIT_REQUIRE_SUCCESS( 2045 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2046 2047 DPRINTF("Tell the tracer child should have exited\n"); 2048 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2049 2050 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 2051 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2052 tracer); 2053 2054 validate_status_exited(status, exitval_tracer); 2055 2056 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2057 TWAIT_FNAME); 2058 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 2059 tracee); 2060 2061 validate_status_exited(status, exitval_tracee); 2062 2063 msg_close(&parent_tracer); 2064 msg_close(&parent_tracee); 2065} 2066 2067#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 2068ATF_TC(test); \ 2069ATF_TC_HEAD(test, tc) \ 2070{ \ 2071 atf_tc_set_md_var(tc, "descr", \ 2072 "Assert that tracee sees its original parent when being traced " \ 2073 "(check " descr ")"); \ 2074} \ 2075 \ 2076ATF_TC_BODY(test, tc) \ 2077{ \ 2078 \ 2079 tracee_sees_its_original_parent(type); \ 2080} 2081 2082TRACEE_SEES_ITS_ORIGINAL_PARENT( 2083 tracee_sees_its_original_parent_getppid, 2084 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2085 "getppid(2)"); 2086TRACEE_SEES_ITS_ORIGINAL_PARENT( 2087 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 2088 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2089 "sysctl(3) and kinfo_proc2"); 2090TRACEE_SEES_ITS_ORIGINAL_PARENT( 2091 tracee_sees_its_original_parent_procfs_status, 2092 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 2093 "the status file in procfs"); 2094#endif 2095 2096/// ---------------------------------------------------------------------------- 2097 2098static void 2099eventmask_preserved(int event) 2100{ 2101 const int exitval = 5; 2102 const int sigval = SIGSTOP; 2103 pid_t child, wpid; 2104#if defined(TWAIT_HAVE_STATUS) 2105 int status; 2106#endif 2107 ptrace_event_t set_event, get_event; 2108 const int len = sizeof(ptrace_event_t); 2109 2110 DPRINTF("Before forking process PID=%d\n", getpid()); 2111 SYSCALL_REQUIRE((child = fork()) != -1); 2112 if (child == 0) { 2113 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2114 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2115 2116 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2117 FORKEE_ASSERT(raise(sigval) == 0); 2118 2119 DPRINTF("Before exiting of the child process\n"); 2120 _exit(exitval); 2121 } 2122 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2123 2124 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2125 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2126 2127 validate_status_stopped(status, sigval); 2128 2129 set_event.pe_set_event = event; 2130 SYSCALL_REQUIRE( 2131 ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 2132 SYSCALL_REQUIRE( 2133 ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 2134 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 2135 2136 DPRINTF("Before resuming the child process where it left off and " 2137 "without signal to be sent\n"); 2138 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2139 2140 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2141 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2142 2143 validate_status_exited(status, exitval); 2144 2145 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2146 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2147} 2148 2149#define EVENTMASK_PRESERVED(test, event) \ 2150ATF_TC(test); \ 2151ATF_TC_HEAD(test, tc) \ 2152{ \ 2153 atf_tc_set_md_var(tc, "descr", \ 2154 "Verify that eventmask " #event " is preserved"); \ 2155} \ 2156 \ 2157ATF_TC_BODY(test, tc) \ 2158{ \ 2159 \ 2160 eventmask_preserved(event); \ 2161} 2162 2163EVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 2164EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 2165EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 2166EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 2167EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 2168EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 2169 2170/// ---------------------------------------------------------------------------- 2171 2172static void 2173fork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork, 2174 bool trackvforkdone, bool detachchild, bool detachparent) 2175{ 2176 const int exitval = 5; 2177 const int exitval2 = 15; 2178 const int sigval = SIGSTOP; 2179 pid_t child, child2 = 0, wpid; 2180#if defined(TWAIT_HAVE_STATUS) 2181 int status; 2182#endif 2183 ptrace_state_t state; 2184 const int slen = sizeof(state); 2185 ptrace_event_t event; 2186 const int elen = sizeof(event); 2187 2188 DPRINTF("Before forking process PID=%d\n", getpid()); 2189 SYSCALL_REQUIRE((child = fork()) != -1); 2190 if (child == 0) { 2191 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2192 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2193 2194 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2195 FORKEE_ASSERT(raise(sigval) == 0); 2196 2197 FORKEE_ASSERT((child2 = (fn)()) != -1); 2198 2199 if (child2 == 0) 2200 _exit(exitval2); 2201 2202 FORKEE_REQUIRE_SUCCESS 2203 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 2204 2205 forkee_status_exited(status, exitval2); 2206 2207 DPRINTF("Before exiting of the child process\n"); 2208 _exit(exitval); 2209 } 2210 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2211 2212 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2213 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2214 2215 validate_status_stopped(status, sigval); 2216 2217 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 2218 trackfork ? "|PTRACE_FORK" : "", 2219 trackvfork ? "|PTRACE_VFORK" : "", 2220 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 2221 event.pe_set_event = 0; 2222 if (trackfork) 2223 event.pe_set_event |= PTRACE_FORK; 2224 if (trackvfork) 2225 event.pe_set_event |= PTRACE_VFORK; 2226 if (trackvforkdone) 2227 event.pe_set_event |= PTRACE_VFORK_DONE; 2228 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 2229 2230 DPRINTF("Before resuming the child process where it left off and " 2231 "without signal to be sent\n"); 2232 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2233 2234#if defined(TWAIT_HAVE_PID) 2235 if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 2236 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 2237 child); 2238 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2239 child); 2240 2241 validate_status_stopped(status, SIGTRAP); 2242 2243 SYSCALL_REQUIRE( 2244 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2245 if (trackfork && fn == fork) { 2246 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 2247 PTRACE_FORK); 2248 } 2249 if (trackvfork && fn == vfork) { 2250 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 2251 PTRACE_VFORK); 2252 } 2253 2254 child2 = state.pe_other_pid; 2255 DPRINTF("Reported ptrace event with forkee %d\n", child2); 2256 2257 DPRINTF("Before calling %s() for the forkee %d of the child " 2258 "%d\n", TWAIT_FNAME, child2, child); 2259 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 2260 child2); 2261 2262 validate_status_stopped(status, SIGTRAP); 2263 2264 SYSCALL_REQUIRE( 2265 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 2266 if (trackfork && fn == fork) { 2267 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 2268 PTRACE_FORK); 2269 } 2270 if (trackvfork && fn == vfork) { 2271 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 2272 PTRACE_VFORK); 2273 } 2274 2275 ATF_REQUIRE_EQ(state.pe_other_pid, child); 2276 2277 DPRINTF("Before resuming the forkee process where it left off " 2278 "and without signal to be sent\n"); 2279 SYSCALL_REQUIRE( 2280 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 2281 2282 DPRINTF("Before resuming the child process where it left off " 2283 "and without signal to be sent\n"); 2284 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2285 } 2286#endif 2287 2288 if (trackvforkdone && fn == vfork) { 2289 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 2290 child); 2291 TWAIT_REQUIRE_SUCCESS( 2292 wpid = TWAIT_GENERIC(child, &status, 0), child); 2293 2294 validate_status_stopped(status, SIGTRAP); 2295 2296 SYSCALL_REQUIRE( 2297 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2298 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 2299 2300 child2 = state.pe_other_pid; 2301 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 2302 child2); 2303 2304 DPRINTF("Before resuming the child process where it left off " 2305 "and without signal to be sent\n"); 2306 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2307 } 2308 2309#if defined(TWAIT_HAVE_PID) 2310 if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 2311 DPRINTF("Before calling %s() for the forkee - expected exited" 2312 "\n", TWAIT_FNAME); 2313 TWAIT_REQUIRE_SUCCESS( 2314 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 2315 2316 validate_status_exited(status, exitval2); 2317 2318 DPRINTF("Before calling %s() for the forkee - expected no " 2319 "process\n", TWAIT_FNAME); 2320 TWAIT_REQUIRE_FAILURE(ECHILD, 2321 wpid = TWAIT_GENERIC(child2, &status, 0)); 2322 } 2323#endif 2324 2325 DPRINTF("Before calling %s() for the child - expected stopped " 2326 "SIGCHLD\n", TWAIT_FNAME); 2327 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2328 2329 validate_status_stopped(status, SIGCHLD); 2330 2331 DPRINTF("Before resuming the child process where it left off and " 2332 "without signal to be sent\n"); 2333 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2334 2335 DPRINTF("Before calling %s() for the child - expected exited\n", 2336 TWAIT_FNAME); 2337 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2338 2339 validate_status_exited(status, exitval); 2340 2341 DPRINTF("Before calling %s() for the child - expected no process\n", 2342 TWAIT_FNAME); 2343 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2344} 2345 2346#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \ 2347ATF_TC(name); \ 2348ATF_TC_HEAD(name, tc) \ 2349{ \ 2350 atf_tc_set_md_var(tc, "descr", descr); \ 2351} \ 2352 \ 2353ATF_TC_BODY(name, tc) \ 2354{ \ 2355 \ 2356 fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent); \ 2357} 2358 2359#define F false 2360#define T true 2361 2362#define F_IF__0(x) 2363#define F_IF__1(x) x 2364#define F_IF__(x,y) F_IF__ ## x (y) 2365#define F_IF_(x,y) F_IF__(x,y) 2366#define F_IF(x,y) F_IF_(x,y) 2367 2368#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \ 2369 "Verify " #function "(2) called with 0" \ 2370 F_IF(forkbit,"|PTRACE_FORK") \ 2371 F_IF(vforkbit,"|PTRACE_VFORK") \ 2372 F_IF(vforkdonebit,"|PTRACE_VFORK_DONE") \ 2373 " in EVENT_MASK." \ 2374 F_IF(dchildbit," Detach child in this test.") \ 2375 F_IF(dparentbit," Detach parent in this test.") 2376 2377FORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F) 2378#if defined(TWAIT_HAVE_PID) 2379FORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F) 2380FORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F) 2381FORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F) 2382#endif 2383FORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F) 2384#if defined(TWAIT_HAVE_PID) 2385FORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F) 2386FORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F) 2387FORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F) 2388#endif 2389 2390FORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F) 2391#if defined(TWAIT_HAVE_PID) 2392FORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F) 2393FORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F) 2394FORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F) 2395#endif 2396FORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F) 2397#if defined(TWAIT_HAVE_PID) 2398FORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F) 2399FORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F) 2400FORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F) 2401#endif 2402 2403/// ---------------------------------------------------------------------------- 2404 2405enum bytes_transfer_type { 2406 BYTES_TRANSFER_DATA, 2407 BYTES_TRANSFER_DATAIO, 2408 BYTES_TRANSFER_TEXT, 2409 BYTES_TRANSFER_TEXTIO, 2410 BYTES_TRANSFER_AUXV 2411}; 2412 2413static int __used 2414bytes_transfer_dummy(int a, int b, int c, int d) 2415{ 2416 int e, f, g, h; 2417 2418 a *= 4; 2419 b += 3; 2420 c -= 2; 2421 d /= 1; 2422 2423 e = strtol("10", NULL, 10); 2424 f = strtol("20", NULL, 10); 2425 g = strtol("30", NULL, 10); 2426 h = strtol("40", NULL, 10); 2427 2428 return (a + b * c - d) + (e * f - g / h); 2429} 2430 2431static void 2432bytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 2433{ 2434 const int exitval = 5; 2435 const int sigval = SIGSTOP; 2436 pid_t child, wpid; 2437 bool skip = false; 2438 2439 int lookup_me = 0; 2440 uint8_t lookup_me8 = 0; 2441 uint16_t lookup_me16 = 0; 2442 uint32_t lookup_me32 = 0; 2443 uint64_t lookup_me64 = 0; 2444 2445 int magic = 0x13579246; 2446 uint8_t magic8 = 0xab; 2447 uint16_t magic16 = 0x1234; 2448 uint32_t magic32 = 0x98765432; 2449 uint64_t magic64 = 0xabcdef0123456789; 2450 2451 struct ptrace_io_desc io; 2452#if defined(TWAIT_HAVE_STATUS) 2453 int status; 2454#endif 2455 /* 513 is just enough, for the purposes of ATF it's good enough */ 2456 AuxInfo ai[513], *aip; 2457 2458 ATF_REQUIRE(size < sizeof(ai)); 2459 2460 /* Prepare variables for .TEXT transfers */ 2461 switch (type) { 2462 case BYTES_TRANSFER_TEXT: 2463 memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 2464 break; 2465 case BYTES_TRANSFER_TEXTIO: 2466 switch (size) { 2467 case 8: 2468 memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 2469 break; 2470 case 16: 2471 memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 2472 break; 2473 case 32: 2474 memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 2475 break; 2476 case 64: 2477 memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 2478 break; 2479 } 2480 break; 2481 default: 2482 break; 2483 } 2484 2485 /* Prepare variables for PIOD and AUXV transfers */ 2486 switch (type) { 2487 case BYTES_TRANSFER_TEXTIO: 2488 case BYTES_TRANSFER_DATAIO: 2489 io.piod_op = operation; 2490 switch (size) { 2491 case 8: 2492 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2493 (void *)bytes_transfer_dummy : 2494 &lookup_me8; 2495 io.piod_addr = &lookup_me8; 2496 io.piod_len = sizeof(lookup_me8); 2497 break; 2498 case 16: 2499 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2500 (void *)bytes_transfer_dummy : 2501 &lookup_me16; 2502 io.piod_addr = &lookup_me16; 2503 io.piod_len = sizeof(lookup_me16); 2504 break; 2505 case 32: 2506 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2507 (void *)bytes_transfer_dummy : 2508 &lookup_me32; 2509 io.piod_addr = &lookup_me32; 2510 io.piod_len = sizeof(lookup_me32); 2511 break; 2512 case 64: 2513 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2514 (void *)bytes_transfer_dummy : 2515 &lookup_me64; 2516 io.piod_addr = &lookup_me64; 2517 io.piod_len = sizeof(lookup_me64); 2518 break; 2519 default: 2520 break; 2521 } 2522 break; 2523 case BYTES_TRANSFER_AUXV: 2524 io.piod_op = operation; 2525 io.piod_offs = 0; 2526 io.piod_addr = ai; 2527 io.piod_len = size; 2528 break; 2529 default: 2530 break; 2531 } 2532 2533 DPRINTF("Before forking process PID=%d\n", getpid()); 2534 SYSCALL_REQUIRE((child = fork()) != -1); 2535 if (child == 0) { 2536 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2537 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2538 2539 switch (type) { 2540 case BYTES_TRANSFER_DATA: 2541 switch (operation) { 2542 case PT_READ_D: 2543 case PT_READ_I: 2544 lookup_me = magic; 2545 break; 2546 default: 2547 break; 2548 } 2549 break; 2550 case BYTES_TRANSFER_DATAIO: 2551 switch (operation) { 2552 case PIOD_READ_D: 2553 case PIOD_READ_I: 2554 switch (size) { 2555 case 8: 2556 lookup_me8 = magic8; 2557 break; 2558 case 16: 2559 lookup_me16 = magic16; 2560 break; 2561 case 32: 2562 lookup_me32 = magic32; 2563 break; 2564 case 64: 2565 lookup_me64 = magic64; 2566 break; 2567 default: 2568 break; 2569 } 2570 break; 2571 default: 2572 break; 2573 } 2574 default: 2575 break; 2576 } 2577 2578 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2579 FORKEE_ASSERT(raise(sigval) == 0); 2580 2581 /* Handle PIOD and PT separately as operation values overlap */ 2582 switch (type) { 2583 case BYTES_TRANSFER_DATA: 2584 switch (operation) { 2585 case PT_WRITE_D: 2586 case PT_WRITE_I: 2587 FORKEE_ASSERT_EQ(lookup_me, magic); 2588 break; 2589 default: 2590 break; 2591 } 2592 break; 2593 case BYTES_TRANSFER_DATAIO: 2594 switch (operation) { 2595 case PIOD_WRITE_D: 2596 case PIOD_WRITE_I: 2597 switch (size) { 2598 case 8: 2599 FORKEE_ASSERT_EQ(lookup_me8, magic8); 2600 break; 2601 case 16: 2602 FORKEE_ASSERT_EQ(lookup_me16, magic16); 2603 break; 2604 case 32: 2605 FORKEE_ASSERT_EQ(lookup_me32, magic32); 2606 break; 2607 case 64: 2608 FORKEE_ASSERT_EQ(lookup_me64, magic64); 2609 break; 2610 default: 2611 break; 2612 } 2613 break; 2614 default: 2615 break; 2616 } 2617 break; 2618 case BYTES_TRANSFER_TEXT: 2619 FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 2620 sizeof(magic)) == 0); 2621 break; 2622 case BYTES_TRANSFER_TEXTIO: 2623 switch (size) { 2624 case 8: 2625 FORKEE_ASSERT(memcmp(&magic8, 2626 bytes_transfer_dummy, 2627 sizeof(magic8)) == 0); 2628 break; 2629 case 16: 2630 FORKEE_ASSERT(memcmp(&magic16, 2631 bytes_transfer_dummy, 2632 sizeof(magic16)) == 0); 2633 break; 2634 case 32: 2635 FORKEE_ASSERT(memcmp(&magic32, 2636 bytes_transfer_dummy, 2637 sizeof(magic32)) == 0); 2638 break; 2639 case 64: 2640 FORKEE_ASSERT(memcmp(&magic64, 2641 bytes_transfer_dummy, 2642 sizeof(magic64)) == 0); 2643 break; 2644 } 2645 break; 2646 default: 2647 break; 2648 } 2649 2650 DPRINTF("Before exiting of the child process\n"); 2651 _exit(exitval); 2652 } 2653 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2654 2655 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2656 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2657 2658 validate_status_stopped(status, sigval); 2659 2660 /* Check PaX MPROTECT */ 2661 if (!can_we_write_to_text(child)) { 2662 switch (type) { 2663 case BYTES_TRANSFER_TEXTIO: 2664 switch (operation) { 2665 case PIOD_WRITE_D: 2666 case PIOD_WRITE_I: 2667 skip = true; 2668 break; 2669 default: 2670 break; 2671 } 2672 break; 2673 case BYTES_TRANSFER_TEXT: 2674 switch (operation) { 2675 case PT_WRITE_D: 2676 case PT_WRITE_I: 2677 skip = true; 2678 break; 2679 default: 2680 break; 2681 } 2682 break; 2683 default: 2684 break; 2685 } 2686 } 2687 2688 /* Bailout cleanly killing the child process */ 2689 if (skip) { 2690 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 2691 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2692 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2693 child); 2694 2695 validate_status_signaled(status, SIGKILL, 0); 2696 2697 atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 2698 } 2699 2700 DPRINTF("Calling operation to transfer bytes between child=%d and " 2701 "parent=%d\n", child, getpid()); 2702 2703 switch (type) { 2704 case BYTES_TRANSFER_TEXTIO: 2705 case BYTES_TRANSFER_DATAIO: 2706 case BYTES_TRANSFER_AUXV: 2707 switch (operation) { 2708 case PIOD_WRITE_D: 2709 case PIOD_WRITE_I: 2710 switch (size) { 2711 case 8: 2712 lookup_me8 = magic8; 2713 break; 2714 case 16: 2715 lookup_me16 = magic16; 2716 break; 2717 case 32: 2718 lookup_me32 = magic32; 2719 break; 2720 case 64: 2721 lookup_me64 = magic64; 2722 break; 2723 default: 2724 break; 2725 } 2726 break; 2727 default: 2728 break; 2729 } 2730 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 2731 switch (operation) { 2732 case PIOD_READ_D: 2733 case PIOD_READ_I: 2734 switch (size) { 2735 case 8: 2736 ATF_REQUIRE_EQ(lookup_me8, magic8); 2737 break; 2738 case 16: 2739 ATF_REQUIRE_EQ(lookup_me16, magic16); 2740 break; 2741 case 32: 2742 ATF_REQUIRE_EQ(lookup_me32, magic32); 2743 break; 2744 case 64: 2745 ATF_REQUIRE_EQ(lookup_me64, magic64); 2746 break; 2747 default: 2748 break; 2749 } 2750 break; 2751 case PIOD_READ_AUXV: 2752 DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 2753 io.piod_len); 2754 ATF_REQUIRE(io.piod_len > 0); 2755 for (aip = ai; aip->a_type != AT_NULL; aip++) 2756 DPRINTF("a_type=%#llx a_v=%#llx\n", 2757 (long long int)aip->a_type, 2758 (long long int)aip->a_v); 2759 break; 2760 default: 2761 break; 2762 } 2763 break; 2764 case BYTES_TRANSFER_TEXT: 2765 switch (operation) { 2766 case PT_READ_D: 2767 case PT_READ_I: 2768 errno = 0; 2769 lookup_me = ptrace(operation, child, 2770 bytes_transfer_dummy, 0); 2771 ATF_REQUIRE_EQ(lookup_me, magic); 2772 SYSCALL_REQUIRE_ERRNO(errno, 0); 2773 break; 2774 case PT_WRITE_D: 2775 case PT_WRITE_I: 2776 SYSCALL_REQUIRE(ptrace(operation, child, 2777 bytes_transfer_dummy, magic) 2778 != -1); 2779 break; 2780 default: 2781 break; 2782 } 2783 break; 2784 case BYTES_TRANSFER_DATA: 2785 switch (operation) { 2786 case PT_READ_D: 2787 case PT_READ_I: 2788 errno = 0; 2789 lookup_me = ptrace(operation, child, &lookup_me, 0); 2790 ATF_REQUIRE_EQ(lookup_me, magic); 2791 SYSCALL_REQUIRE_ERRNO(errno, 0); 2792 break; 2793 case PT_WRITE_D: 2794 case PT_WRITE_I: 2795 lookup_me = magic; 2796 SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 2797 magic) != -1); 2798 break; 2799 default: 2800 break; 2801 } 2802 break; 2803 default: 2804 break; 2805 } 2806 2807 DPRINTF("Before resuming the child process where it left off and " 2808 "without signal to be sent\n"); 2809 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2810 2811 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2812 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2813 2814 validate_status_exited(status, exitval); 2815 2816 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2817 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2818} 2819 2820#define BYTES_TRANSFER(test, operation, size, type) \ 2821ATF_TC(test); \ 2822ATF_TC_HEAD(test, tc) \ 2823{ \ 2824 atf_tc_set_md_var(tc, "descr", \ 2825 "Verify bytes transfer operation" #operation " and size " #size \ 2826 " of type " #type); \ 2827} \ 2828 \ 2829ATF_TC_BODY(test, tc) \ 2830{ \ 2831 \ 2832 bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 2833} 2834 2835// DATA 2836 2837BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 2838BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 2839BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 2840BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 2841 2842BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 2843BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 2844BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 2845BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 2846 2847BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 2848BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 2849BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 2850BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 2851 2852BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 2853BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 2854BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 2855BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 2856 2857BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 2858BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 2859BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 2860BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 2861 2862// TEXT 2863 2864BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 2865BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 2866BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 2867BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 2868 2869BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 2870BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 2871BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 2872BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 2873 2874BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 2875BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 2876BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 2877BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 2878 2879BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 2880BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 2881BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 2882BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 2883 2884BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 2885BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 2886BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 2887BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 2888 2889// AUXV 2890 2891BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 2892 2893/// ---------------------------------------------------------------------------- 2894 2895#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 2896static void 2897access_regs(const char *regset, const char *aux) 2898{ 2899 const int exitval = 5; 2900 const int sigval = SIGSTOP; 2901 pid_t child, wpid; 2902#if defined(TWAIT_HAVE_STATUS) 2903 int status; 2904#endif 2905#if defined(HAVE_GPREGS) 2906 struct reg gpr; 2907 register_t rgstr; 2908#endif 2909#if defined(HAVE_FPREGS) 2910 struct fpreg fpr; 2911#endif 2912 2913#if !defined(HAVE_GPREGS) 2914 if (strcmp(regset, "regs") == 0) 2915 atf_tc_fail("Impossible test scenario!"); 2916#endif 2917 2918#if !defined(HAVE_FPREGS) 2919 if (strcmp(regset, "fpregs") == 0) 2920 atf_tc_fail("Impossible test scenario!"); 2921#endif 2922 2923 DPRINTF("Before forking process PID=%d\n", getpid()); 2924 SYSCALL_REQUIRE((child = fork()) != -1); 2925 if (child == 0) { 2926 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2927 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2928 2929 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2930 FORKEE_ASSERT(raise(sigval) == 0); 2931 2932 DPRINTF("Before exiting of the child process\n"); 2933 _exit(exitval); 2934 } 2935 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2936 2937 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2938 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2939 2940 validate_status_stopped(status, sigval); 2941 2942#if defined(HAVE_GPREGS) 2943 if (strcmp(regset, "regs") == 0) { 2944 DPRINTF("Call GETREGS for the child process\n"); 2945 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 2946 2947 if (strcmp(aux, "none") == 0) { 2948 DPRINTF("Retrieved registers\n"); 2949 } else if (strcmp(aux, "pc") == 0) { 2950 rgstr = PTRACE_REG_PC(&gpr); 2951 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 2952 } else if (strcmp(aux, "set_pc") == 0) { 2953 rgstr = PTRACE_REG_PC(&gpr); 2954 PTRACE_REG_SET_PC(&gpr, rgstr); 2955 } else if (strcmp(aux, "sp") == 0) { 2956 rgstr = PTRACE_REG_SP(&gpr); 2957 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 2958 } else if (strcmp(aux, "intrv") == 0) { 2959 rgstr = PTRACE_REG_INTRV(&gpr); 2960 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 2961 } else if (strcmp(aux, "setregs") == 0) { 2962 DPRINTF("Call SETREGS for the child process\n"); 2963 SYSCALL_REQUIRE( 2964 ptrace(PT_GETREGS, child, &gpr, 0) != -1); 2965 } 2966 } 2967#endif 2968 2969#if defined(HAVE_FPREGS) 2970 if (strcmp(regset, "fpregs") == 0) { 2971 DPRINTF("Call GETFPREGS for the child process\n"); 2972 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 2973 2974 if (strcmp(aux, "getfpregs") == 0) { 2975 DPRINTF("Retrieved FP registers\n"); 2976 } else if (strcmp(aux, "setfpregs") == 0) { 2977 DPRINTF("Call SETFPREGS for the child\n"); 2978 SYSCALL_REQUIRE( 2979 ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 2980 } 2981 } 2982#endif 2983 2984 DPRINTF("Before resuming the child process where it left off and " 2985 "without signal to be sent\n"); 2986 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2987 2988 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2989 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2990 2991 validate_status_exited(status, exitval); 2992 2993 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2994 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2995} 2996 2997#define ACCESS_REGS(test, regset, aux) \ 2998ATF_TC(test); \ 2999ATF_TC_HEAD(test, tc) \ 3000{ \ 3001 atf_tc_set_md_var(tc, "descr", \ 3002 "Verify " regset " with auxiliary operation: " aux); \ 3003} \ 3004 \ 3005ATF_TC_BODY(test, tc) \ 3006{ \ 3007 \ 3008 access_regs(regset, aux); \ 3009} 3010#endif 3011 3012#if defined(HAVE_GPREGS) 3013ACCESS_REGS(access_regs1, "regs", "none") 3014ACCESS_REGS(access_regs2, "regs", "pc") 3015ACCESS_REGS(access_regs3, "regs", "set_pc") 3016ACCESS_REGS(access_regs4, "regs", "sp") 3017ACCESS_REGS(access_regs5, "regs", "intrv") 3018ACCESS_REGS(access_regs6, "regs", "setregs") 3019#endif 3020#if defined(HAVE_FPREGS) 3021ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 3022ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 3023#endif 3024 3025/// ---------------------------------------------------------------------------- 3026 3027#if defined(PT_STEP) 3028static void 3029ptrace_step(int N, int setstep) 3030{ 3031 const int exitval = 5; 3032 const int sigval = SIGSTOP; 3033 pid_t child, wpid; 3034#if defined(TWAIT_HAVE_STATUS) 3035 int status; 3036#endif 3037 int happy; 3038 struct ptrace_siginfo info; 3039 3040#if defined(__arm__) 3041 /* PT_STEP not supported on arm 32-bit */ 3042 atf_tc_expect_fail("PR kern/52119"); 3043#endif 3044 3045 DPRINTF("Before forking process PID=%d\n", getpid()); 3046 SYSCALL_REQUIRE((child = fork()) != -1); 3047 if (child == 0) { 3048 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3049 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3050 3051 happy = check_happy(999); 3052 3053 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3054 FORKEE_ASSERT(raise(sigval) == 0); 3055 3056 FORKEE_ASSERT_EQ(happy, check_happy(999)); 3057 3058 DPRINTF("Before exiting of the child process\n"); 3059 _exit(exitval); 3060 } 3061 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3062 3063 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3064 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3065 3066 validate_status_stopped(status, sigval); 3067 3068 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3069 SYSCALL_REQUIRE( 3070 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3071 3072 DPRINTF("Before checking siginfo_t\n"); 3073 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3074 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3075 3076 while (N --> 0) { 3077 if (setstep) { 3078 DPRINTF("Before resuming the child process where it " 3079 "left off and without signal to be sent (use " 3080 "PT_SETSTEP and PT_CONTINUE)\n"); 3081 SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 3082 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 3083 != -1); 3084 } else { 3085 DPRINTF("Before resuming the child process where it " 3086 "left off and without signal to be sent (use " 3087 "PT_STEP)\n"); 3088 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 3089 != -1); 3090 } 3091 3092 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3093 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3094 child); 3095 3096 validate_status_stopped(status, SIGTRAP); 3097 3098 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3099 SYSCALL_REQUIRE( 3100 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3101 3102 DPRINTF("Before checking siginfo_t\n"); 3103 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 3104 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 3105 3106 if (setstep) { 3107 SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 3108 } 3109 } 3110 3111 DPRINTF("Before resuming the child process where it left off and " 3112 "without signal to be sent\n"); 3113 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3114 3115 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3116 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3117 3118 validate_status_exited(status, exitval); 3119 3120 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3121 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3122} 3123 3124#define PTRACE_STEP(test, N, setstep) \ 3125ATF_TC(test); \ 3126ATF_TC_HEAD(test, tc) \ 3127{ \ 3128 atf_tc_set_md_var(tc, "descr", \ 3129 "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 3130} \ 3131 \ 3132ATF_TC_BODY(test, tc) \ 3133{ \ 3134 \ 3135 ptrace_step(N, setstep); \ 3136} 3137 3138PTRACE_STEP(step1, 1, 0) 3139PTRACE_STEP(step2, 2, 0) 3140PTRACE_STEP(step3, 3, 0) 3141PTRACE_STEP(step4, 4, 0) 3142PTRACE_STEP(setstep1, 1, 1) 3143PTRACE_STEP(setstep2, 2, 1) 3144PTRACE_STEP(setstep3, 3, 1) 3145PTRACE_STEP(setstep4, 4, 1) 3146#endif 3147 3148/// ---------------------------------------------------------------------------- 3149 3150static void 3151ptrace_kill(const char *type) 3152{ 3153 const int sigval = SIGSTOP; 3154 pid_t child, wpid; 3155#if defined(TWAIT_HAVE_STATUS) 3156 int status; 3157#endif 3158 3159 DPRINTF("Before forking process PID=%d\n", getpid()); 3160 SYSCALL_REQUIRE((child = fork()) != -1); 3161 if (child == 0) { 3162 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3163 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3164 3165 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3166 FORKEE_ASSERT(raise(sigval) == 0); 3167 3168 /* NOTREACHED */ 3169 FORKEE_ASSERTX(0 && 3170 "Child should be terminated by a signal from its parent"); 3171 } 3172 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3173 3174 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3175 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3176 3177 validate_status_stopped(status, sigval); 3178 3179 DPRINTF("Before killing the child process with %s\n", type); 3180 if (strcmp(type, "ptrace(PT_KILL)") == 0) { 3181 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 3182 } else if (strcmp(type, "kill(SIGKILL)") == 0) { 3183 kill(child, SIGKILL); 3184 } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 3185 setpgid(child, 0); 3186 killpg(getpgid(child), SIGKILL); 3187 } 3188 3189 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3190 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3191 3192 validate_status_signaled(status, SIGKILL, 0); 3193 3194 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3195 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3196} 3197 3198#define PTRACE_KILL(test, type) \ 3199ATF_TC(test); \ 3200ATF_TC_HEAD(test, tc) \ 3201{ \ 3202 atf_tc_set_md_var(tc, "descr", \ 3203 "Verify killing the child with " type); \ 3204} \ 3205 \ 3206ATF_TC_BODY(test, tc) \ 3207{ \ 3208 \ 3209 ptrace_kill(type); \ 3210} 3211 3212// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 3213PTRACE_KILL(kill1, "ptrace(PT_KILL)") 3214PTRACE_KILL(kill2, "kill(SIGKILL)") 3215PTRACE_KILL(kill3, "killpg(SIGKILL)") 3216 3217/// ---------------------------------------------------------------------------- 3218 3219static void 3220traceme_lwpinfo(const int threads) 3221{ 3222 const int sigval = SIGSTOP; 3223 const int sigval2 = SIGINT; 3224 pid_t child, wpid; 3225#if defined(TWAIT_HAVE_STATUS) 3226 int status; 3227#endif 3228 struct ptrace_lwpinfo lwp = {0, 0}; 3229 struct ptrace_siginfo info; 3230 3231 /* Maximum number of supported threads in this test */ 3232 pthread_t t[3]; 3233 int n, rv; 3234 3235 ATF_REQUIRE((int)__arraycount(t) >= threads); 3236 3237 DPRINTF("Before forking process PID=%d\n", getpid()); 3238 SYSCALL_REQUIRE((child = fork()) != -1); 3239 if (child == 0) { 3240 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3241 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3242 3243 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3244 FORKEE_ASSERT(raise(sigval) == 0); 3245 3246 for (n = 0; n < threads; n++) { 3247 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 3248 FORKEE_ASSERT(rv == 0); 3249 } 3250 3251 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 3252 FORKEE_ASSERT(raise(sigval2) == 0); 3253 3254 /* NOTREACHED */ 3255 FORKEE_ASSERTX(0 && "Not reached"); 3256 } 3257 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3258 3259 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3260 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3261 3262 validate_status_stopped(status, sigval); 3263 3264 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 3265 SYSCALL_REQUIRE( 3266 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3267 3268 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3269 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3270 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3271 info.psi_siginfo.si_errno); 3272 3273 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3274 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3275 3276 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3277 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3278 3279 DPRINTF("Assert that there exists a single thread only\n"); 3280 ATF_REQUIRE(lwp.pl_lwpid > 0); 3281 3282 DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 3283 lwp.pl_lwpid); 3284 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 3285 3286 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3287 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3288 3289 DPRINTF("Assert that there exists a single thread only\n"); 3290 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 3291 3292 DPRINTF("Before resuming the child process where it left off and " 3293 "without signal to be sent\n"); 3294 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3295 3296 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3297 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3298 3299 validate_status_stopped(status, sigval2); 3300 3301 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 3302 SYSCALL_REQUIRE( 3303 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3304 3305 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3306 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3307 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3308 info.psi_siginfo.si_errno); 3309 3310 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 3311 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3312 3313 memset(&lwp, 0, sizeof(lwp)); 3314 3315 for (n = 0; n <= threads; n++) { 3316 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3317 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3318 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3319 3320 DPRINTF("Assert that the thread exists\n"); 3321 ATF_REQUIRE(lwp.pl_lwpid > 0); 3322 3323 DPRINTF("Assert that lwp thread %d received expected event\n", 3324 lwp.pl_lwpid); 3325 FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ? 3326 PL_EVENT_SIGNAL : PL_EVENT_NONE); 3327 } 3328 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3329 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3330 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3331 3332 DPRINTF("Assert that there are no more threads\n"); 3333 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 3334 3335 DPRINTF("Before resuming the child process where it left off and " 3336 "without signal to be sent\n"); 3337 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 3338 3339 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3341 3342 validate_status_signaled(status, SIGKILL, 0); 3343 3344 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3345 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3346} 3347 3348#define TRACEME_LWPINFO(test, threads) \ 3349ATF_TC(test); \ 3350ATF_TC_HEAD(test, tc) \ 3351{ \ 3352 atf_tc_set_md_var(tc, "descr", \ 3353 "Verify LWPINFO with the child with " #threads \ 3354 " spawned extra threads"); \ 3355} \ 3356 \ 3357ATF_TC_BODY(test, tc) \ 3358{ \ 3359 \ 3360 traceme_lwpinfo(threads); \ 3361} 3362 3363TRACEME_LWPINFO(traceme_lwpinfo0, 0) 3364TRACEME_LWPINFO(traceme_lwpinfo1, 1) 3365TRACEME_LWPINFO(traceme_lwpinfo2, 2) 3366TRACEME_LWPINFO(traceme_lwpinfo3, 3) 3367 3368/// ---------------------------------------------------------------------------- 3369 3370#if defined(TWAIT_HAVE_PID) 3371static void 3372attach_lwpinfo(const int threads) 3373{ 3374 const int sigval = SIGINT; 3375 struct msg_fds parent_tracee, parent_tracer; 3376 const int exitval_tracer = 10; 3377 pid_t tracee, tracer, wpid; 3378 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 3379#if defined(TWAIT_HAVE_STATUS) 3380 int status; 3381#endif 3382 struct ptrace_lwpinfo lwp = {0, 0}; 3383 struct ptrace_siginfo info; 3384 3385 /* Maximum number of supported threads in this test */ 3386 pthread_t t[3]; 3387 int n, rv; 3388 3389 DPRINTF("Spawn tracee\n"); 3390 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 3391 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 3392 tracee = atf_utils_fork(); 3393 if (tracee == 0) { 3394 /* Wait for message from the parent */ 3395 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 3396 3397 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 3398 3399 for (n = 0; n < threads; n++) { 3400 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 3401 FORKEE_ASSERT(rv == 0); 3402 } 3403 3404 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 3405 3406 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3407 FORKEE_ASSERT(raise(sigval) == 0); 3408 3409 /* NOTREACHED */ 3410 FORKEE_ASSERTX(0 && "Not reached"); 3411 } 3412 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 3413 3414 DPRINTF("Spawn debugger\n"); 3415 tracer = atf_utils_fork(); 3416 if (tracer == 0) { 3417 /* No IPC to communicate with the child */ 3418 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 3419 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 3420 3421 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 3422 FORKEE_REQUIRE_SUCCESS( 3423 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3424 3425 forkee_status_stopped(status, SIGSTOP); 3426 3427 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3428 "tracee"); 3429 FORKEE_ASSERT( 3430 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3431 3432 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3433 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3434 "si_errno=%#x\n", 3435 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3436 info.psi_siginfo.si_errno); 3437 3438 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 3439 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 3440 3441 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3442 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3443 != -1); 3444 3445 DPRINTF("Assert that there exists a thread\n"); 3446 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 3447 3448 DPRINTF("Assert that lwp thread %d received event " 3449 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 3450 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 3451 3452 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3453 "tracee\n"); 3454 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3455 != -1); 3456 3457 DPRINTF("Assert that there are no more lwp threads in " 3458 "tracee\n"); 3459 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 3460 3461 /* Resume tracee with PT_CONTINUE */ 3462 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3463 3464 /* Inform parent that tracer has attached to tracee */ 3465 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 3466 3467 /* Wait for parent */ 3468 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 3469 3470 /* Wait for tracee and assert that it raised a signal */ 3471 FORKEE_REQUIRE_SUCCESS( 3472 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3473 3474 forkee_status_stopped(status, SIGINT); 3475 3476 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3477 "child"); 3478 FORKEE_ASSERT( 3479 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3480 3481 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3482 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3483 "si_errno=%#x\n", 3484 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3485 info.psi_siginfo.si_errno); 3486 3487 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 3488 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 3489 3490 memset(&lwp, 0, sizeof(lwp)); 3491 3492 for (n = 0; n <= threads; n++) { 3493 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3494 "child\n"); 3495 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 3496 sizeof(lwp)) != -1); 3497 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3498 3499 DPRINTF("Assert that the thread exists\n"); 3500 FORKEE_ASSERT(lwp.pl_lwpid > 0); 3501 3502 DPRINTF("Assert that lwp thread %d received expected " 3503 "event\n", lwp.pl_lwpid); 3504 FORKEE_ASSERT_EQ(lwp.pl_event, 3505 info.psi_lwpid == lwp.pl_lwpid ? 3506 PL_EVENT_SIGNAL : PL_EVENT_NONE); 3507 } 3508 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3509 "tracee\n"); 3510 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3511 != -1); 3512 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3513 3514 DPRINTF("Assert that there are no more threads\n"); 3515 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 3516 3517 DPRINTF("Before resuming the child process where it left off " 3518 "and without signal to be sent\n"); 3519 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 3520 != -1); 3521 3522 /* Wait for tracee and assert that it exited */ 3523 FORKEE_REQUIRE_SUCCESS( 3524 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3525 3526 forkee_status_signaled(status, SIGKILL, 0); 3527 3528 DPRINTF("Before exiting of the tracer process\n"); 3529 _exit(exitval_tracer); 3530 } 3531 3532 DPRINTF("Wait for the tracer to attach to the tracee\n"); 3533 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 3534 3535 DPRINTF("Resume the tracee and spawn threads\n"); 3536 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 3537 3538 DPRINTF("Resume the tracee and let it exit\n"); 3539 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 3540 3541 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 3542 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 3543 3544 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 3545 TWAIT_FNAME); 3546 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 3547 tracer); 3548 3549 validate_status_exited(status, exitval_tracer); 3550 3551 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 3552 TWAIT_FNAME); 3553 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 3554 tracee); 3555 3556 validate_status_signaled(status, SIGKILL, 0); 3557 3558 msg_close(&parent_tracer); 3559 msg_close(&parent_tracee); 3560} 3561 3562#define ATTACH_LWPINFO(test, threads) \ 3563ATF_TC(test); \ 3564ATF_TC_HEAD(test, tc) \ 3565{ \ 3566 atf_tc_set_md_var(tc, "descr", \ 3567 "Verify LWPINFO with the child with " #threads \ 3568 " spawned extra threads (tracer is not the original " \ 3569 "parent)"); \ 3570} \ 3571 \ 3572ATF_TC_BODY(test, tc) \ 3573{ \ 3574 \ 3575 attach_lwpinfo(threads); \ 3576} 3577 3578ATTACH_LWPINFO(attach_lwpinfo0, 0) 3579ATTACH_LWPINFO(attach_lwpinfo1, 1) 3580ATTACH_LWPINFO(attach_lwpinfo2, 2) 3581ATTACH_LWPINFO(attach_lwpinfo3, 3) 3582#endif 3583 3584/// ---------------------------------------------------------------------------- 3585 3586static void 3587ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 3588{ 3589 const int exitval = 5; 3590 const int sigval = SIGINT; 3591 const int sigfaked = SIGTRAP; 3592 const int sicodefaked = TRAP_BRKPT; 3593 pid_t child, wpid; 3594 struct sigaction sa; 3595#if defined(TWAIT_HAVE_STATUS) 3596 int status; 3597#endif 3598 struct ptrace_siginfo info; 3599 memset(&info, 0, sizeof(info)); 3600 3601 DPRINTF("Before forking process PID=%d\n", getpid()); 3602 SYSCALL_REQUIRE((child = fork()) != -1); 3603 if (child == 0) { 3604 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3605 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3606 3607 sa.sa_sigaction = sah; 3608 sa.sa_flags = SA_SIGINFO; 3609 sigemptyset(&sa.sa_mask); 3610 3611 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 3612 != -1); 3613 3614 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3615 FORKEE_ASSERT(raise(sigval) == 0); 3616 3617 FORKEE_ASSERT_EQ(*signal_caught, 1); 3618 3619 DPRINTF("Before exiting of the child process\n"); 3620 _exit(exitval); 3621 } 3622 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3623 3624 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3625 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3626 3627 validate_status_stopped(status, sigval); 3628 3629 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3630 SYSCALL_REQUIRE( 3631 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3632 3633 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3634 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3635 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3636 info.psi_siginfo.si_errno); 3637 3638 if (faked) { 3639 DPRINTF("Before setting new faked signal to signo=%d " 3640 "si_code=%d\n", sigfaked, sicodefaked); 3641 info.psi_siginfo.si_signo = sigfaked; 3642 info.psi_siginfo.si_code = sicodefaked; 3643 } 3644 3645 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 3646 SYSCALL_REQUIRE( 3647 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 3648 3649 if (faked) { 3650 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3651 "child\n"); 3652 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 3653 sizeof(info)) != -1); 3654 3655 DPRINTF("Before checking siginfo_t\n"); 3656 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 3657 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 3658 } 3659 3660 DPRINTF("Before resuming the child process where it left off and " 3661 "without signal to be sent\n"); 3662 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 3663 faked ? sigfaked : sigval) != -1); 3664 3665 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3666 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3667 3668 validate_status_exited(status, exitval); 3669 3670 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3671 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3672} 3673 3674#define PTRACE_SIGINFO(test, faked) \ 3675ATF_TC(test); \ 3676ATF_TC_HEAD(test, tc) \ 3677{ \ 3678 atf_tc_set_md_var(tc, "descr", \ 3679 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 3680 "with%s setting signal to new value", faked ? "" : "out"); \ 3681} \ 3682 \ 3683static int test##_caught = 0; \ 3684 \ 3685static void \ 3686test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 3687{ \ 3688 if (faked) { \ 3689 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 3690 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 3691 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 3692 } else { \ 3693 FORKEE_ASSERT_EQ(sig, SIGINT); \ 3694 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 3695 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 3696 } \ 3697 \ 3698 ++ test##_caught; \ 3699} \ 3700 \ 3701ATF_TC_BODY(test, tc) \ 3702{ \ 3703 \ 3704 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 3705} 3706 3707PTRACE_SIGINFO(siginfo_set_unmodified, false) 3708PTRACE_SIGINFO(siginfo_set_faked, true) 3709 3710/// ---------------------------------------------------------------------------- 3711 3712ATF_TC(traceme_exec); 3713ATF_TC_HEAD(traceme_exec, tc) 3714{ 3715 atf_tc_set_md_var(tc, "descr", 3716 "Detect SIGTRAP TRAP_EXEC from tracee"); 3717} 3718 3719ATF_TC_BODY(traceme_exec, tc) 3720{ 3721 const int sigval = SIGTRAP; 3722 pid_t child, wpid; 3723#if defined(TWAIT_HAVE_STATUS) 3724 int status; 3725#endif 3726 3727 struct ptrace_siginfo info; 3728 memset(&info, 0, sizeof(info)); 3729 3730 DPRINTF("Before forking process PID=%d\n", getpid()); 3731 SYSCALL_REQUIRE((child = fork()) != -1); 3732 if (child == 0) { 3733 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3734 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3735 3736 DPRINTF("Before calling execve(2) from child\n"); 3737 execlp("/bin/echo", "/bin/echo", NULL); 3738 3739 FORKEE_ASSERT(0 && "Not reached"); 3740 } 3741 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3742 3743 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3744 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3745 3746 validate_status_stopped(status, sigval); 3747 3748 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3749 SYSCALL_REQUIRE( 3750 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3751 3752 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3753 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3754 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3755 info.psi_siginfo.si_errno); 3756 3757 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3758 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 3759 3760 DPRINTF("Before resuming the child process where it left off and " 3761 "without signal to be sent\n"); 3762 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3763 3764 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3765 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3766 3767 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3768 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3769} 3770 3771/// ---------------------------------------------------------------------------- 3772 3773static volatile int done; 3774 3775static void * 3776trace_threads_cb(void *arg __unused) 3777{ 3778 3779 done++; 3780 3781 while (done < 3) 3782 continue; 3783 3784 return NULL; 3785} 3786 3787static void 3788trace_threads(bool trace_create, bool trace_exit) 3789{ 3790 const int sigval = SIGSTOP; 3791 pid_t child, wpid; 3792#if defined(TWAIT_HAVE_STATUS) 3793 int status; 3794#endif 3795 ptrace_state_t state; 3796 const int slen = sizeof(state); 3797 ptrace_event_t event; 3798 const int elen = sizeof(event); 3799 struct ptrace_siginfo info; 3800 3801 pthread_t t[3]; 3802 int rv; 3803 size_t n; 3804 lwpid_t lid; 3805 3806 /* Track created and exited threads */ 3807 bool traced_lwps[__arraycount(t)]; 3808 3809 atf_tc_skip("PR kern/51995"); 3810 3811 DPRINTF("Before forking process PID=%d\n", getpid()); 3812 SYSCALL_REQUIRE((child = fork()) != -1); 3813 if (child == 0) { 3814 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3815 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3816 3817 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3818 FORKEE_ASSERT(raise(sigval) == 0); 3819 3820 for (n = 0; n < __arraycount(t); n++) { 3821 rv = pthread_create(&t[n], NULL, trace_threads_cb, 3822 NULL); 3823 FORKEE_ASSERT(rv == 0); 3824 } 3825 3826 for (n = 0; n < __arraycount(t); n++) { 3827 rv = pthread_join(t[n], NULL); 3828 FORKEE_ASSERT(rv == 0); 3829 } 3830 3831 /* 3832 * There is race between _exit() and pthread_join() detaching 3833 * a thread. For simplicity kill the process after detecting 3834 * LWP events. 3835 */ 3836 while (true) 3837 continue; 3838 3839 FORKEE_ASSERT(0 && "Not reached"); 3840 } 3841 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3842 3843 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3844 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3845 3846 validate_status_stopped(status, sigval); 3847 3848 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3849 SYSCALL_REQUIRE( 3850 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3851 3852 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3853 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3854 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3855 info.psi_siginfo.si_errno); 3856 3857 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3858 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3859 3860 DPRINTF("Set LWP event mask for the child %d\n", child); 3861 memset(&event, 0, sizeof(event)); 3862 if (trace_create) 3863 event.pe_set_event |= PTRACE_LWP_CREATE; 3864 if (trace_exit) 3865 event.pe_set_event |= PTRACE_LWP_EXIT; 3866 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3867 3868 DPRINTF("Before resuming the child process where it left off and " 3869 "without signal to be sent\n"); 3870 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3871 3872 memset(traced_lwps, 0, sizeof(traced_lwps)); 3873 3874 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 3875 DPRINTF("Before calling %s() for the child - expected stopped " 3876 "SIGTRAP\n", TWAIT_FNAME); 3877 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3878 child); 3879 3880 validate_status_stopped(status, SIGTRAP); 3881 3882 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3883 "child\n"); 3884 SYSCALL_REQUIRE( 3885 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3886 3887 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3888 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3889 "si_errno=%#x\n", 3890 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3891 info.psi_siginfo.si_errno); 3892 3893 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 3894 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 3895 3896 SYSCALL_REQUIRE( 3897 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3898 3899 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 3900 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 3901 3902 lid = state.pe_lwp; 3903 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 3904 3905 traced_lwps[lid - 1] = true; 3906 3907 DPRINTF("Before resuming the child process where it left off " 3908 "and without signal to be sent\n"); 3909 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3910 } 3911 3912 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 3913 DPRINTF("Before calling %s() for the child - expected stopped " 3914 "SIGTRAP\n", TWAIT_FNAME); 3915 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3916 child); 3917 3918 validate_status_stopped(status, SIGTRAP); 3919 3920 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3921 "child\n"); 3922 SYSCALL_REQUIRE( 3923 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3924 3925 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3926 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3927 "si_errno=%#x\n", 3928 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3929 info.psi_siginfo.si_errno); 3930 3931 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 3932 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 3933 3934 SYSCALL_REQUIRE( 3935 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3936 3937 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 3938 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 3939 3940 lid = state.pe_lwp; 3941 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 3942 3943 if (trace_create) { 3944 ATF_REQUIRE(traced_lwps[lid - 1] == true); 3945 traced_lwps[lid - 1] = false; 3946 } 3947 3948 DPRINTF("Before resuming the child process where it left off " 3949 "and without signal to be sent\n"); 3950 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3951 } 3952 3953 kill(child, SIGKILL); 3954 3955 DPRINTF("Before calling %s() for the child - expected exited\n", 3956 TWAIT_FNAME); 3957 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3958 3959 validate_status_signaled(status, SIGKILL, 0); 3960 3961 DPRINTF("Before calling %s() for the child - expected no process\n", 3962 TWAIT_FNAME); 3963 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3964} 3965 3966#define TRACE_THREADS(test, trace_create, trace_exit) \ 3967ATF_TC(test); \ 3968ATF_TC_HEAD(test, tc) \ 3969{ \ 3970 atf_tc_set_md_var(tc, "descr", \ 3971 "Verify spawning threads with%s tracing LWP create and" \ 3972 "with%s tracing LWP exit", trace_create ? "" : "out", \ 3973 trace_exit ? "" : "out"); \ 3974} \ 3975 \ 3976ATF_TC_BODY(test, tc) \ 3977{ \ 3978 \ 3979 trace_threads(trace_create, trace_exit); \ 3980} 3981 3982TRACE_THREADS(trace_thread1, false, false) 3983TRACE_THREADS(trace_thread2, false, true) 3984TRACE_THREADS(trace_thread3, true, false) 3985TRACE_THREADS(trace_thread4, true, true) 3986 3987/// ---------------------------------------------------------------------------- 3988 3989ATF_TC(signal_mask_unrelated); 3990ATF_TC_HEAD(signal_mask_unrelated, tc) 3991{ 3992 atf_tc_set_md_var(tc, "descr", 3993 "Verify that masking single unrelated signal does not stop tracer " 3994 "from catching other signals"); 3995} 3996 3997ATF_TC_BODY(signal_mask_unrelated, tc) 3998{ 3999 const int exitval = 5; 4000 const int sigval = SIGSTOP; 4001 const int sigmasked = SIGTRAP; 4002 const int signotmasked = SIGINT; 4003 pid_t child, wpid; 4004#if defined(TWAIT_HAVE_STATUS) 4005 int status; 4006#endif 4007 sigset_t intmask; 4008 4009 DPRINTF("Before forking process PID=%d\n", getpid()); 4010 SYSCALL_REQUIRE((child = fork()) != -1); 4011 if (child == 0) { 4012 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4013 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4014 4015 sigemptyset(&intmask); 4016 sigaddset(&intmask, sigmasked); 4017 sigprocmask(SIG_BLOCK, &intmask, NULL); 4018 4019 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4020 FORKEE_ASSERT(raise(sigval) == 0); 4021 4022 DPRINTF("Before raising %s from child\n", 4023 strsignal(signotmasked)); 4024 FORKEE_ASSERT(raise(signotmasked) == 0); 4025 4026 DPRINTF("Before exiting of the child process\n"); 4027 _exit(exitval); 4028 } 4029 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4030 4031 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4032 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4033 4034 validate_status_stopped(status, sigval); 4035 4036 DPRINTF("Before resuming the child process where it left off and " 4037 "without signal to be sent\n"); 4038 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4039 4040 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4041 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4042 4043 validate_status_stopped(status, signotmasked); 4044 4045 DPRINTF("Before resuming the child process where it left off and " 4046 "without signal to be sent\n"); 4047 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4048 4049 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4050 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4051 4052 validate_status_exited(status, exitval); 4053 4054 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4055 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4056} 4057 4058/// ---------------------------------------------------------------------------- 4059 4060ATF_TC(signal3); 4061ATF_TC_HEAD(signal3, tc) 4062{ 4063 atf_tc_set_md_var(tc, "timeout", "5"); 4064 atf_tc_set_md_var(tc, "descr", 4065 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4066 "catching software breakpoints"); 4067} 4068 4069ATF_TC_BODY(signal3, tc) 4070{ 4071 const int exitval = 5; 4072 const int sigval = SIGSTOP; 4073 const int sigmasked = SIGTRAP; 4074 pid_t child, wpid; 4075#if defined(TWAIT_HAVE_STATUS) 4076 int status; 4077#endif 4078 sigset_t intmask; 4079 4080 DPRINTF("Before forking process PID=%d\n", getpid()); 4081 SYSCALL_REQUIRE((child = fork()) != -1); 4082 if (child == 0) { 4083 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4084 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4085 4086 sigemptyset(&intmask); 4087 sigaddset(&intmask, sigmasked); 4088 sigprocmask(SIG_BLOCK, &intmask, NULL); 4089 4090 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4091 FORKEE_ASSERT(raise(sigval) == 0); 4092 4093 DPRINTF("Before raising software breakpoint from child\n"); 4094 trigger_trap(); 4095 4096 DPRINTF("Before exiting of the child process\n"); 4097 _exit(exitval); 4098 } 4099 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4100 4101 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4102 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4103 4104 validate_status_stopped(status, sigval); 4105 4106 DPRINTF("Before resuming the child process where it left off and " 4107 "without signal to be sent\n"); 4108 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4109 4110 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4111 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4112 4113 validate_status_stopped(status, sigmasked); 4114 4115 DPRINTF("Before resuming the child process where it left off and " 4116 "without signal to be sent\n"); 4117 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 4118 4119 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4120 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4121 4122 validate_status_signaled(status, SIGKILL, 0); 4123 4124 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4125 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4126} 4127 4128#if defined(PT_STEP) 4129ATF_TC(signal4); 4130ATF_TC_HEAD(signal4, tc) 4131{ 4132 atf_tc_set_md_var(tc, "descr", 4133 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4134 "catching single step trap"); 4135} 4136 4137ATF_TC_BODY(signal4, tc) 4138{ 4139 const int exitval = 5; 4140 const int sigval = SIGSTOP; 4141 const int sigmasked = SIGTRAP; 4142 pid_t child, wpid; 4143#if defined(TWAIT_HAVE_STATUS) 4144 int status; 4145#endif 4146 sigset_t intmask; 4147 int happy; 4148 4149#if defined(__arm__) 4150 /* PT_STEP not supported on arm 32-bit */ 4151 atf_tc_expect_fail("PR kern/51918 PR kern/52119"); 4152#endif 4153 4154 DPRINTF("Before forking process PID=%d\n", getpid()); 4155 SYSCALL_REQUIRE((child = fork()) != -1); 4156 if (child == 0) { 4157 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4158 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4159 4160 happy = check_happy(100); 4161 4162 sigemptyset(&intmask); 4163 sigaddset(&intmask, sigmasked); 4164 sigprocmask(SIG_BLOCK, &intmask, NULL); 4165 4166 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4167 FORKEE_ASSERT(raise(sigval) == 0); 4168 4169 FORKEE_ASSERT_EQ(happy, check_happy(100)); 4170 4171 DPRINTF("Before exiting of the child process\n"); 4172 _exit(exitval); 4173 } 4174 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4175 4176 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4177 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4178 4179 validate_status_stopped(status, sigval); 4180 4181 DPRINTF("Before resuming the child process where it left off and " 4182 "without signal to be sent\n"); 4183 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 4184 4185 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4186 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4187 4188 validate_status_stopped(status, sigmasked); 4189 4190 DPRINTF("Before resuming the child process where it left off and " 4191 "without signal to be sent\n"); 4192 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4193 4194 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4195 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4196 4197 validate_status_exited(status, exitval); 4198 4199 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4200 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4201} 4202#endif 4203 4204ATF_TC(signal5); 4205ATF_TC_HEAD(signal5, tc) 4206{ 4207 atf_tc_set_md_var(tc, "descr", 4208 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4209 "catching exec() breakpoint"); 4210} 4211 4212ATF_TC_BODY(signal5, tc) 4213{ 4214 const int sigval = SIGSTOP; 4215 const int sigmasked = SIGTRAP; 4216 pid_t child, wpid; 4217#if defined(TWAIT_HAVE_STATUS) 4218 int status; 4219#endif 4220 struct ptrace_siginfo info; 4221 sigset_t intmask; 4222 4223 memset(&info, 0, sizeof(info)); 4224 4225 DPRINTF("Before forking process PID=%d\n", getpid()); 4226 SYSCALL_REQUIRE((child = fork()) != -1); 4227 if (child == 0) { 4228 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4229 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4230 4231 sigemptyset(&intmask); 4232 sigaddset(&intmask, sigmasked); 4233 sigprocmask(SIG_BLOCK, &intmask, NULL); 4234 4235 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4236 FORKEE_ASSERT(raise(sigval) == 0); 4237 4238 DPRINTF("Before calling execve(2) from child\n"); 4239 execlp("/bin/echo", "/bin/echo", NULL); 4240 4241 /* NOTREACHED */ 4242 FORKEE_ASSERTX(0 && "Not reached"); 4243 } 4244 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4245 4246 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4247 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4248 4249 validate_status_stopped(status, sigval); 4250 4251 DPRINTF("Before resuming the child process where it left off and " 4252 "without signal to be sent\n"); 4253 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4254 4255 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4256 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4257 4258 validate_status_stopped(status, sigmasked); 4259 4260 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4261 SYSCALL_REQUIRE( 4262 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4263 4264 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4265 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4266 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4267 info.psi_siginfo.si_errno); 4268 4269 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked); 4270 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4271 4272 DPRINTF("Before resuming the child process where it left off and " 4273 "without signal to be sent\n"); 4274 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4275 4276 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4277 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4278 4279 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4280 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4281} 4282 4283#if defined(TWAIT_HAVE_PID) 4284ATF_TC(signal6); 4285ATF_TC_HEAD(signal6, tc) 4286{ 4287 atf_tc_set_md_var(tc, "timeout", "5"); 4288 atf_tc_set_md_var(tc, "descr", 4289 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4290 "catching PTRACE_FORK breakpoint"); 4291} 4292 4293ATF_TC_BODY(signal6, tc) 4294{ 4295 const int exitval = 5; 4296 const int exitval2 = 15; 4297 const int sigval = SIGSTOP; 4298 const int sigmasked = SIGTRAP; 4299 pid_t child, child2, wpid; 4300#if defined(TWAIT_HAVE_STATUS) 4301 int status; 4302#endif 4303 sigset_t intmask; 4304 ptrace_state_t state; 4305 const int slen = sizeof(state); 4306 ptrace_event_t event; 4307 const int elen = sizeof(event); 4308 4309 atf_tc_expect_fail("PR kern/51918"); 4310 4311 DPRINTF("Before forking process PID=%d\n", getpid()); 4312 SYSCALL_REQUIRE((child = fork()) != -1); 4313 if (child == 0) { 4314 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4315 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4316 4317 sigemptyset(&intmask); 4318 sigaddset(&intmask, sigmasked); 4319 sigprocmask(SIG_BLOCK, &intmask, NULL); 4320 4321 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4322 FORKEE_ASSERT(raise(sigval) == 0); 4323 4324 FORKEE_ASSERT((child2 = fork()) != -1); 4325 4326 if (child2 == 0) 4327 _exit(exitval2); 4328 4329 FORKEE_REQUIRE_SUCCESS 4330 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4331 4332 forkee_status_exited(status, exitval2); 4333 4334 DPRINTF("Before exiting of the child process\n"); 4335 _exit(exitval); 4336 } 4337 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4338 4339 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4341 4342 validate_status_stopped(status, sigval); 4343 4344 DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 4345 event.pe_set_event = PTRACE_FORK; 4346 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4347 4348 DPRINTF("Before resuming the child process where it left off and " 4349 "without signal to be sent\n"); 4350 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4351 4352 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4353 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4354 4355 validate_status_stopped(status, sigmasked); 4356 4357 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4358 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4359 4360 child2 = state.pe_other_pid; 4361 DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2); 4362 4363 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 4364 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4365 child2); 4366 4367 validate_status_stopped(status, SIGTRAP); 4368 4369 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 4370 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4371 ATF_REQUIRE_EQ(state.pe_other_pid, child); 4372 4373 DPRINTF("Before resuming the forkee process where it left off and " 4374 "without signal to be sent\n"); 4375 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 4376 4377 DPRINTF("Before resuming the child process where it left off and " 4378 "without signal to be sent\n"); 4379 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4380 4381 DPRINTF("Before calling %s() for the forkee - expected exited\n", 4382 TWAIT_FNAME); 4383 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4384 child2); 4385 4386 validate_status_exited(status, exitval2); 4387 4388 DPRINTF("Before calling %s() for the forkee - expected no process\n", 4389 TWAIT_FNAME); 4390 TWAIT_REQUIRE_FAILURE(ECHILD, 4391 wpid = TWAIT_GENERIC(child2, &status, 0)); 4392 4393 DPRINTF("Before calling %s() for the child - expected stopped " 4394 "SIGCHLD\n", TWAIT_FNAME); 4395 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4396 4397 validate_status_stopped(status, SIGCHLD); 4398 4399 DPRINTF("Before resuming the child process where it left off and " 4400 "without signal to be sent\n"); 4401 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4402 4403 DPRINTF("Before calling %s() for the child - expected exited\n", 4404 TWAIT_FNAME); 4405 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4406 4407 validate_status_exited(status, exitval); 4408 4409 DPRINTF("Before calling %s() for the child - expected no process\n", 4410 TWAIT_FNAME); 4411 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4412} 4413#endif 4414 4415#if defined(TWAIT_HAVE_PID) 4416ATF_TC(signal7); 4417ATF_TC_HEAD(signal7, tc) 4418{ 4419 atf_tc_set_md_var(tc, "descr", 4420 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4421 "catching PTRACE_VFORK breakpoint"); 4422} 4423 4424ATF_TC_BODY(signal7, tc) 4425{ 4426 const int exitval = 5; 4427 const int exitval2 = 15; 4428 const int sigval = SIGSTOP; 4429 const int sigmasked = SIGTRAP; 4430 pid_t child, child2, wpid; 4431#if defined(TWAIT_HAVE_STATUS) 4432 int status; 4433#endif 4434 sigset_t intmask; 4435 ptrace_state_t state; 4436 const int slen = sizeof(state); 4437 ptrace_event_t event; 4438 const int elen = sizeof(event); 4439 4440 atf_tc_expect_fail("PR kern/51918"); 4441 4442 DPRINTF("Before forking process PID=%d\n", getpid()); 4443 SYSCALL_REQUIRE((child = fork()) != -1); 4444 if (child == 0) { 4445 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4446 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4447 4448 sigemptyset(&intmask); 4449 sigaddset(&intmask, sigmasked); 4450 sigprocmask(SIG_BLOCK, &intmask, NULL); 4451 4452 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4453 FORKEE_ASSERT(raise(sigval) == 0); 4454 4455 FORKEE_ASSERT((child2 = fork()) != -1); 4456 4457 if (child2 == 0) 4458 _exit(exitval2); 4459 4460 FORKEE_REQUIRE_SUCCESS 4461 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4462 4463 forkee_status_exited(status, exitval2); 4464 4465 DPRINTF("Before exiting of the child process\n"); 4466 _exit(exitval); 4467 } 4468 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4469 4470 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4471 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4472 4473 validate_status_stopped(status, sigval); 4474 4475 DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 4476 event.pe_set_event = PTRACE_VFORK; 4477 SYSCALL_REQUIRE( 4478 ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || 4479 errno == ENOTSUP); 4480 4481 DPRINTF("Before resuming the child process where it left off and " 4482 "without signal to be sent\n"); 4483 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4484 4485 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4486 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4487 4488 validate_status_stopped(status, sigmasked); 4489 4490 SYSCALL_REQUIRE( 4491 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4492 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 4493 4494 child2 = state.pe_other_pid; 4495 DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2); 4496 4497 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 4498 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4499 child2); 4500 4501 validate_status_stopped(status, SIGTRAP); 4502 4503 SYSCALL_REQUIRE( 4504 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 4505 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 4506 ATF_REQUIRE_EQ(state.pe_other_pid, child); 4507 4508 DPRINTF("Before resuming the forkee process where it left off and " 4509 "without signal to be sent\n"); 4510 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 4511 4512 DPRINTF("Before resuming the child process where it left off and " 4513 "without signal to be sent\n"); 4514 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4515 4516 DPRINTF("Before calling %s() for the forkee - expected exited\n", 4517 TWAIT_FNAME); 4518 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4519 child2); 4520 4521 validate_status_exited(status, exitval2); 4522 4523 DPRINTF("Before calling %s() for the forkee - expected no process\n", 4524 TWAIT_FNAME); 4525 TWAIT_REQUIRE_FAILURE(ECHILD, 4526 wpid = TWAIT_GENERIC(child2, &status, 0)); 4527 4528 DPRINTF("Before calling %s() for the child - expected stopped " 4529 "SIGCHLD\n", TWAIT_FNAME); 4530 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4531 4532 validate_status_stopped(status, SIGCHLD); 4533 4534 DPRINTF("Before resuming the child process where it left off and " 4535 "without signal to be sent\n"); 4536 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4537 4538 DPRINTF("Before calling %s() for the child - expected exited\n", 4539 TWAIT_FNAME); 4540 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4541 4542 validate_status_exited(status, exitval); 4543 4544 DPRINTF("Before calling %s() for the child - expected no process\n", 4545 TWAIT_FNAME); 4546 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4547} 4548#endif 4549 4550ATF_TC(signal8); 4551ATF_TC_HEAD(signal8, tc) 4552{ 4553 atf_tc_set_md_var(tc, "descr", 4554 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4555 "catching PTRACE_VFORK_DONE breakpoint"); 4556} 4557 4558ATF_TC_BODY(signal8, tc) 4559{ 4560 const int exitval = 5; 4561 const int exitval2 = 15; 4562 const int sigval = SIGSTOP; 4563 const int sigmasked = SIGTRAP; 4564 pid_t child, child2, wpid; 4565#if defined(TWAIT_HAVE_STATUS) 4566 int status; 4567#endif 4568 sigset_t intmask; 4569 ptrace_state_t state; 4570 const int slen = sizeof(state); 4571 ptrace_event_t event; 4572 const int elen = sizeof(event); 4573 4574 atf_tc_expect_fail("PR kern/51918"); 4575 4576 DPRINTF("Before forking process PID=%d\n", getpid()); 4577 SYSCALL_REQUIRE((child = fork()) != -1); 4578 if (child == 0) { 4579 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4580 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4581 4582 sigemptyset(&intmask); 4583 sigaddset(&intmask, sigmasked); 4584 sigprocmask(SIG_BLOCK, &intmask, NULL); 4585 4586 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4587 FORKEE_ASSERT(raise(sigval) == 0); 4588 4589 FORKEE_ASSERT((child2 = vfork()) != -1); 4590 4591 if (child2 == 0) 4592 _exit(exitval2); 4593 4594 FORKEE_REQUIRE_SUCCESS 4595 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4596 4597 forkee_status_exited(status, exitval2); 4598 4599 DPRINTF("Before exiting of the child process\n"); 4600 _exit(exitval); 4601 } 4602 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4603 4604 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4605 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4606 4607 validate_status_stopped(status, sigval); 4608 4609 DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", 4610 child); 4611 event.pe_set_event = PTRACE_VFORK_DONE; 4612 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4613 4614 DPRINTF("Before resuming the child process where it left off and " 4615 "without signal to be sent\n"); 4616 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4617 4618 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4619 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4620 4621 validate_status_stopped(status, sigmasked); 4622 4623 SYSCALL_REQUIRE( 4624 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4625 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 4626 4627 child2 = state.pe_other_pid; 4628 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); 4629 4630 DPRINTF("Before resuming the child process where it left off and " 4631 "without signal to be sent\n"); 4632 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4633 4634 DPRINTF("Before calling %s() for the child - expected stopped " 4635 "SIGCHLD\n", TWAIT_FNAME); 4636 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4637 4638 validate_status_stopped(status, SIGCHLD); 4639 4640 DPRINTF("Before resuming the child process where it left off and " 4641 "without signal to be sent\n"); 4642 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4643 4644 DPRINTF("Before calling %s() for the child - expected exited\n", 4645 TWAIT_FNAME); 4646 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4647 4648 validate_status_exited(status, exitval); 4649 4650 DPRINTF("Before calling %s() for the child - expected no process\n", 4651 TWAIT_FNAME); 4652 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4653} 4654 4655volatile lwpid_t the_lwp_id = 0; 4656 4657static void 4658lwp_main_func(void *arg) 4659{ 4660 the_lwp_id = _lwp_self(); 4661 _lwp_exit(); 4662} 4663 4664ATF_TC(signal9); 4665ATF_TC_HEAD(signal9, tc) 4666{ 4667 atf_tc_set_md_var(tc, "descr", 4668 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4669 "catching PTRACE_LWP_CREATE breakpoint"); 4670} 4671 4672ATF_TC_BODY(signal9, tc) 4673{ 4674 const int exitval = 5; 4675 const int sigval = SIGSTOP; 4676 const int sigmasked = SIGTRAP; 4677 pid_t child, wpid; 4678#if defined(TWAIT_HAVE_STATUS) 4679 int status; 4680#endif 4681 sigset_t intmask; 4682 ptrace_state_t state; 4683 const int slen = sizeof(state); 4684 ptrace_event_t event; 4685 const int elen = sizeof(event); 4686 ucontext_t uc; 4687 lwpid_t lid; 4688 static const size_t ssize = 16*1024; 4689 void *stack; 4690 4691 atf_tc_expect_fail("PR kern/51918"); 4692 4693 DPRINTF("Before forking process PID=%d\n", getpid()); 4694 SYSCALL_REQUIRE((child = fork()) != -1); 4695 if (child == 0) { 4696 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4697 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4698 4699 sigemptyset(&intmask); 4700 sigaddset(&intmask, sigmasked); 4701 sigprocmask(SIG_BLOCK, &intmask, NULL); 4702 4703 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4704 FORKEE_ASSERT(raise(sigval) == 0); 4705 4706 DPRINTF("Before allocating memory for stack in child\n"); 4707 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4708 4709 DPRINTF("Before making context for new lwp in child\n"); 4710 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 4711 4712 DPRINTF("Before creating new in child\n"); 4713 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4714 4715 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4716 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4717 4718 DPRINTF("Before verifying that reported %d and running lid %d " 4719 "are the same\n", lid, the_lwp_id); 4720 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4721 4722 DPRINTF("Before exiting of the child process\n"); 4723 _exit(exitval); 4724 } 4725 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4726 4727 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4728 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4729 4730 validate_status_stopped(status, sigval); 4731 4732 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 4733 event.pe_set_event = PTRACE_LWP_CREATE; 4734 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4735 4736 DPRINTF("Before resuming the child process where it left off and " 4737 "without signal to be sent\n"); 4738 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4739 4740 DPRINTF("Before calling %s() for the child - expected stopped " 4741 "SIGTRAP\n", TWAIT_FNAME); 4742 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4743 4744 validate_status_stopped(status, sigmasked); 4745 4746 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4747 4748 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 4749 4750 lid = state.pe_lwp; 4751 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 4752 4753 DPRINTF("Before resuming the child process where it left off and " 4754 "without signal to be sent\n"); 4755 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4756 4757 DPRINTF("Before calling %s() for the child - expected exited\n", 4758 TWAIT_FNAME); 4759 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4760 4761 validate_status_exited(status, exitval); 4762 4763 DPRINTF("Before calling %s() for the child - expected no process\n", 4764 TWAIT_FNAME); 4765 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4766} 4767 4768ATF_TC(signal10); 4769ATF_TC_HEAD(signal10, tc) 4770{ 4771 atf_tc_set_md_var(tc, "descr", 4772 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4773 "catching PTRACE_LWP_EXIT breakpoint"); 4774} 4775 4776ATF_TC_BODY(signal10, tc) 4777{ 4778 const int exitval = 5; 4779 const int sigval = SIGSTOP; 4780 const int sigmasked = SIGTRAP; 4781 pid_t child, wpid; 4782#if defined(TWAIT_HAVE_STATUS) 4783 int status; 4784#endif 4785 sigset_t intmask; 4786 ptrace_state_t state; 4787 const int slen = sizeof(state); 4788 ptrace_event_t event; 4789 const int elen = sizeof(event); 4790 ucontext_t uc; 4791 lwpid_t lid; 4792 static const size_t ssize = 16*1024; 4793 void *stack; 4794 4795 atf_tc_expect_fail("PR kern/51918"); 4796 4797 DPRINTF("Before forking process PID=%d\n", getpid()); 4798 SYSCALL_REQUIRE((child = fork()) != -1); 4799 if (child == 0) { 4800 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4801 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4802 4803 sigemptyset(&intmask); 4804 sigaddset(&intmask, sigmasked); 4805 sigprocmask(SIG_BLOCK, &intmask, NULL); 4806 4807 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4808 FORKEE_ASSERT(raise(sigval) == 0); 4809 4810 DPRINTF("Before allocating memory for stack in child\n"); 4811 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4812 4813 DPRINTF("Before making context for new lwp in child\n"); 4814 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 4815 4816 DPRINTF("Before creating new in child\n"); 4817 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4818 4819 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4820 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4821 4822 DPRINTF("Before verifying that reported %d and running lid %d " 4823 "are the same\n", lid, the_lwp_id); 4824 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4825 4826 DPRINTF("Before exiting of the child process\n"); 4827 _exit(exitval); 4828 } 4829 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4830 4831 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4832 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4833 4834 validate_status_stopped(status, sigval); 4835 4836 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 4837 event.pe_set_event = PTRACE_LWP_EXIT; 4838 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4839 4840 DPRINTF("Before resuming the child process where it left off and " 4841 "without signal to be sent\n"); 4842 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4843 4844 DPRINTF("Before calling %s() for the child - expected stopped " 4845 "SIGTRAP\n", TWAIT_FNAME); 4846 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4847 4848 validate_status_stopped(status, sigmasked); 4849 4850 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4851 4852 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 4853 4854 lid = state.pe_lwp; 4855 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 4856 4857 DPRINTF("Before resuming the child process where it left off and " 4858 "without signal to be sent\n"); 4859 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4860 4861 DPRINTF("Before calling %s() for the child - expected exited\n", 4862 TWAIT_FNAME); 4863 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4864 4865 validate_status_exited(status, exitval); 4866 4867 DPRINTF("Before calling %s() for the child - expected no process\n", 4868 TWAIT_FNAME); 4869 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4870} 4871 4872static void 4873lwp_main_stop(void *arg) 4874{ 4875 the_lwp_id = _lwp_self(); 4876 4877 raise(SIGTRAP); 4878 4879 _lwp_exit(); 4880} 4881 4882ATF_TC(suspend1); 4883ATF_TC_HEAD(suspend1, tc) 4884{ 4885 atf_tc_set_md_var(tc, "descr", 4886 "Verify that a thread can be suspended by a debugger and later " 4887 "resumed by a tracee"); 4888} 4889 4890ATF_TC_BODY(suspend1, tc) 4891{ 4892 const int exitval = 5; 4893 const int sigval = SIGSTOP; 4894 pid_t child, wpid; 4895#if defined(TWAIT_HAVE_STATUS) 4896 int status; 4897#endif 4898 ucontext_t uc; 4899 lwpid_t lid; 4900 static const size_t ssize = 16*1024; 4901 void *stack; 4902 struct ptrace_lwpinfo pl; 4903 struct ptrace_siginfo psi; 4904 volatile int go = 0; 4905 4906 // Feature pending for refactoring 4907 atf_tc_expect_fail("PR kern/51995"); 4908 4909 // Hangs with qemu 4910 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 4911 4912 DPRINTF("Before forking process PID=%d\n", getpid()); 4913 SYSCALL_REQUIRE((child = fork()) != -1); 4914 if (child == 0) { 4915 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4916 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4917 4918 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4919 FORKEE_ASSERT(raise(sigval) == 0); 4920 4921 DPRINTF("Before allocating memory for stack in child\n"); 4922 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4923 4924 DPRINTF("Before making context for new lwp in child\n"); 4925 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 4926 4927 DPRINTF("Before creating new in child\n"); 4928 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4929 4930 while (go == 0) 4931 continue; 4932 4933 raise(SIGINT); 4934 4935 FORKEE_ASSERT(_lwp_continue(lid) == 0); 4936 4937 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4938 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4939 4940 DPRINTF("Before verifying that reported %d and running lid %d " 4941 "are the same\n", lid, the_lwp_id); 4942 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4943 4944 DPRINTF("Before exiting of the child process\n"); 4945 _exit(exitval); 4946 } 4947 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4948 4949 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4950 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4951 4952 validate_status_stopped(status, sigval); 4953 4954 DPRINTF("Before resuming the child process where it left off and " 4955 "without signal to be sent\n"); 4956 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4957 4958 DPRINTF("Before calling %s() for the child - expected stopped " 4959 "SIGTRAP\n", TWAIT_FNAME); 4960 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4961 4962 validate_status_stopped(status, SIGTRAP); 4963 4964 DPRINTF("Before reading siginfo and lwpid_t\n"); 4965 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 4966 4967 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 4968 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 4969 4970 DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 4971 child, getpid()); 4972 SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 4973 4974 DPRINTF("Before resuming the child process where it left off and " 4975 "without signal to be sent\n"); 4976 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4977 4978 DPRINTF("Before calling %s() for the child - expected stopped " 4979 "SIGINT\n", TWAIT_FNAME); 4980 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4981 4982 validate_status_stopped(status, SIGINT); 4983 4984 pl.pl_lwpid = 0; 4985 4986 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4987 while (pl.pl_lwpid != 0) { 4988 4989 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4990 switch (pl.pl_lwpid) { 4991 case 1: 4992 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 4993 break; 4994 case 2: 4995 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 4996 break; 4997 } 4998 } 4999 5000 DPRINTF("Before resuming the child process where it left off and " 5001 "without signal to be sent\n"); 5002 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5003 5004 DPRINTF("Before calling %s() for the child - expected exited\n", 5005 TWAIT_FNAME); 5006 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5007 5008 validate_status_exited(status, exitval); 5009 5010 DPRINTF("Before calling %s() for the child - expected no process\n", 5011 TWAIT_FNAME); 5012 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5013} 5014 5015ATF_TC(suspend2); 5016ATF_TC_HEAD(suspend2, tc) 5017{ 5018 atf_tc_set_md_var(tc, "descr", 5019 "Verify that the while the only thread within a process is " 5020 "suspended, the whole process cannot be unstopped"); 5021} 5022 5023ATF_TC_BODY(suspend2, tc) 5024{ 5025 const int exitval = 5; 5026 const int sigval = SIGSTOP; 5027 pid_t child, wpid; 5028#if defined(TWAIT_HAVE_STATUS) 5029 int status; 5030#endif 5031 struct ptrace_siginfo psi; 5032 5033 // Feature pending for refactoring 5034 atf_tc_expect_fail("PR kern/51995"); 5035 5036 // Hangs with qemu 5037 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5038 5039 DPRINTF("Before forking process PID=%d\n", getpid()); 5040 SYSCALL_REQUIRE((child = fork()) != -1); 5041 if (child == 0) { 5042 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5043 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5044 5045 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5046 FORKEE_ASSERT(raise(sigval) == 0); 5047 5048 DPRINTF("Before exiting of the child process\n"); 5049 _exit(exitval); 5050 } 5051 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5052 5053 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5054 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5055 5056 validate_status_stopped(status, sigval); 5057 5058 DPRINTF("Before reading siginfo and lwpid_t\n"); 5059 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5060 5061 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5062 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5063 5064 DPRINTF("Before resuming the child process where it left off and " 5065 "without signal to be sent\n"); 5066 ATF_REQUIRE_ERRNO(EDEADLK, 5067 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 5068 5069 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 5070 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 5071 5072 DPRINTF("Before resuming the child process where it left off and " 5073 "without signal to be sent\n"); 5074 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5075 5076 DPRINTF("Before calling %s() for the child - expected exited\n", 5077 TWAIT_FNAME); 5078 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5079 5080 validate_status_exited(status, exitval); 5081 5082 DPRINTF("Before calling %s() for the child - expected no process\n", 5083 TWAIT_FNAME); 5084 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5085} 5086 5087ATF_TC(resume1); 5088ATF_TC_HEAD(resume1, tc) 5089{ 5090 atf_tc_set_md_var(tc, "timeout", "5"); 5091 atf_tc_set_md_var(tc, "descr", 5092 "Verify that a thread can be suspended by a debugger and later " 5093 "resumed by the debugger"); 5094} 5095 5096ATF_TC_BODY(resume1, tc) 5097{ 5098 struct msg_fds fds; 5099 const int exitval = 5; 5100 const int sigval = SIGSTOP; 5101 pid_t child, wpid; 5102 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 5103#if defined(TWAIT_HAVE_STATUS) 5104 int status; 5105#endif 5106 ucontext_t uc; 5107 lwpid_t lid; 5108 static const size_t ssize = 16*1024; 5109 void *stack; 5110 struct ptrace_lwpinfo pl; 5111 struct ptrace_siginfo psi; 5112 5113 // Feature pending for refactoring 5114 atf_tc_expect_fail("PR kern/51995"); 5115 5116 // Hangs with qemu 5117 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5118 5119 SYSCALL_REQUIRE(msg_open(&fds) == 0); 5120 5121 DPRINTF("Before forking process PID=%d\n", getpid()); 5122 SYSCALL_REQUIRE((child = fork()) != -1); 5123 if (child == 0) { 5124 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5125 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5126 5127 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5128 FORKEE_ASSERT(raise(sigval) == 0); 5129 5130 DPRINTF("Before allocating memory for stack in child\n"); 5131 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5132 5133 DPRINTF("Before making context for new lwp in child\n"); 5134 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 5135 5136 DPRINTF("Before creating new in child\n"); 5137 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5138 5139 CHILD_TO_PARENT("Message", fds, msg); 5140 5141 raise(SIGINT); 5142 5143 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5144 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5145 5146 DPRINTF("Before verifying that reported %d and running lid %d " 5147 "are the same\n", lid, the_lwp_id); 5148 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5149 5150 DPRINTF("Before exiting of the child process\n"); 5151 _exit(exitval); 5152 } 5153 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5154 5155 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5156 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5157 5158 validate_status_stopped(status, sigval); 5159 5160 DPRINTF("Before resuming the child process where it left off and " 5161 "without signal to be sent\n"); 5162 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5163 5164 DPRINTF("Before calling %s() for the child - expected stopped " 5165 "SIGTRAP\n", TWAIT_FNAME); 5166 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5167 5168 validate_status_stopped(status, SIGTRAP); 5169 5170 DPRINTF("Before reading siginfo and lwpid_t\n"); 5171 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5172 5173 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5174 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5175 5176 PARENT_FROM_CHILD("Message", fds, msg); 5177 5178 DPRINTF("Before resuming the child process where it left off and " 5179 "without signal to be sent\n"); 5180 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5181 5182 DPRINTF("Before calling %s() for the child - expected stopped " 5183 "SIGINT\n", TWAIT_FNAME); 5184 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5185 5186 validate_status_stopped(status, SIGINT); 5187 5188 pl.pl_lwpid = 0; 5189 5190 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5191 while (pl.pl_lwpid != 0) { 5192 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5193 switch (pl.pl_lwpid) { 5194 case 1: 5195 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 5196 break; 5197 case 2: 5198 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 5199 break; 5200 } 5201 } 5202 5203 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 5204 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 5205 5206 DPRINTF("Before resuming the child process where it left off and " 5207 "without signal to be sent\n"); 5208 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5209 5210 DPRINTF("Before calling %s() for the child - expected exited\n", 5211 TWAIT_FNAME); 5212 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5213 5214 validate_status_exited(status, exitval); 5215 5216 DPRINTF("Before calling %s() for the child - expected no process\n", 5217 TWAIT_FNAME); 5218 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5219 5220 msg_close(&fds); 5221 5222 DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 5223 sleep(10); 5224} 5225 5226ATF_TC(syscall1); 5227ATF_TC_HEAD(syscall1, tc) 5228{ 5229 atf_tc_set_md_var(tc, "descr", 5230 "Verify that getpid(2) can be traced with PT_SYSCALL"); 5231} 5232 5233ATF_TC_BODY(syscall1, tc) 5234{ 5235 const int exitval = 5; 5236 const int sigval = SIGSTOP; 5237 pid_t child, wpid; 5238#if defined(TWAIT_HAVE_STATUS) 5239 int status; 5240#endif 5241 struct ptrace_siginfo info; 5242 memset(&info, 0, sizeof(info)); 5243 5244 DPRINTF("Before forking process PID=%d\n", getpid()); 5245 SYSCALL_REQUIRE((child = fork()) != -1); 5246 if (child == 0) { 5247 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5248 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5249 5250 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5251 FORKEE_ASSERT(raise(sigval) == 0); 5252 5253 syscall(SYS_getpid); 5254 5255 DPRINTF("Before exiting of the child process\n"); 5256 _exit(exitval); 5257 } 5258 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5259 5260 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5262 5263 validate_status_stopped(status, sigval); 5264 5265 DPRINTF("Before resuming the child process where it left off and " 5266 "without signal to be sent\n"); 5267 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5268 5269 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5270 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5271 5272 validate_status_stopped(status, SIGTRAP); 5273 5274 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5275 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5276 5277 DPRINTF("Before checking siginfo_t and lwpid\n"); 5278 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5279 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5280 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 5281 5282 DPRINTF("Before resuming the child process where it left off and " 5283 "without signal to be sent\n"); 5284 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5285 5286 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5287 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5288 5289 validate_status_stopped(status, SIGTRAP); 5290 5291 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5292 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5293 5294 DPRINTF("Before checking siginfo_t and lwpid\n"); 5295 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5296 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5297 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 5298 5299 DPRINTF("Before resuming the child process where it left off and " 5300 "without signal to be sent\n"); 5301 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5302 5303 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5304 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5305 5306 validate_status_exited(status, exitval); 5307 5308 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5309 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5310} 5311 5312ATF_TC(syscallemu1); 5313ATF_TC_HEAD(syscallemu1, tc) 5314{ 5315 atf_tc_set_md_var(tc, "descr", 5316 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 5317} 5318 5319ATF_TC_BODY(syscallemu1, tc) 5320{ 5321 const int exitval = 5; 5322 const int sigval = SIGSTOP; 5323 pid_t child, wpid; 5324#if defined(TWAIT_HAVE_STATUS) 5325 int status; 5326#endif 5327 5328#if defined(__sparc__) && !defined(__sparc64__) 5329 /* syscallemu does not work on sparc (32-bit) */ 5330 atf_tc_expect_fail("PR kern/52166"); 5331#endif 5332 5333 DPRINTF("Before forking process PID=%d\n", getpid()); 5334 SYSCALL_REQUIRE((child = fork()) != -1); 5335 if (child == 0) { 5336 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5337 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5338 5339 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5340 FORKEE_ASSERT(raise(sigval) == 0); 5341 5342 syscall(SYS_exit, 100); 5343 5344 DPRINTF("Before exiting of the child process\n"); 5345 _exit(exitval); 5346 } 5347 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5348 5349 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5350 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5351 5352 validate_status_stopped(status, sigval); 5353 5354 DPRINTF("Before resuming the child process where it left off and " 5355 "without signal to be sent\n"); 5356 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5357 5358 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5359 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5360 5361 validate_status_stopped(status, SIGTRAP); 5362 5363 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 5364 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 5365 5366 DPRINTF("Before resuming the child process where it left off and " 5367 "without signal to be sent\n"); 5368 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5369 5370 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5371 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5372 5373 validate_status_stopped(status, SIGTRAP); 5374 5375 DPRINTF("Before resuming the child process where it left off and " 5376 "without signal to be sent\n"); 5377 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5378 5379 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5380 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5381 5382 validate_status_exited(status, exitval); 5383 5384 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5385 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5386} 5387 5388#include "t_ptrace_amd64_wait.h" 5389#include "t_ptrace_i386_wait.h" 5390#include "t_ptrace_x86_wait.h" 5391 5392ATF_TP_ADD_TCS(tp) 5393{ 5394 setvbuf(stdout, NULL, _IONBF, 0); 5395 setvbuf(stderr, NULL, _IONBF, 0); 5396 5397 ATF_TP_ADD_TC(tp, traceme_raise1); 5398 ATF_TP_ADD_TC(tp, traceme_raise2); 5399 ATF_TP_ADD_TC(tp, traceme_raise3); 5400 ATF_TP_ADD_TC(tp, traceme_raise4); 5401 ATF_TP_ADD_TC(tp, traceme_raise5); 5402 ATF_TP_ADD_TC(tp, traceme_raise6); 5403 ATF_TP_ADD_TC(tp, traceme_raise7); 5404 ATF_TP_ADD_TC(tp, traceme_raise8); 5405 ATF_TP_ADD_TC(tp, traceme_raise9); 5406 ATF_TP_ADD_TC(tp, traceme_raise10); 5407 5408 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 5409 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 5410 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 5411 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 5412 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 5413 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 5414 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 5415 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 5416 5417 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 5418 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 5419 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 5420 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 5421 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 5422 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 5423 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 5424 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 5425 5426 ATF_TP_ADD_TC(tp, traceme_crash_trap); 5427 ATF_TP_ADD_TC(tp, traceme_crash_segv); 5428 ATF_TP_ADD_TC(tp, traceme_crash_ill); 5429 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 5430 ATF_TP_ADD_TC(tp, traceme_crash_bus); 5431 5432 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 5433 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 5434 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 5435 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 5436 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 5437 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 5438 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 5439 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 5440 5441 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 5442 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 5443 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 5444 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 5445 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 5446 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 5447 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 5448 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 5449 5450 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 5451 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 5452 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 5453 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 5454 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 5455 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 5456 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 5457 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 5458 5459 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 5460 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 5461 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 5462 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 5463 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 5464 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 5465 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 5466 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 5467 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 5468 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 5469 5470 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 5471 5472 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 5473 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 5474 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 5475 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 5476 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 5477 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 5478 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 5479 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 5480 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 5481 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 5482 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 5483 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 5484 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 5485 5486 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 5487 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 5488 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 5489 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 5490 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 5491 5492 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 5493 5494 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 5495 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 5496 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 5497 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 5498 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 5499 5500 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 5501 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 5502 ATF_TP_ADD_TC_HAVE_PID(tp, 5503 unrelated_tracer_sees_terminaton_before_the_parent); 5504 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 5505 5506 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 5507 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 5508 5509 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 5510 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 5511 5512 ATF_TP_ADD_TC_HAVE_PID(tp, 5513 tracee_sees_its_original_parent_getppid); 5514 ATF_TP_ADD_TC_HAVE_PID(tp, 5515 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 5516 ATF_TP_ADD_TC_HAVE_PID(tp, 5517 tracee_sees_its_original_parent_procfs_status); 5518 5519 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 5520 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 5521 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 5522 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 5523 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 5524 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 5525 5526 ATF_TP_ADD_TC(tp, fork1); 5527 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 5528 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 5529 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 5530 ATF_TP_ADD_TC(tp, fork5); 5531 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 5532 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 5533 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 5534 5535 ATF_TP_ADD_TC(tp, vfork1); 5536 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 5537 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 5538 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 5539 ATF_TP_ADD_TC(tp, vfork5); 5540 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 5541// thes tests hang on SMP machines, disable them for now 5542// ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 5543// ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 5544 5545 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 5546 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 5547 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 5548 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 5549 5550 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 5551 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 5552 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 5553 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 5554 5555 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 5556 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 5557 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 5558 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 5559 5560 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 5561 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 5562 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 5563 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 5564 5565 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 5566 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 5567 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 5568 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 5569 5570 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 5571 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 5572 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 5573 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 5574 5575 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 5576 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 5577 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 5578 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 5579 5580 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 5581 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 5582 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 5583 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 5584 5585 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 5586 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 5587 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 5588 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 5589 5590 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 5591 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 5592 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 5593 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 5594 5595 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 5596 5597 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 5598 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 5599 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 5600 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 5601 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 5602 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 5603 5604 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 5605 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 5606 5607 ATF_TP_ADD_TC_PT_STEP(tp, step1); 5608 ATF_TP_ADD_TC_PT_STEP(tp, step2); 5609 ATF_TP_ADD_TC_PT_STEP(tp, step3); 5610 ATF_TP_ADD_TC_PT_STEP(tp, step4); 5611 5612 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 5613 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 5614 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 5615 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 5616 5617 ATF_TP_ADD_TC(tp, kill1); 5618 ATF_TP_ADD_TC(tp, kill2); 5619 ATF_TP_ADD_TC(tp, kill3); 5620 5621 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 5622 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 5623 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 5624 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 5625 5626 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 5627 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 5628 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 5629 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 5630 5631 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 5632 ATF_TP_ADD_TC(tp, siginfo_set_faked); 5633 5634 ATF_TP_ADD_TC(tp, traceme_exec); 5635 5636 ATF_TP_ADD_TC(tp, trace_thread1); 5637 ATF_TP_ADD_TC(tp, trace_thread2); 5638 ATF_TP_ADD_TC(tp, trace_thread3); 5639 ATF_TP_ADD_TC(tp, trace_thread4); 5640 5641 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 5642 5643 ATF_TP_ADD_TC(tp, signal3); 5644 ATF_TP_ADD_TC_PT_STEP(tp, signal4); 5645 ATF_TP_ADD_TC(tp, signal5); 5646 ATF_TP_ADD_TC_HAVE_PID(tp, signal6); 5647 ATF_TP_ADD_TC_HAVE_PID(tp, signal7); 5648 ATF_TP_ADD_TC(tp, signal8); 5649 ATF_TP_ADD_TC(tp, signal9); 5650 ATF_TP_ADD_TC(tp, signal10); 5651 5652 ATF_TP_ADD_TC(tp, suspend1); 5653 ATF_TP_ADD_TC(tp, suspend2); 5654 5655 ATF_TP_ADD_TC(tp, resume1); 5656 5657 ATF_TP_ADD_TC(tp, syscall1); 5658 5659 ATF_TP_ADD_TC(tp, syscallemu1); 5660 5661 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 5662 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 5663 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 5664 5665 return atf_no_error(); 5666} 5667