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