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