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