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