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