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