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