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