t_ptrace_wait.c revision 313680
1/* $NetBSD: t_ptrace_wait.c,v 1.53 2017/01/10 05:08:24 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.53 2017/01/10 05:08:24 kamil Exp $"); 31 32#include <sys/param.h> 33#include <sys/types.h> 34#include <sys/ptrace.h> 35#include <sys/resource.h> 36#include <sys/stat.h> 37#include <sys/sysctl.h> 38#include <sys/wait.h> 39#include <machine/reg.h> 40#include <err.h> 41#include <errno.h> 42#include <signal.h> 43#include <stdint.h> 44#include <stdio.h> 45#include <stdlib.h> 46#include <strings.h> 47#include <unistd.h> 48 49#include <atf-c.h> 50 51#include "../h_macros.h" 52 53#include "t_ptrace_wait.h" 54#include "msg.h" 55 56#define PARENT_TO_CHILD(info, fds, msg) \ 57 ATF_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0) 58 59#define CHILD_FROM_PARENT(info, fds, msg) \ 60 FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) 61 62#define CHILD_TO_PARENT(info, fds, msg) \ 63 FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0) 64 65#define PARENT_FROM_CHILD(info, fds, msg) \ 66 ATF_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) 67 68ATF_TC(traceme1); 69ATF_TC_HEAD(traceme1, tc) 70{ 71 atf_tc_set_md_var(tc, "descr", 72 "Verify SIGSTOP followed by _exit(2) in a child"); 73} 74 75ATF_TC_BODY(traceme1, tc) 76{ 77 const int exitval = 5; 78 const int sigval = SIGSTOP; 79 pid_t child, wpid; 80#if defined(TWAIT_HAVE_STATUS) 81 int status; 82#endif 83 84 printf("Before forking process PID=%d\n", getpid()); 85 ATF_REQUIRE((child = fork()) != -1); 86 if (child == 0) { 87 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 88 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 89 90 printf("Before raising %s from child\n", strsignal(sigval)); 91 FORKEE_ASSERT(raise(sigval) == 0); 92 93 printf("Before exiting of the child process\n"); 94 _exit(exitval); 95 } 96 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 97 98 printf("Before calling %s() for the child\n", TWAIT_FNAME); 99 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 100 101 validate_status_stopped(status, sigval); 102 103 printf("Before resuming the child process where it left off and " 104 "without signal to be sent\n"); 105 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 106 107 printf("Before calling %s() for the child\n", TWAIT_FNAME); 108 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 109 110 validate_status_exited(status, exitval); 111 112 printf("Before calling %s() for the child\n", TWAIT_FNAME); 113 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 114} 115 116ATF_TC(traceme2); 117ATF_TC_HEAD(traceme2, tc) 118{ 119 atf_tc_set_md_var(tc, "descr", 120 "Verify SIGSTOP followed by _exit(2) in a child"); 121} 122 123static int traceme2_caught = 0; 124 125static void 126traceme2_sighandler(int sig) 127{ 128 FORKEE_ASSERT_EQ(sig, SIGINT); 129 130 ++traceme2_caught; 131} 132 133ATF_TC_BODY(traceme2, tc) 134{ 135 const int exitval = 5; 136 const int sigval = SIGSTOP, sigsent = SIGINT; 137 pid_t child, wpid; 138 struct sigaction sa; 139#if defined(TWAIT_HAVE_STATUS) 140 int status; 141#endif 142 143 printf("Before forking process PID=%d\n", getpid()); 144 ATF_REQUIRE((child = fork()) != -1); 145 if (child == 0) { 146 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 147 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 148 149 sa.sa_handler = traceme2_sighandler; 150 sa.sa_flags = SA_SIGINFO; 151 sigemptyset(&sa.sa_mask); 152 153 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 154 155 printf("Before raising %s from child\n", strsignal(sigval)); 156 FORKEE_ASSERT(raise(sigval) == 0); 157 158 FORKEE_ASSERT_EQ(traceme2_caught, 1); 159 160 printf("Before exiting of the child process\n"); 161 _exit(exitval); 162 } 163 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 164 165 printf("Before calling %s() for the child\n", TWAIT_FNAME); 166 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 167 168 validate_status_stopped(status, sigval); 169 170 printf("Before resuming the child process where it left off and with " 171 "signal %s to be sent\n", strsignal(sigsent)); 172 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 173 174 printf("Before calling %s() for the child\n", TWAIT_FNAME); 175 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 176 177 validate_status_exited(status, exitval); 178 179 printf("Before calling %s() for the exited child\n", TWAIT_FNAME); 180 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 181} 182 183ATF_TC(traceme3); 184ATF_TC_HEAD(traceme3, tc) 185{ 186 atf_tc_set_md_var(tc, "descr", 187 "Verify SIGSTOP followed by termination by a signal in a child"); 188} 189 190ATF_TC_BODY(traceme3, tc) 191{ 192 const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */; 193 pid_t child, wpid; 194#if defined(TWAIT_HAVE_STATUS) 195 int status; 196#endif 197 198 printf("Before forking process PID=%d\n", getpid()); 199 ATF_REQUIRE((child = fork()) != -1); 200 if (child == 0) { 201 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 202 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 203 204 printf("Before raising %s from child\n", strsignal(sigval)); 205 FORKEE_ASSERT(raise(sigval) == 0); 206 207 /* NOTREACHED */ 208 FORKEE_ASSERTX(0 && 209 "Child should be terminated by a signal from its parent"); 210 } 211 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 212 213 printf("Before calling %s() for the child\n", TWAIT_FNAME); 214 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 215 216 validate_status_stopped(status, sigval); 217 218 printf("Before resuming the child process where it left off and with " 219 "signal %s to be sent\n", strsignal(sigsent)); 220 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 221 222 printf("Before calling %s() for the child\n", TWAIT_FNAME); 223 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 224 225 validate_status_signaled(status, sigsent, 0); 226 227 printf("Before calling %s() for the exited child\n", TWAIT_FNAME); 228 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 229} 230 231ATF_TC(traceme4); 232ATF_TC_HEAD(traceme4, tc) 233{ 234 atf_tc_set_md_var(tc, "descr", 235 "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child"); 236} 237 238ATF_TC_BODY(traceme4, tc) 239{ 240 const int exitval = 5; 241 const int sigval = SIGSTOP, sigsent = SIGCONT; 242 pid_t child, wpid; 243#if defined(TWAIT_HAVE_STATUS) 244 int status; 245#endif 246 247 printf("Before forking process PID=%d\n", getpid()); 248 ATF_REQUIRE((child = fork()) != -1); 249 if (child == 0) { 250 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 251 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 252 253 printf("Before raising %s from child\n", strsignal(sigval)); 254 FORKEE_ASSERT(raise(sigval) == 0); 255 256 printf("Before raising %s from child\n", strsignal(sigsent)); 257 FORKEE_ASSERT(raise(sigsent) == 0); 258 259 printf("Before exiting of the child process\n"); 260 _exit(exitval); 261 } 262 printf("Parent process PID=%d, child's PID=%d\n", getpid(),child); 263 264 printf("Before calling %s() for the child\n", TWAIT_FNAME); 265 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 266 267 validate_status_stopped(status, sigval); 268 269 printf("Before resuming the child process where it left off and " 270 "without signal to be sent\n"); 271 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 272 273 printf("Before calling %s() for the child\n", TWAIT_FNAME); 274 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 275 276 validate_status_stopped(status, sigsent); 277 278 printf("Before resuming the child process where it left off and " 279 "without signal to be sent\n"); 280 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 281 282 printf("Before calling %s() for the child\n", TWAIT_FNAME); 283 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 284 285 validate_status_exited(status, exitval); 286 287 printf("Before calling %s() for the exited child\n", TWAIT_FNAME); 288 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 289} 290 291#if defined(TWAIT_HAVE_PID) 292ATF_TC(attach1); 293ATF_TC_HEAD(attach1, tc) 294{ 295 atf_tc_set_md_var(tc, "descr", 296 "Assert that tracer sees process termination before the parent"); 297} 298 299ATF_TC_BODY(attach1, tc) 300{ 301 struct msg_fds parent_tracee, parent_tracer; 302 const int exitval_tracee = 5; 303 const int exitval_tracer = 10; 304 pid_t tracee, tracer, wpid; 305 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 306#if defined(TWAIT_HAVE_STATUS) 307 int status; 308#endif 309 310 printf("Spawn tracee\n"); 311 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 312 tracee = atf_utils_fork(); 313 if (tracee == 0) { 314 // Wait for parent to let us exit 315 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 316 _exit(exitval_tracee); 317 } 318 319 printf("Spawn debugger\n"); 320 ATF_REQUIRE(msg_open(&parent_tracer) == 0); 321 tracer = atf_utils_fork(); 322 if (tracer == 0) { 323 printf("Before calling PT_ATTACH from tracee %d\n", getpid()); 324 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 325 326 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 327 FORKEE_REQUIRE_SUCCESS( 328 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 329 330 forkee_status_stopped(status, SIGSTOP); 331 332 /* Resume tracee with PT_CONTINUE */ 333 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 334 335 /* Inform parent that tracer has attached to tracee */ 336 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 337 338 /* Wait for parent to tell use that tracee should have exited */ 339 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 340 341 /* Wait for tracee and assert that it exited */ 342 FORKEE_REQUIRE_SUCCESS( 343 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 344 345 forkee_status_exited(status, exitval_tracee); 346 printf("Tracee %d exited with %d\n", tracee, exitval_tracee); 347 348 printf("Before exiting of the tracer process\n"); 349 _exit(exitval_tracer); 350 } 351 352 printf("Wait for the tracer to attach to the tracee\n"); 353 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 354 355 printf("Resume the tracee and let it exit\n"); 356 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 357 358 printf("Detect that tracee is zombie\n"); 359 await_zombie(tracee); 360 361 362 printf("Assert that there is no status about tracee %d - " 363 "Tracer must detect zombie first - calling %s()\n", tracee, 364 TWAIT_FNAME); 365 TWAIT_REQUIRE_SUCCESS( 366 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 367 368 printf("Tell the tracer child should have exited\n"); 369 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 370 printf("Wait for tracer to finish its job and exit - calling %s()\n", 371 TWAIT_FNAME); 372 373 printf("Wait from tracer child to complete waiting for tracee\n"); 374 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 375 tracer); 376 377 validate_status_exited(status, exitval_tracer); 378 379 printf("Wait for tracee to finish its job and exit - calling %s()\n", 380 TWAIT_FNAME); 381 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 382 tracee); 383 384 validate_status_exited(status, exitval_tracee); 385 386 msg_close(&parent_tracer); 387 msg_close(&parent_tracee); 388} 389#endif 390 391#if defined(TWAIT_HAVE_PID) 392ATF_TC(attach2); 393ATF_TC_HEAD(attach2, tc) 394{ 395 atf_tc_set_md_var(tc, "descr", 396 "Assert that any tracer sees process termination before its " 397 "parent"); 398} 399 400ATF_TC_BODY(attach2, tc) 401{ 402 struct msg_fds parent_tracer, parent_tracee; 403 const int exitval_tracee = 5; 404 const int exitval_tracer1 = 10, exitval_tracer2 = 20; 405 pid_t tracee, tracer, wpid; 406 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 407#if defined(TWAIT_HAVE_STATUS) 408 int status; 409#endif 410 411 printf("Spawn tracee\n"); 412 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 413 tracee = atf_utils_fork(); 414 if (tracee == 0) { 415 /* Wait for message from the parent */ 416 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 417 _exit(exitval_tracee); 418 } 419 420 printf("Spawn debugger\n"); 421 ATF_REQUIRE(msg_open(&parent_tracer) == 0); 422 tracer = atf_utils_fork(); 423 if (tracer == 0) { 424 /* Fork again and drop parent to reattach to PID 1 */ 425 tracer = atf_utils_fork(); 426 if (tracer != 0) 427 _exit(exitval_tracer1); 428 429 printf("Before calling PT_ATTACH from tracee %d\n", getpid()); 430 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 431 432 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 433 FORKEE_REQUIRE_SUCCESS( 434 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 435 436 forkee_status_stopped(status, SIGSTOP); 437 438 /* Resume tracee with PT_CONTINUE */ 439 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 440 441 /* Inform parent that tracer has attached to tracee */ 442 CHILD_TO_PARENT("Message 1", parent_tracer, msg); 443 CHILD_FROM_PARENT("Message 2", parent_tracer, msg); 444 445 /* Wait for tracee and assert that it exited */ 446 FORKEE_REQUIRE_SUCCESS( 447 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 448 449 forkee_status_exited(status, exitval_tracee); 450 451 printf("Before exiting of the tracer process\n"); 452 _exit(exitval_tracer2); 453 } 454 printf("Wait for the tracer process (direct child) to exit calling " 455 "%s()\n", TWAIT_FNAME); 456 TWAIT_REQUIRE_SUCCESS( 457 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 458 459 validate_status_exited(status, exitval_tracer1); 460 461 printf("Wait for the non-exited tracee process with %s()\n", 462 TWAIT_FNAME); 463 TWAIT_REQUIRE_SUCCESS( 464 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 465 466 printf("Wait for the tracer to attach to the tracee\n"); 467 PARENT_FROM_CHILD("Message 1", parent_tracer, msg); 468 printf("Resume the tracee and let it exit\n"); 469 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 470 471 printf("Detect that tracee is zombie\n"); 472 await_zombie(tracee); 473 474 printf("Assert that there is no status about tracee - " 475 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 476 TWAIT_REQUIRE_SUCCESS( 477 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 478 479 printf("Resume the tracer and let it detect exited tracee\n"); 480 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 481 482 printf("Wait for tracee to finish its job and exit - calling %s()\n", 483 TWAIT_FNAME); 484 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 485 tracee); 486 487 validate_status_exited(status, exitval_tracee); 488 489 msg_close(&parent_tracer); 490 msg_close(&parent_tracee); 491 492} 493#endif 494 495ATF_TC(attach3); 496ATF_TC_HEAD(attach3, tc) 497{ 498 atf_tc_set_md_var(tc, "descr", 499 "Assert that tracer parent can PT_ATTACH to its child"); 500} 501 502ATF_TC_BODY(attach3, tc) 503{ 504 struct msg_fds parent_tracee; 505 const int exitval_tracee = 5; 506 pid_t tracee, wpid; 507 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 508#if defined(TWAIT_HAVE_STATUS) 509 int status; 510#endif 511 512 printf("Spawn tracee\n"); 513 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 514 tracee = atf_utils_fork(); 515 if (tracee == 0) { 516 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 517 printf("Parent should now attach to tracee\n"); 518 519 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 520 /* Wait for message from the parent */ 521 _exit(exitval_tracee); 522 } 523 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 524 525 printf("Before calling PT_ATTACH for tracee %d\n", tracee); 526 ATF_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 527 528 printf("Wait for the stopped tracee process with %s()\n", 529 TWAIT_FNAME); 530 TWAIT_REQUIRE_SUCCESS( 531 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 532 533 validate_status_stopped(status, SIGSTOP); 534 535 printf("Resume tracee with PT_CONTINUE\n"); 536 ATF_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 537 538 printf("Let the tracee exit now\n"); 539 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 540 541 printf("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 542 TWAIT_REQUIRE_SUCCESS( 543 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 544 545 validate_status_exited(status, exitval_tracee); 546 547 printf("Before calling %s() for tracee\n", TWAIT_FNAME); 548 TWAIT_REQUIRE_FAILURE(ECHILD, 549 wpid = TWAIT_GENERIC(tracee, &status, 0)); 550 551 msg_close(&parent_tracee); 552} 553 554ATF_TC(attach4); 555ATF_TC_HEAD(attach4, tc) 556{ 557 atf_tc_set_md_var(tc, "descr", 558 "Assert that tracer child can PT_ATTACH to its parent"); 559} 560 561ATF_TC_BODY(attach4, tc) 562{ 563 struct msg_fds parent_tracee; 564 const int exitval_tracer = 5; 565 pid_t tracer, wpid; 566 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 567#if defined(TWAIT_HAVE_STATUS) 568 int status; 569#endif 570 571 printf("Spawn tracer\n"); 572 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 573 tracer = atf_utils_fork(); 574 if (tracer == 0) { 575 576 /* Wait for message from the parent */ 577 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 578 579 printf("Attach to parent PID %d with PT_ATTACH from child\n", 580 getppid()); 581 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 582 583 printf("Wait for the stopped parent process with %s()\n", 584 TWAIT_FNAME); 585 FORKEE_REQUIRE_SUCCESS( 586 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 587 588 forkee_status_stopped(status, SIGSTOP); 589 590 printf("Resume parent with PT_DETACH\n"); 591 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 592 != -1); 593 594 /* Tell parent we are ready */ 595 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 596 597 _exit(exitval_tracer); 598 } 599 600 printf("Wait for the tracer to become ready\n"); 601 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 602 printf("Allow the tracer to exit now\n"); 603 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 604 605 printf("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 606 TWAIT_REQUIRE_SUCCESS( 607 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 608 609 validate_status_exited(status, exitval_tracer); 610 611 printf("Before calling %s() for tracer\n", TWAIT_FNAME); 612 TWAIT_REQUIRE_FAILURE(ECHILD, 613 wpid = TWAIT_GENERIC(tracer, &status, 0)); 614 615 msg_close(&parent_tracee); 616} 617 618#if defined(TWAIT_HAVE_PID) 619ATF_TC(attach5); 620ATF_TC_HEAD(attach5, tc) 621{ 622 atf_tc_set_md_var(tc, "descr", 623 "Assert that tracer sees its parent when attached to tracer " 624 "(check getppid(2))"); 625} 626 627ATF_TC_BODY(attach5, tc) 628{ 629 struct msg_fds parent_tracer, parent_tracee; 630 const int exitval_tracee = 5; 631 const int exitval_tracer = 10; 632 pid_t parent, tracee, tracer, wpid; 633 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 634#if defined(TWAIT_HAVE_STATUS) 635 int status; 636#endif 637 638 printf("Spawn tracee\n"); 639 ATF_REQUIRE(msg_open(&parent_tracer) == 0); 640 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 641 tracee = atf_utils_fork(); 642 if (tracee == 0) { 643 parent = getppid(); 644 645 /* Emit message to the parent */ 646 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 647 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 648 649 FORKEE_ASSERT_EQ(parent, getppid()); 650 651 _exit(exitval_tracee); 652 } 653 printf("Wait for child to record its parent identifier (pid)\n"); 654 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 655 656 printf("Spawn debugger\n"); 657 tracer = atf_utils_fork(); 658 if (tracer == 0) { 659 /* No IPC to communicate with the child */ 660 printf("Before calling PT_ATTACH from tracee %d\n", getpid()); 661 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 662 663 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 664 FORKEE_REQUIRE_SUCCESS( 665 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 666 667 forkee_status_stopped(status, SIGSTOP); 668 669 /* Resume tracee with PT_CONTINUE */ 670 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 671 672 /* Inform parent that tracer has attached to tracee */ 673 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 674 675 /* Wait for parent to tell use that tracee should have exited */ 676 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 677 678 /* Wait for tracee and assert that it exited */ 679 FORKEE_REQUIRE_SUCCESS( 680 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 681 682 forkee_status_exited(status, exitval_tracee); 683 684 printf("Before exiting of the tracer process\n"); 685 _exit(exitval_tracer); 686 } 687 688 printf("Wait for the tracer to attach to the tracee\n"); 689 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 690 691 printf("Resume the tracee and let it exit\n"); 692 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 693 694 printf("Detect that tracee is zombie\n"); 695 await_zombie(tracee); 696 697 printf("Assert that there is no status about tracee - " 698 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 699 TWAIT_REQUIRE_SUCCESS( 700 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 701 702 printf("Tell the tracer child should have exited\n"); 703 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 704 705 printf("Wait from tracer child to complete waiting for tracee\n"); 706 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 707 tracer); 708 709 validate_status_exited(status, exitval_tracer); 710 711 printf("Wait for tracee to finish its job and exit - calling %s()\n", 712 TWAIT_FNAME); 713 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 714 tracee); 715 716 validate_status_exited(status, exitval_tracee); 717 718 msg_close(&parent_tracer); 719 msg_close(&parent_tracee); 720} 721#endif 722 723#if defined(TWAIT_HAVE_PID) 724ATF_TC(attach6); 725ATF_TC_HEAD(attach6, tc) 726{ 727 atf_tc_set_md_var(tc, "descr", 728 "Assert that tracer sees its parent when attached to tracer " 729 "(check sysctl(7) and struct kinfo_proc2)"); 730} 731 732ATF_TC_BODY(attach6, tc) 733{ 734 struct msg_fds parent_tracee, parent_tracer; 735 const int exitval_tracee = 5; 736 const int exitval_tracer = 10; 737 pid_t parent, tracee, tracer, wpid; 738 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 739#if defined(TWAIT_HAVE_STATUS) 740 int status; 741#endif 742 int name[CTL_MAXNAME]; 743 struct kinfo_proc2 kp; 744 size_t len = sizeof(kp); 745 unsigned int namelen; 746 747 printf("Spawn tracee\n"); 748 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 749 ATF_REQUIRE(msg_open(&parent_tracer) == 0); 750 tracee = atf_utils_fork(); 751 if (tracee == 0) { 752 parent = getppid(); 753 754 /* Emit message to the parent */ 755 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 756 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 757 758 namelen = 0; 759 name[namelen++] = CTL_KERN; 760 name[namelen++] = KERN_PROC2; 761 name[namelen++] = KERN_PROC_PID; 762 name[namelen++] = getpid(); 763 name[namelen++] = len; 764 name[namelen++] = 1; 765 766 FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0); 767 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 768 769 _exit(exitval_tracee); 770 } 771 772 printf("Wait for child to record its parent identifier (pid)\n"); 773 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 774 775 printf("Spawn debugger\n"); 776 tracer = atf_utils_fork(); 777 if (tracer == 0) { 778 /* No IPC to communicate with the child */ 779 printf("Before calling PT_ATTACH from tracee %d\n", getpid()); 780 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 781 782 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 783 FORKEE_REQUIRE_SUCCESS( 784 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 785 786 forkee_status_stopped(status, SIGSTOP); 787 788 /* Resume tracee with PT_CONTINUE */ 789 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 790 791 /* Inform parent that tracer has attached to tracee */ 792 CHILD_TO_PARENT("Message 1", parent_tracer, msg); 793 794 CHILD_FROM_PARENT("Message 2", parent_tracer, msg); 795 796 /* Wait for tracee and assert that it exited */ 797 FORKEE_REQUIRE_SUCCESS( 798 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 799 800 forkee_status_exited(status, exitval_tracee); 801 802 printf("Before exiting of the tracer process\n"); 803 _exit(exitval_tracer); 804 } 805 806 printf("Wait for the tracer to attach to the tracee\n"); 807 PARENT_FROM_CHILD("Message 1", parent_tracer, msg); 808 809 printf("Resume the tracee and let it exit\n"); 810 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 811 812 printf("Detect that tracee is zombie\n"); 813 await_zombie(tracee); 814 815 printf("Assert that there is no status about tracee - " 816 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 817 TWAIT_REQUIRE_SUCCESS( 818 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 819 820 printf("Resume the tracer and let it detect exited tracee\n"); 821 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 822 823 printf("Wait for tracer to finish its job and exit - calling %s()\n", 824 TWAIT_FNAME); 825 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 826 tracer); 827 828 validate_status_exited(status, exitval_tracer); 829 830 printf("Wait for tracee to finish its job and exit - calling %s()\n", 831 TWAIT_FNAME); 832 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 833 tracee); 834 835 validate_status_exited(status, exitval_tracee); 836 837 msg_close(&parent_tracee); 838 msg_close(&parent_tracer); 839} 840#endif 841 842#if defined(TWAIT_HAVE_PID) 843ATF_TC(attach7); 844ATF_TC_HEAD(attach7, tc) 845{ 846 atf_tc_set_md_var(tc, "descr", 847 "Assert that tracer sees its parent when attached to tracer " 848 "(check /proc/curproc/status 3rd column)"); 849} 850 851ATF_TC_BODY(attach7, tc) 852{ 853 struct msg_fds parent_tracee, parent_tracer; 854 int rv; 855 const int exitval_tracee = 5; 856 const int exitval_tracer = 10; 857 pid_t parent, tracee, tracer, wpid; 858 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 859#if defined(TWAIT_HAVE_STATUS) 860 int status; 861#endif 862 FILE *fp; 863 struct stat st; 864 const char *fname = "/proc/curproc/status"; 865 char s_executable[MAXPATHLEN]; 866 int s_pid, s_ppid; 867 /* 868 * Format: 869 * EXECUTABLE PID PPID ... 870 */ 871 872 ATF_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 873 if (rv != 0) { 874 atf_tc_skip("/proc/curproc/status not found"); 875 } 876 877 printf("Spawn tracee\n"); 878 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 879 ATF_REQUIRE(msg_open(&parent_tracer) == 0); 880 tracee = atf_utils_fork(); 881 if (tracee == 0) { 882 parent = getppid(); 883 884 // Wait for parent to let us exit 885 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 886 CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); 887 888 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 889 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 890 FORKEE_ASSERT(fclose(fp) == 0); 891 FORKEE_ASSERT_EQ(parent, s_ppid); 892 893 _exit(exitval_tracee); 894 } 895 896 printf("Wait for child to record its parent identifier (pid)\n"); 897 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 898 899 printf("Spawn debugger\n"); 900 tracer = atf_utils_fork(); 901 if (tracer == 0) { 902 printf("Before calling PT_ATTACH from tracee %d\n", getpid()); 903 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 904 905 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 906 FORKEE_REQUIRE_SUCCESS( 907 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 908 909 forkee_status_stopped(status, SIGSTOP); 910 911 /* Resume tracee with PT_CONTINUE */ 912 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 913 914 /* Inform parent that tracer has attached to tracee */ 915 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 916 917 /* Wait for parent to tell use that tracee should have exited */ 918 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 919 920 /* Wait for tracee and assert that it exited */ 921 FORKEE_REQUIRE_SUCCESS( 922 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 923 924 forkee_status_exited(status, exitval_tracee); 925 926 printf("Before exiting of the tracer process\n"); 927 _exit(exitval_tracer); 928 } 929 printf("Wait for the tracer to attach to the tracee\n"); 930 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 931 printf("Resume the tracee and let it exit\n"); 932 PARENT_TO_CHILD("tracee exit", parent_tracee, msg); 933 934 printf("Detect that tracee is zombie\n"); 935 await_zombie(tracee); 936 937 printf("Assert that there is no status about tracee - " 938 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 939 TWAIT_REQUIRE_SUCCESS( 940 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 941 942 printf("Resume the tracer and let it detect exited tracee\n"); 943 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 944 945 printf("Wait for tracer to finish its job and exit - calling %s()\n", 946 TWAIT_FNAME); 947 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 948 tracer); 949 950 validate_status_exited(status, exitval_tracer); 951 952 printf("Wait for tracee to finish its job and exit - calling %s()\n", 953 TWAIT_FNAME); 954 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 955 tracee); 956 957 validate_status_exited(status, exitval_tracee); 958 959 msg_close(&parent_tracee); 960 msg_close(&parent_tracer); 961} 962#endif 963 964ATF_TC(eventmask1); 965ATF_TC_HEAD(eventmask1, tc) 966{ 967 atf_tc_set_md_var(tc, "descr", 968 "Verify that empty EVENT_MASK is preserved"); 969} 970 971ATF_TC_BODY(eventmask1, tc) 972{ 973 const int exitval = 5; 974 const int sigval = SIGSTOP; 975 pid_t child, wpid; 976#if defined(TWAIT_HAVE_STATUS) 977 int status; 978#endif 979 ptrace_event_t set_event, get_event; 980 const int len = sizeof(ptrace_event_t); 981 982 printf("Before forking process PID=%d\n", getpid()); 983 ATF_REQUIRE((child = fork()) != -1); 984 if (child == 0) { 985 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 986 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 987 988 printf("Before raising %s from child\n", strsignal(sigval)); 989 FORKEE_ASSERT(raise(sigval) == 0); 990 991 printf("Before exiting of the child process\n"); 992 _exit(exitval); 993 } 994 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 995 996 printf("Before calling %s() for the child\n", TWAIT_FNAME); 997 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 998 999 validate_status_stopped(status, sigval); 1000 1001 set_event.pe_set_event = 0; 1002 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 1003 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 1004 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 1005 1006 printf("Before resuming the child process where it left off and " 1007 "without signal to be sent\n"); 1008 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1009 1010 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1011 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1012 1013 validate_status_exited(status, exitval); 1014 1015 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1016 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1017} 1018 1019ATF_TC(eventmask2); 1020ATF_TC_HEAD(eventmask2, tc) 1021{ 1022 atf_tc_set_md_var(tc, "descr", 1023 "Verify that PTRACE_FORK in EVENT_MASK is preserved"); 1024} 1025 1026ATF_TC_BODY(eventmask2, tc) 1027{ 1028 const int exitval = 5; 1029 const int sigval = SIGSTOP; 1030 pid_t child, wpid; 1031#if defined(TWAIT_HAVE_STATUS) 1032 int status; 1033#endif 1034 ptrace_event_t set_event, get_event; 1035 const int len = sizeof(ptrace_event_t); 1036 1037 printf("Before forking process PID=%d\n", getpid()); 1038 ATF_REQUIRE((child = fork()) != -1); 1039 if (child == 0) { 1040 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1041 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1042 1043 printf("Before raising %s from child\n", strsignal(sigval)); 1044 FORKEE_ASSERT(raise(sigval) == 0); 1045 1046 printf("Before exiting of the child process\n"); 1047 _exit(exitval); 1048 } 1049 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1050 1051 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1052 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1053 1054 validate_status_stopped(status, sigval); 1055 1056 set_event.pe_set_event = PTRACE_FORK; 1057 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 1058 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 1059 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 1060 1061 printf("Before resuming the child process where it left off and " 1062 "without signal to be sent\n"); 1063 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1064 1065 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1066 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1067 1068 validate_status_exited(status, exitval); 1069 1070 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1071 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1072} 1073 1074#if defined(TWAIT_HAVE_PID) 1075ATF_TC(fork1); 1076ATF_TC_HEAD(fork1, tc) 1077{ 1078 atf_tc_set_md_var(tc, "descr", 1079 "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK " 1080 "set to PTRACE_FORK"); 1081} 1082 1083ATF_TC_BODY(fork1, tc) 1084{ 1085 const int exitval = 5; 1086 const int exitval2 = 15; 1087 const int sigval = SIGSTOP; 1088 pid_t child, child2, wpid; 1089#if defined(TWAIT_HAVE_STATUS) 1090 int status; 1091#endif 1092 ptrace_state_t state; 1093 const int slen = sizeof(state); 1094 ptrace_event_t event; 1095 const int elen = sizeof(event); 1096 1097 printf("Before forking process PID=%d\n", getpid()); 1098 ATF_REQUIRE((child = fork()) != -1); 1099 if (child == 0) { 1100 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1101 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1102 1103 printf("Before raising %s from child\n", strsignal(sigval)); 1104 FORKEE_ASSERT(raise(sigval) == 0); 1105 1106 FORKEE_ASSERT((child2 = fork()) != 1); 1107 1108 if (child2 == 0) 1109 _exit(exitval2); 1110 1111 FORKEE_REQUIRE_SUCCESS 1112 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 1113 1114 forkee_status_exited(status, exitval2); 1115 1116 printf("Before exiting of the child process\n"); 1117 _exit(exitval); 1118 } 1119 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1120 1121 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1122 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1123 1124 validate_status_stopped(status, sigval); 1125 1126 printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 1127 event.pe_set_event = PTRACE_FORK; 1128 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1129 1130 printf("Before resuming the child process where it left off and " 1131 "without signal to be sent\n"); 1132 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1133 1134 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); 1135 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1136 1137 validate_status_stopped(status, SIGTRAP); 1138 1139 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1140 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 1141 1142 child2 = state.pe_other_pid; 1143 printf("Reported PTRACE_FORK event with forkee %d\n", child2); 1144 1145 printf("Before calling %s() for the forkee %d of the child %d\n", 1146 TWAIT_FNAME, child2, child); 1147 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 1148 child2); 1149 1150 validate_status_stopped(status, SIGTRAP); 1151 1152 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 1153 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 1154 ATF_REQUIRE_EQ(state.pe_other_pid, child); 1155 1156 printf("Before resuming the forkee process where it left off and " 1157 "without signal to be sent\n"); 1158 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 1159 1160 printf("Before resuming the child process where it left off and " 1161 "without signal to be sent\n"); 1162 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1163 1164 printf("Before calling %s() for the forkee - expected exited\n", 1165 TWAIT_FNAME); 1166 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 1167 child2); 1168 1169 validate_status_exited(status, exitval2); 1170 1171 printf("Before calling %s() for the forkee - expected no process\n", 1172 TWAIT_FNAME); 1173 TWAIT_REQUIRE_FAILURE(ECHILD, 1174 wpid = TWAIT_GENERIC(child2, &status, 0)); 1175 1176 printf("Before calling %s() for the child - expected stopped " 1177 "SIGCHLD\n", TWAIT_FNAME); 1178 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1179 1180 validate_status_stopped(status, SIGCHLD); 1181 1182 printf("Before resuming the child process where it left off and " 1183 "without signal to be sent\n"); 1184 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1185 1186 printf("Before calling %s() for the child - expected exited\n", 1187 TWAIT_FNAME); 1188 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1189 1190 validate_status_exited(status, exitval); 1191 1192 printf("Before calling %s() for the child - expected no process\n", 1193 TWAIT_FNAME); 1194 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1195} 1196#endif 1197 1198ATF_TC(fork2); 1199ATF_TC_HEAD(fork2, tc) 1200{ 1201 atf_tc_set_md_var(tc, "descr", 1202 "Verify that fork(2) is not intercepted by ptrace(2) with empty " 1203 "EVENT_MASK"); 1204} 1205 1206ATF_TC_BODY(fork2, tc) 1207{ 1208 const int exitval = 5; 1209 const int exitval2 = 15; 1210 const int sigval = SIGSTOP; 1211 pid_t child, child2, wpid; 1212#if defined(TWAIT_HAVE_STATUS) 1213 int status; 1214#endif 1215 ptrace_event_t event; 1216 const int elen = sizeof(event); 1217 1218 printf("Before forking process PID=%d\n", getpid()); 1219 ATF_REQUIRE((child = fork()) != -1); 1220 if (child == 0) { 1221 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1222 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1223 1224 printf("Before raising %s from child\n", strsignal(sigval)); 1225 FORKEE_ASSERT(raise(sigval) == 0); 1226 1227 FORKEE_ASSERT((child2 = fork()) != 1); 1228 1229 if (child2 == 0) 1230 _exit(exitval2); 1231 1232 FORKEE_REQUIRE_SUCCESS 1233 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 1234 1235 forkee_status_exited(status, exitval2); 1236 1237 printf("Before exiting of the child process\n"); 1238 _exit(exitval); 1239 } 1240 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1241 1242 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1243 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1244 1245 validate_status_stopped(status, sigval); 1246 1247 printf("Set empty EVENT_MASK for the child %d\n", child); 1248 event.pe_set_event = 0; 1249 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1250 1251 printf("Before resuming the child process where it left off and " 1252 "without signal to be sent\n"); 1253 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1254 1255 printf("Before calling %s() for the child - expected stopped " 1256 "SIGCHLD\n", TWAIT_FNAME); 1257 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1258 1259 validate_status_stopped(status, SIGCHLD); 1260 1261 printf("Before resuming the child process where it left off and " 1262 "without signal to be sent\n"); 1263 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1264 1265 printf("Before calling %s() for the child - expected exited\n", 1266 TWAIT_FNAME); 1267 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1268 1269 validate_status_exited(status, exitval); 1270 1271 printf("Before calling %s() for the child - expected no process\n", 1272 TWAIT_FNAME); 1273 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1274} 1275 1276#if defined(TWAIT_HAVE_PID) 1277ATF_TC(vfork1); 1278ATF_TC_HEAD(vfork1, tc) 1279{ 1280 atf_tc_set_md_var(tc, "descr", 1281 "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " 1282 "set to PTRACE_VFORK"); 1283} 1284 1285ATF_TC_BODY(vfork1, tc) 1286{ 1287 const int exitval = 5; 1288 const int exitval2 = 15; 1289 const int sigval = SIGSTOP; 1290 pid_t child, child2, wpid; 1291#if defined(TWAIT_HAVE_STATUS) 1292 int status; 1293#endif 1294 ptrace_state_t state; 1295 const int slen = sizeof(state); 1296 ptrace_event_t event; 1297 const int elen = sizeof(event); 1298 1299 /* 1300 * ptrace(2) command PT_SET_EVENT_MASK: option PTRACE_VFORK unsupported 1301 */ 1302#ifndef PTRACE_VFORK 1303#define PTRACE_VFORK 0 1304#endif 1305 atf_tc_expect_fail("PR kern/51630"); 1306 1307 printf("Before forking process PID=%d\n", getpid()); 1308 ATF_REQUIRE((child = fork()) != -1); 1309 if (child == 0) { 1310 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1311 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1312 1313 printf("Before raising %s from child\n", strsignal(sigval)); 1314 FORKEE_ASSERT(raise(sigval) == 0); 1315 1316 FORKEE_ASSERT((child2 = vfork()) != 1); 1317 1318 if (child2 == 0) 1319 _exit(exitval2); 1320 1321 FORKEE_REQUIRE_SUCCESS 1322 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 1323 1324 forkee_status_exited(status, exitval2); 1325 1326 printf("Before exiting of the child process\n"); 1327 _exit(exitval); 1328 } 1329 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1330 1331 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1332 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1333 1334 validate_status_stopped(status, sigval); 1335 1336 printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 1337 event.pe_set_event = PTRACE_VFORK; 1338 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1339 1340 printf("Before resuming the child process where it left off and " 1341 "without signal to be sent\n"); 1342 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1343 1344 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); 1345 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1346 1347 validate_status_stopped(status, SIGTRAP); 1348 1349 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1350 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 1351 1352 child2 = state.pe_other_pid; 1353 printf("Reported PTRACE_VFORK event with forkee %d\n", child2); 1354 1355 printf("Before calling %s() for the forkee %d of the child %d\n", 1356 TWAIT_FNAME, child2, child); 1357 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 1358 child2); 1359 1360 validate_status_stopped(status, SIGTRAP); 1361 1362 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 1363 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 1364 ATF_REQUIRE_EQ(state.pe_other_pid, child); 1365 1366 printf("Before resuming the forkee process where it left off and " 1367 "without signal to be sent\n"); 1368 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 1369 1370 printf("Before resuming the child process where it left off and " 1371 "without signal to be sent\n"); 1372 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1373 1374 printf("Before calling %s() for the forkee - expected exited\n", 1375 TWAIT_FNAME); 1376 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 1377 child2); 1378 1379 validate_status_exited(status, exitval2); 1380 1381 printf("Before calling %s() for the forkee - expected no process\n", 1382 TWAIT_FNAME); 1383 TWAIT_REQUIRE_FAILURE(ECHILD, 1384 wpid = TWAIT_GENERIC(child2, &status, 0)); 1385 1386 printf("Before calling %s() for the child - expected stopped " 1387 "SIGCHLD\n", TWAIT_FNAME); 1388 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1389 1390 validate_status_stopped(status, SIGCHLD); 1391 1392 printf("Before resuming the child process where it left off and " 1393 "without signal to be sent\n"); 1394 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1395 1396 printf("Before calling %s() for the child - expected exited\n", 1397 TWAIT_FNAME); 1398 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1399 1400 validate_status_exited(status, exitval); 1401 1402 printf("Before calling %s() for the child - expected no process\n", 1403 TWAIT_FNAME); 1404 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1405} 1406#endif 1407 1408ATF_TC(vfork2); 1409ATF_TC_HEAD(vfork2, tc) 1410{ 1411 atf_tc_set_md_var(tc, "descr", 1412 "Verify that vfork(2) is not intercepted by ptrace(2) with empty " 1413 "EVENT_MASK"); 1414} 1415 1416ATF_TC_BODY(vfork2, tc) 1417{ 1418 const int exitval = 5; 1419 const int exitval2 = 15; 1420 const int sigval = SIGSTOP; 1421 pid_t child, child2, wpid; 1422#if defined(TWAIT_HAVE_STATUS) 1423 int status; 1424#endif 1425 ptrace_event_t event; 1426 const int elen = sizeof(event); 1427 1428 printf("Before forking process PID=%d\n", getpid()); 1429 ATF_REQUIRE((child = fork()) != -1); 1430 if (child == 0) { 1431 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1432 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1433 1434 printf("Before raising %s from child\n", strsignal(sigval)); 1435 FORKEE_ASSERT(raise(sigval) == 0); 1436 1437 FORKEE_ASSERT((child2 = vfork()) != 1); 1438 1439 if (child2 == 0) 1440 _exit(exitval2); 1441 1442 FORKEE_REQUIRE_SUCCESS 1443 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 1444 1445 forkee_status_exited(status, exitval2); 1446 1447 printf("Before exiting of the child process\n"); 1448 _exit(exitval); 1449 } 1450 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1451 1452 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1453 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1454 1455 validate_status_stopped(status, sigval); 1456 1457 printf("Set empty EVENT_MASK for the child %d\n", child); 1458 event.pe_set_event = 0; 1459 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1460 1461 printf("Before resuming the child process where it left off and " 1462 "without signal to be sent\n"); 1463 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1464 1465 printf("Before calling %s() for the child - expected stopped " 1466 "SIGCHLD\n", TWAIT_FNAME); 1467 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1468 1469 validate_status_stopped(status, SIGCHLD); 1470 1471 printf("Before resuming the child process where it left off and " 1472 "without signal to be sent\n"); 1473 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1474 1475 printf("Before calling %s() for the child - expected exited\n", 1476 TWAIT_FNAME); 1477 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1478 1479 validate_status_exited(status, exitval); 1480 1481 printf("Before calling %s() for the child - expected no process\n", 1482 TWAIT_FNAME); 1483 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1484} 1485 1486ATF_TC(io_read_d1); 1487ATF_TC_HEAD(io_read_d1, tc) 1488{ 1489 atf_tc_set_md_var(tc, "descr", 1490 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)"); 1491} 1492 1493ATF_TC_BODY(io_read_d1, tc) 1494{ 1495 const int exitval = 5; 1496 const int sigval = SIGSTOP; 1497 pid_t child, wpid; 1498 uint8_t lookup_me = 0; 1499 const uint8_t magic = 0xab; 1500 struct ptrace_io_desc io = { 1501 .piod_op = PIOD_READ_D, 1502 .piod_offs = &lookup_me, 1503 .piod_addr = &lookup_me, 1504 .piod_len = sizeof(lookup_me) 1505 }; 1506#if defined(TWAIT_HAVE_STATUS) 1507 int status; 1508#endif 1509 1510 printf("Before forking process PID=%d\n", getpid()); 1511 ATF_REQUIRE((child = fork()) != -1); 1512 if (child == 0) { 1513 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1514 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1515 1516 lookup_me = magic; 1517 1518 printf("Before raising %s from child\n", strsignal(sigval)); 1519 FORKEE_ASSERT(raise(sigval) == 0); 1520 1521 printf("Before exiting of the child process\n"); 1522 _exit(exitval); 1523 } 1524 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1525 1526 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1527 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1528 1529 validate_status_stopped(status, sigval); 1530 1531 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 1532 child, getpid()); 1533 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1534 1535 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 1536 "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); 1537 1538 printf("Before resuming the child process where it left off and " 1539 "without signal to be sent\n"); 1540 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1541 1542 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1543 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1544 1545 validate_status_exited(status, exitval); 1546 1547 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1548 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1549} 1550 1551ATF_TC(io_read_d2); 1552ATF_TC_HEAD(io_read_d2, tc) 1553{ 1554 atf_tc_set_md_var(tc, "descr", 1555 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)"); 1556} 1557 1558ATF_TC_BODY(io_read_d2, tc) 1559{ 1560 const int exitval = 5; 1561 const int sigval = SIGSTOP; 1562 pid_t child, wpid; 1563 uint16_t lookup_me = 0; 1564 const uint16_t magic = 0x1234; 1565 struct ptrace_io_desc io = { 1566 .piod_op = PIOD_READ_D, 1567 .piod_offs = &lookup_me, 1568 .piod_addr = &lookup_me, 1569 .piod_len = sizeof(lookup_me) 1570 }; 1571#if defined(TWAIT_HAVE_STATUS) 1572 int status; 1573#endif 1574 1575 printf("Before forking process PID=%d\n", getpid()); 1576 ATF_REQUIRE((child = fork()) != -1); 1577 if (child == 0) { 1578 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1579 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1580 1581 lookup_me = magic; 1582 1583 printf("Before raising %s from child\n", strsignal(sigval)); 1584 FORKEE_ASSERT(raise(sigval) == 0); 1585 1586 printf("Before exiting of the child process\n"); 1587 _exit(exitval); 1588 } 1589 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1590 1591 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1592 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1593 1594 validate_status_stopped(status, sigval); 1595 1596 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 1597 child, getpid()); 1598 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1599 1600 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 1601 "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic); 1602 1603 printf("Before resuming the child process where it left off and " 1604 "without signal to be sent\n"); 1605 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1606 1607 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1608 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1609 1610 validate_status_exited(status, exitval); 1611 1612 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1613 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1614} 1615 1616ATF_TC(io_read_d3); 1617ATF_TC_HEAD(io_read_d3, tc) 1618{ 1619 atf_tc_set_md_var(tc, "descr", 1620 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)"); 1621} 1622 1623ATF_TC_BODY(io_read_d3, tc) 1624{ 1625 const int exitval = 5; 1626 const int sigval = SIGSTOP; 1627 pid_t child, wpid; 1628 uint32_t lookup_me = 0; 1629 const uint32_t magic = 0x1234abcd; 1630 struct ptrace_io_desc io = { 1631 .piod_op = PIOD_READ_D, 1632 .piod_offs = &lookup_me, 1633 .piod_addr = &lookup_me, 1634 .piod_len = sizeof(lookup_me) 1635 }; 1636#if defined(TWAIT_HAVE_STATUS) 1637 int status; 1638#endif 1639 1640 printf("Before forking process PID=%d\n", getpid()); 1641 ATF_REQUIRE((child = fork()) != -1); 1642 if (child == 0) { 1643 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1644 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1645 1646 lookup_me = magic; 1647 1648 printf("Before raising %s from child\n", strsignal(sigval)); 1649 FORKEE_ASSERT(raise(sigval) == 0); 1650 1651 printf("Before exiting of the child process\n"); 1652 _exit(exitval); 1653 } 1654 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1655 1656 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1657 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1658 1659 validate_status_stopped(status, sigval); 1660 1661 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 1662 child, getpid()); 1663 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1664 1665 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 1666 "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic); 1667 1668 printf("Before resuming the child process where it left off and " 1669 "without signal to be sent\n"); 1670 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1671 1672 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1673 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1674 1675 validate_status_exited(status, exitval); 1676 1677 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1678 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1679} 1680 1681ATF_TC(io_read_d4); 1682ATF_TC_HEAD(io_read_d4, tc) 1683{ 1684 atf_tc_set_md_var(tc, "descr", 1685 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)"); 1686} 1687 1688ATF_TC_BODY(io_read_d4, tc) 1689{ 1690 const int exitval = 5; 1691 const int sigval = SIGSTOP; 1692 pid_t child, wpid; 1693 uint64_t lookup_me = 0; 1694 const uint64_t magic = 0x1234abcd9876dcfa; 1695 struct ptrace_io_desc io = { 1696 .piod_op = PIOD_READ_D, 1697 .piod_offs = &lookup_me, 1698 .piod_addr = &lookup_me, 1699 .piod_len = sizeof(lookup_me) 1700 }; 1701#if defined(TWAIT_HAVE_STATUS) 1702 int status; 1703#endif 1704 1705 printf("Before forking process PID=%d\n", getpid()); 1706 ATF_REQUIRE((child = fork()) != -1); 1707 if (child == 0) { 1708 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1709 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1710 1711 lookup_me = magic; 1712 1713 printf("Before raising %s from child\n", strsignal(sigval)); 1714 FORKEE_ASSERT(raise(sigval) == 0); 1715 1716 printf("Before exiting of the child process\n"); 1717 _exit(exitval); 1718 } 1719 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1720 1721 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1722 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1723 1724 validate_status_stopped(status, sigval); 1725 1726 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 1727 child, getpid()); 1728 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1729 1730 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 1731 "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic); 1732 1733 printf("Before resuming the child process where it left off and " 1734 "without signal to be sent\n"); 1735 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1736 1737 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1738 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1739 1740 validate_status_exited(status, exitval); 1741 1742 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1743 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1744} 1745 1746ATF_TC(io_write_d1); 1747ATF_TC_HEAD(io_write_d1, tc) 1748{ 1749 atf_tc_set_md_var(tc, "descr", 1750 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)"); 1751} 1752 1753ATF_TC_BODY(io_write_d1, tc) 1754{ 1755 const int exitval = 5; 1756 const int sigval = SIGSTOP; 1757 pid_t child, wpid; 1758 uint8_t lookup_me = 0; 1759 const uint8_t magic = 0xab; 1760 struct ptrace_io_desc io = { 1761 .piod_op = PIOD_WRITE_D, 1762 .piod_offs = &lookup_me, 1763 .piod_addr = &lookup_me, 1764 .piod_len = sizeof(lookup_me) 1765 }; 1766#if defined(TWAIT_HAVE_STATUS) 1767 int status; 1768#endif 1769 1770 printf("Before forking process PID=%d\n", getpid()); 1771 ATF_REQUIRE((child = fork()) != -1); 1772 if (child == 0) { 1773 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1774 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1775 1776 printf("Before raising %s from child\n", strsignal(sigval)); 1777 FORKEE_ASSERT(raise(sigval) == 0); 1778 1779 FORKEE_ASSERT_EQ(lookup_me, magic); 1780 1781 printf("Before exiting of the child process\n"); 1782 _exit(exitval); 1783 } 1784 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1785 1786 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1787 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1788 1789 validate_status_stopped(status, sigval); 1790 1791 lookup_me = magic; 1792 1793 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", 1794 child, getpid()); 1795 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1796 1797 printf("Before resuming the child process where it left off and " 1798 "without signal to be sent\n"); 1799 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1800 1801 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1802 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1803 1804 validate_status_exited(status, exitval); 1805 1806 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1807 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1808} 1809 1810ATF_TC(io_write_d2); 1811ATF_TC_HEAD(io_write_d2, tc) 1812{ 1813 atf_tc_set_md_var(tc, "descr", 1814 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)"); 1815} 1816 1817ATF_TC_BODY(io_write_d2, tc) 1818{ 1819 const int exitval = 5; 1820 const int sigval = SIGSTOP; 1821 pid_t child, wpid; 1822 uint16_t lookup_me = 0; 1823 const uint16_t magic = 0xab12; 1824 struct ptrace_io_desc io = { 1825 .piod_op = PIOD_WRITE_D, 1826 .piod_offs = &lookup_me, 1827 .piod_addr = &lookup_me, 1828 .piod_len = sizeof(lookup_me) 1829 }; 1830#if defined(TWAIT_HAVE_STATUS) 1831 int status; 1832#endif 1833 1834 printf("Before forking process PID=%d\n", getpid()); 1835 ATF_REQUIRE((child = fork()) != -1); 1836 if (child == 0) { 1837 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1838 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1839 1840 printf("Before raising %s from child\n", strsignal(sigval)); 1841 FORKEE_ASSERT(raise(sigval) == 0); 1842 1843 FORKEE_ASSERT_EQ(lookup_me, magic); 1844 1845 printf("Before exiting of the child process\n"); 1846 _exit(exitval); 1847 } 1848 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1849 1850 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1851 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1852 1853 validate_status_stopped(status, sigval); 1854 1855 lookup_me = magic; 1856 1857 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", 1858 child, getpid()); 1859 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1860 1861 printf("Before resuming the child process where it left off and " 1862 "without signal to be sent\n"); 1863 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1864 1865 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1866 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1867 1868 validate_status_exited(status, exitval); 1869 1870 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1871 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1872} 1873 1874ATF_TC(io_write_d3); 1875ATF_TC_HEAD(io_write_d3, tc) 1876{ 1877 atf_tc_set_md_var(tc, "descr", 1878 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)"); 1879} 1880 1881ATF_TC_BODY(io_write_d3, tc) 1882{ 1883 const int exitval = 5; 1884 const int sigval = SIGSTOP; 1885 pid_t child, wpid; 1886 uint32_t lookup_me = 0; 1887 const uint32_t magic = 0xab127643; 1888 struct ptrace_io_desc io = { 1889 .piod_op = PIOD_WRITE_D, 1890 .piod_offs = &lookup_me, 1891 .piod_addr = &lookup_me, 1892 .piod_len = sizeof(lookup_me) 1893 }; 1894#if defined(TWAIT_HAVE_STATUS) 1895 int status; 1896#endif 1897 1898 printf("Before forking process PID=%d\n", getpid()); 1899 ATF_REQUIRE((child = fork()) != -1); 1900 if (child == 0) { 1901 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1902 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1903 1904 printf("Before raising %s from child\n", strsignal(sigval)); 1905 FORKEE_ASSERT(raise(sigval) == 0); 1906 1907 FORKEE_ASSERT_EQ(lookup_me, magic); 1908 1909 printf("Before exiting of the child process\n"); 1910 _exit(exitval); 1911 } 1912 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1913 1914 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1915 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1916 1917 validate_status_stopped(status, sigval); 1918 1919 lookup_me = magic; 1920 1921 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", 1922 child, getpid()); 1923 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1924 1925 printf("Before resuming the child process where it left off and " 1926 "without signal to be sent\n"); 1927 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1928 1929 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1930 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1931 1932 validate_status_exited(status, exitval); 1933 1934 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1935 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1936} 1937 1938ATF_TC(io_write_d4); 1939ATF_TC_HEAD(io_write_d4, tc) 1940{ 1941 atf_tc_set_md_var(tc, "descr", 1942 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)"); 1943} 1944 1945ATF_TC_BODY(io_write_d4, tc) 1946{ 1947 const int exitval = 5; 1948 const int sigval = SIGSTOP; 1949 pid_t child, wpid; 1950 uint64_t lookup_me = 0; 1951 const uint64_t magic = 0xab12764376490123; 1952 struct ptrace_io_desc io = { 1953 .piod_op = PIOD_WRITE_D, 1954 .piod_offs = &lookup_me, 1955 .piod_addr = &lookup_me, 1956 .piod_len = sizeof(lookup_me) 1957 }; 1958#if defined(TWAIT_HAVE_STATUS) 1959 int status; 1960#endif 1961 1962 printf("Before forking process PID=%d\n", getpid()); 1963 ATF_REQUIRE((child = fork()) != -1); 1964 if (child == 0) { 1965 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1966 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1967 1968 printf("Before raising %s from child\n", strsignal(sigval)); 1969 FORKEE_ASSERT(raise(sigval) == 0); 1970 1971 FORKEE_ASSERT_EQ(lookup_me, magic); 1972 1973 printf("Before exiting of the child process\n"); 1974 _exit(exitval); 1975 } 1976 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1977 1978 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1979 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1980 1981 validate_status_stopped(status, sigval); 1982 1983 lookup_me = magic; 1984 1985 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", 1986 child, getpid()); 1987 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 1988 1989 printf("Before resuming the child process where it left off and " 1990 "without signal to be sent\n"); 1991 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1992 1993 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1994 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1995 1996 validate_status_exited(status, exitval); 1997 1998 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1999 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2000} 2001 2002ATF_TC(read_d1); 2003ATF_TC_HEAD(read_d1, tc) 2004{ 2005 atf_tc_set_md_var(tc, "descr", 2006 "Verify PT_READ_D called once"); 2007} 2008 2009ATF_TC_BODY(read_d1, tc) 2010{ 2011 const int exitval = 5; 2012 const int sigval = SIGSTOP; 2013 pid_t child, wpid; 2014 int lookup_me = 0; 2015 const int magic = (int)random(); 2016#if defined(TWAIT_HAVE_STATUS) 2017 int status; 2018#endif 2019 2020 printf("Before forking process PID=%d\n", getpid()); 2021 ATF_REQUIRE((child = fork()) != -1); 2022 if (child == 0) { 2023 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2024 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2025 2026 lookup_me = magic; 2027 2028 printf("Before raising %s from child\n", strsignal(sigval)); 2029 FORKEE_ASSERT(raise(sigval) == 0); 2030 2031 printf("Before exiting of the child process\n"); 2032 _exit(exitval); 2033 } 2034 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2035 2036 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2037 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2038 2039 validate_status_stopped(status, sigval); 2040 2041 printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 2042 child, getpid()); 2043 errno = 0; 2044 lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0); 2045 ATF_REQUIRE_EQ(errno, 0); 2046 2047 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 2048 "got value %#x != expected %#x", lookup_me, magic); 2049 2050 printf("Before resuming the child process where it left off and " 2051 "without signal to be sent\n"); 2052 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2053 2054 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2055 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2056 2057 validate_status_exited(status, exitval); 2058 2059 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2060 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2061} 2062 2063ATF_TC(read_d2); 2064ATF_TC_HEAD(read_d2, tc) 2065{ 2066 atf_tc_set_md_var(tc, "descr", 2067 "Verify PT_READ_D called twice"); 2068} 2069 2070ATF_TC_BODY(read_d2, tc) 2071{ 2072 const int exitval = 5; 2073 const int sigval = SIGSTOP; 2074 pid_t child, wpid; 2075 int lookup_me1 = 0; 2076 int lookup_me2 = 0; 2077 const int magic1 = (int)random(); 2078 const int magic2 = (int)random(); 2079#if defined(TWAIT_HAVE_STATUS) 2080 int status; 2081#endif 2082 2083 printf("Before forking process PID=%d\n", getpid()); 2084 ATF_REQUIRE((child = fork()) != -1); 2085 if (child == 0) { 2086 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2087 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2088 2089 lookup_me1 = magic1; 2090 lookup_me2 = magic2; 2091 2092 printf("Before raising %s from child\n", strsignal(sigval)); 2093 FORKEE_ASSERT(raise(sigval) == 0); 2094 2095 printf("Before exiting of the child process\n"); 2096 _exit(exitval); 2097 } 2098 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2099 2100 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2101 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2102 2103 validate_status_stopped(status, sigval); 2104 2105 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", 2106 child, getpid()); 2107 errno = 0; 2108 lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); 2109 ATF_REQUIRE_EQ(errno, 0); 2110 2111 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, 2112 "got value %#x != expected %#x", lookup_me1, magic1); 2113 2114 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", 2115 child, getpid()); 2116 errno = 0; 2117 lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); 2118 ATF_REQUIRE_EQ(errno, 0); 2119 2120 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, 2121 "got value %#x != expected %#x", lookup_me2, magic2); 2122 2123 printf("Before resuming the child process where it left off and " 2124 "without signal to be sent\n"); 2125 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2126 2127 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2128 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2129 2130 validate_status_exited(status, exitval); 2131 2132 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2133 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2134} 2135 2136ATF_TC(read_d3); 2137ATF_TC_HEAD(read_d3, tc) 2138{ 2139 atf_tc_set_md_var(tc, "descr", 2140 "Verify PT_READ_D called three times"); 2141} 2142 2143ATF_TC_BODY(read_d3, tc) 2144{ 2145 const int exitval = 5; 2146 const int sigval = SIGSTOP; 2147 pid_t child, wpid; 2148 int lookup_me1 = 0; 2149 int lookup_me2 = 0; 2150 int lookup_me3 = 0; 2151 const int magic1 = (int)random(); 2152 const int magic2 = (int)random(); 2153 const int magic3 = (int)random(); 2154#if defined(TWAIT_HAVE_STATUS) 2155 int status; 2156#endif 2157 2158 printf("Before forking process PID=%d\n", getpid()); 2159 ATF_REQUIRE((child = fork()) != -1); 2160 if (child == 0) { 2161 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2162 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2163 2164 lookup_me1 = magic1; 2165 lookup_me2 = magic2; 2166 lookup_me3 = magic3; 2167 2168 printf("Before raising %s from child\n", strsignal(sigval)); 2169 FORKEE_ASSERT(raise(sigval) == 0); 2170 2171 printf("Before exiting of the child process\n"); 2172 _exit(exitval); 2173 } 2174 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2175 2176 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2177 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2178 2179 validate_status_stopped(status, sigval); 2180 2181 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", 2182 child, getpid()); 2183 errno = 0; 2184 lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); 2185 ATF_REQUIRE_EQ(errno, 0); 2186 2187 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, 2188 "got value %#x != expected %#x", lookup_me1, magic1); 2189 2190 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", 2191 child, getpid()); 2192 errno = 0; 2193 lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); 2194 ATF_REQUIRE_EQ(errno, 0); 2195 2196 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, 2197 "got value %#x != expected %#x", lookup_me2, magic2); 2198 2199 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", 2200 child, getpid()); 2201 errno = 0; 2202 lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); 2203 ATF_REQUIRE_EQ(errno, 0); 2204 2205 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, 2206 "got value %#x != expected %#x", lookup_me3, magic3); 2207 2208 printf("Before resuming the child process where it left off and " 2209 "without signal to be sent\n"); 2210 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2211 2212 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2213 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2214 2215 validate_status_exited(status, exitval); 2216 2217 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2218 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2219} 2220 2221ATF_TC(read_d4); 2222ATF_TC_HEAD(read_d4, tc) 2223{ 2224 atf_tc_set_md_var(tc, "descr", 2225 "Verify PT_READ_D called four times"); 2226} 2227 2228ATF_TC_BODY(read_d4, tc) 2229{ 2230 const int exitval = 5; 2231 const int sigval = SIGSTOP; 2232 pid_t child, wpid; 2233 int lookup_me1 = 0; 2234 int lookup_me2 = 0; 2235 int lookup_me3 = 0; 2236 int lookup_me4 = 0; 2237 const int magic1 = (int)random(); 2238 const int magic2 = (int)random(); 2239 const int magic3 = (int)random(); 2240 const int magic4 = (int)random(); 2241#if defined(TWAIT_HAVE_STATUS) 2242 int status; 2243#endif 2244 2245 printf("Before forking process PID=%d\n", getpid()); 2246 ATF_REQUIRE((child = fork()) != -1); 2247 if (child == 0) { 2248 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2249 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2250 2251 lookup_me1 = magic1; 2252 lookup_me2 = magic2; 2253 lookup_me3 = magic3; 2254 lookup_me4 = magic4; 2255 2256 printf("Before raising %s from child\n", strsignal(sigval)); 2257 FORKEE_ASSERT(raise(sigval) == 0); 2258 2259 printf("Before exiting of the child process\n"); 2260 _exit(exitval); 2261 } 2262 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2263 2264 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2265 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2266 2267 validate_status_stopped(status, sigval); 2268 2269 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", 2270 child, getpid()); 2271 errno = 0; 2272 lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); 2273 ATF_REQUIRE_EQ(errno, 0); 2274 2275 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, 2276 "got value %#x != expected %#x", lookup_me1, magic1); 2277 2278 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", 2279 child, getpid()); 2280 errno = 0; 2281 lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); 2282 ATF_REQUIRE_EQ(errno, 0); 2283 2284 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, 2285 "got value %#x != expected %#x", lookup_me2, magic2); 2286 2287 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", 2288 child, getpid()); 2289 errno = 0; 2290 lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); 2291 ATF_REQUIRE_EQ(errno, 0); 2292 2293 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, 2294 "got value %#x != expected %#x", lookup_me3, magic3); 2295 2296 printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n", 2297 child, getpid()); 2298 errno = 0; 2299 lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0); 2300 ATF_REQUIRE_EQ(errno, 0); 2301 2302 ATF_REQUIRE_EQ_MSG(lookup_me4, magic4, 2303 "got value %#x != expected %#x", lookup_me4, magic4); 2304 2305 printf("Before resuming the child process where it left off and " 2306 "without signal to be sent\n"); 2307 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2308 2309 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2310 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2311 2312 validate_status_exited(status, exitval); 2313 2314 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2315 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2316} 2317 2318ATF_TC(write_d1); 2319ATF_TC_HEAD(write_d1, tc) 2320{ 2321 atf_tc_set_md_var(tc, "descr", 2322 "Verify PT_WRITE_D called once"); 2323} 2324 2325ATF_TC_BODY(write_d1, tc) 2326{ 2327 const int exitval = 5; 2328 const int sigval = SIGSTOP; 2329 pid_t child, wpid; 2330 int lookup_me = 0; 2331 const int magic = (int)random(); 2332#if defined(TWAIT_HAVE_STATUS) 2333 int status; 2334#endif 2335 2336 printf("Before forking process PID=%d\n", getpid()); 2337 ATF_REQUIRE((child = fork()) != -1); 2338 if (child == 0) { 2339 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2340 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2341 2342 printf("Before raising %s from child\n", strsignal(sigval)); 2343 FORKEE_ASSERT(raise(sigval) == 0); 2344 2345 FORKEE_ASSERT_EQ(lookup_me, magic); 2346 2347 printf("Before exiting of the child process\n"); 2348 _exit(exitval); 2349 } 2350 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2351 2352 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2353 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2354 2355 validate_status_stopped(status, sigval); 2356 2357 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", 2358 child, getpid()); 2359 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1); 2360 2361 printf("Before resuming the child process where it left off and " 2362 "without signal to be sent\n"); 2363 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2364 2365 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2366 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2367 2368 validate_status_exited(status, exitval); 2369 2370 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2371 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2372} 2373 2374ATF_TC(write_d2); 2375ATF_TC_HEAD(write_d2, tc) 2376{ 2377 atf_tc_set_md_var(tc, "descr", 2378 "Verify PT_WRITE_D called twice"); 2379} 2380 2381ATF_TC_BODY(write_d2, tc) 2382{ 2383 const int exitval = 5; 2384 const int sigval = SIGSTOP; 2385 pid_t child, wpid; 2386 int lookup_me1 = 0; 2387 int lookup_me2 = 0; 2388 const int magic1 = (int)random(); 2389 const int magic2 = (int)random(); 2390#if defined(TWAIT_HAVE_STATUS) 2391 int status; 2392#endif 2393 2394 printf("Before forking process PID=%d\n", getpid()); 2395 ATF_REQUIRE((child = fork()) != -1); 2396 if (child == 0) { 2397 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2398 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2399 2400 printf("Before raising %s from child\n", strsignal(sigval)); 2401 FORKEE_ASSERT(raise(sigval) == 0); 2402 2403 FORKEE_ASSERT_EQ(lookup_me1, magic1); 2404 FORKEE_ASSERT_EQ(lookup_me2, magic2); 2405 2406 printf("Before exiting of the child process\n"); 2407 _exit(exitval); 2408 } 2409 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2410 2411 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2412 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2413 2414 validate_status_stopped(status, sigval); 2415 2416 printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", 2417 child, getpid()); 2418 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); 2419 2420 printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", 2421 child, getpid()); 2422 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); 2423 2424 printf("Before resuming the child process where it left off and " 2425 "without signal to be sent\n"); 2426 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2427 2428 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2429 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2430 2431 validate_status_exited(status, exitval); 2432 2433 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2434 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2435} 2436 2437ATF_TC(write_d3); 2438ATF_TC_HEAD(write_d3, tc) 2439{ 2440 atf_tc_set_md_var(tc, "descr", 2441 "Verify PT_WRITE_D called three times"); 2442} 2443 2444ATF_TC_BODY(write_d3, tc) 2445{ 2446 const int exitval = 5; 2447 const int sigval = SIGSTOP; 2448 pid_t child, wpid; 2449 int lookup_me1 = 0; 2450 int lookup_me2 = 0; 2451 int lookup_me3 = 0; 2452 const int magic1 = (int)random(); 2453 const int magic2 = (int)random(); 2454 const int magic3 = (int)random(); 2455#if defined(TWAIT_HAVE_STATUS) 2456 int status; 2457#endif 2458 2459 printf("Before forking process PID=%d\n", getpid()); 2460 ATF_REQUIRE((child = fork()) != -1); 2461 if (child == 0) { 2462 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2463 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2464 2465 printf("Before raising %s from child\n", strsignal(sigval)); 2466 FORKEE_ASSERT(raise(sigval) == 0); 2467 2468 FORKEE_ASSERT_EQ(lookup_me1, magic1); 2469 FORKEE_ASSERT_EQ(lookup_me2, magic2); 2470 FORKEE_ASSERT_EQ(lookup_me3, magic3); 2471 2472 printf("Before exiting of the child process\n"); 2473 _exit(exitval); 2474 } 2475 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2476 2477 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2478 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2479 2480 validate_status_stopped(status, sigval); 2481 2482 printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", 2483 child, getpid()); 2484 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); 2485 2486 printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", 2487 child, getpid()); 2488 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); 2489 2490 printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", 2491 child, getpid()); 2492 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); 2493 2494 printf("Before resuming the child process where it left off and " 2495 "without signal to be sent\n"); 2496 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2497 2498 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2499 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2500 2501 validate_status_exited(status, exitval); 2502 2503 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2504 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2505} 2506 2507ATF_TC(write_d4); 2508ATF_TC_HEAD(write_d4, tc) 2509{ 2510 atf_tc_set_md_var(tc, "descr", 2511 "Verify PT_WRITE_D called four times"); 2512} 2513 2514ATF_TC_BODY(write_d4, tc) 2515{ 2516 const int exitval = 5; 2517 const int sigval = SIGSTOP; 2518 pid_t child, wpid; 2519 int lookup_me1 = 0; 2520 int lookup_me2 = 0; 2521 int lookup_me3 = 0; 2522 int lookup_me4 = 0; 2523 const int magic1 = (int)random(); 2524 const int magic2 = (int)random(); 2525 const int magic3 = (int)random(); 2526 const int magic4 = (int)random(); 2527#if defined(TWAIT_HAVE_STATUS) 2528 int status; 2529#endif 2530 2531 printf("Before forking process PID=%d\n", getpid()); 2532 ATF_REQUIRE((child = fork()) != -1); 2533 if (child == 0) { 2534 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2535 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2536 2537 printf("Before raising %s from child\n", strsignal(sigval)); 2538 FORKEE_ASSERT(raise(sigval) == 0); 2539 2540 FORKEE_ASSERT_EQ(lookup_me1, magic1); 2541 FORKEE_ASSERT_EQ(lookup_me2, magic2); 2542 FORKEE_ASSERT_EQ(lookup_me3, magic3); 2543 FORKEE_ASSERT_EQ(lookup_me4, magic4); 2544 2545 printf("Before exiting of the child process\n"); 2546 _exit(exitval); 2547 } 2548 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2549 2550 printf("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 printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", 2556 child, getpid()); 2557 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); 2558 2559 printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", 2560 child, getpid()); 2561 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); 2562 2563 printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", 2564 child, getpid()); 2565 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); 2566 2567 printf("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n", 2568 child, getpid()); 2569 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1); 2570 2571 printf("Before resuming the child process where it left off and " 2572 "without signal to be sent\n"); 2573 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2574 2575 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2576 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2577 2578 validate_status_exited(status, exitval); 2579 2580 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2581 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2582} 2583 2584ATF_TC(io_read_d_write_d_handshake1); 2585ATF_TC_HEAD(io_read_d_write_d_handshake1, tc) 2586{ 2587 atf_tc_set_md_var(tc, "descr", 2588 "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake"); 2589} 2590 2591ATF_TC_BODY(io_read_d_write_d_handshake1, tc) 2592{ 2593 const int exitval = 5; 2594 const int sigval = SIGSTOP; 2595 pid_t child, wpid; 2596 uint8_t lookup_me_fromtracee = 0; 2597 const uint8_t magic_fromtracee = (uint8_t)random(); 2598 uint8_t lookup_me_totracee = 0; 2599 const uint8_t magic_totracee = (uint8_t)random(); 2600 struct ptrace_io_desc io_fromtracee = { 2601 .piod_op = PIOD_READ_D, 2602 .piod_offs = &lookup_me_fromtracee, 2603 .piod_addr = &lookup_me_fromtracee, 2604 .piod_len = sizeof(lookup_me_fromtracee) 2605 }; 2606 struct ptrace_io_desc io_totracee = { 2607 .piod_op = PIOD_WRITE_D, 2608 .piod_offs = &lookup_me_totracee, 2609 .piod_addr = &lookup_me_totracee, 2610 .piod_len = sizeof(lookup_me_totracee) 2611 }; 2612#if defined(TWAIT_HAVE_STATUS) 2613 int status; 2614#endif 2615 2616 printf("Before forking process PID=%d\n", getpid()); 2617 ATF_REQUIRE((child = fork()) != -1); 2618 if (child == 0) { 2619 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2620 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2621 2622 lookup_me_fromtracee = magic_fromtracee; 2623 2624 printf("Before raising %s from child\n", strsignal(sigval)); 2625 FORKEE_ASSERT(raise(sigval) == 0); 2626 2627 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); 2628 2629 printf("Before exiting of the child process\n"); 2630 _exit(exitval); 2631 } 2632 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2633 2634 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2635 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2636 2637 validate_status_stopped(status, sigval); 2638 2639 printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", 2640 child, getpid()); 2641 ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); 2642 2643 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, 2644 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, 2645 magic_fromtracee); 2646 2647 lookup_me_totracee = magic_totracee; 2648 2649 printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", 2650 child, getpid()); 2651 ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); 2652 2653 ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, 2654 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, 2655 magic_totracee); 2656 2657 printf("Before resuming the child process where it left off and " 2658 "without signal to be sent\n"); 2659 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2660 2661 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2662 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2663 2664 validate_status_exited(status, exitval); 2665 2666 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2667 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2668} 2669 2670ATF_TC(io_read_d_write_d_handshake2); 2671ATF_TC_HEAD(io_read_d_write_d_handshake2, tc) 2672{ 2673 atf_tc_set_md_var(tc, "descr", 2674 "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake"); 2675} 2676 2677ATF_TC_BODY(io_read_d_write_d_handshake2, tc) 2678{ 2679 const int exitval = 5; 2680 const int sigval = SIGSTOP; 2681 pid_t child, wpid; 2682 uint8_t lookup_me_fromtracee = 0; 2683 const uint8_t magic_fromtracee = (uint8_t)random(); 2684 uint8_t lookup_me_totracee = 0; 2685 const uint8_t magic_totracee = (uint8_t)random(); 2686 struct ptrace_io_desc io_fromtracee = { 2687 .piod_op = PIOD_READ_D, 2688 .piod_offs = &lookup_me_fromtracee, 2689 .piod_addr = &lookup_me_fromtracee, 2690 .piod_len = sizeof(lookup_me_fromtracee) 2691 }; 2692 struct ptrace_io_desc io_totracee = { 2693 .piod_op = PIOD_WRITE_D, 2694 .piod_offs = &lookup_me_totracee, 2695 .piod_addr = &lookup_me_totracee, 2696 .piod_len = sizeof(lookup_me_totracee) 2697 }; 2698#if defined(TWAIT_HAVE_STATUS) 2699 int status; 2700#endif 2701 2702 printf("Before forking process PID=%d\n", getpid()); 2703 ATF_REQUIRE((child = fork()) != -1); 2704 if (child == 0) { 2705 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2706 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2707 2708 lookup_me_fromtracee = magic_fromtracee; 2709 2710 printf("Before raising %s from child\n", strsignal(sigval)); 2711 FORKEE_ASSERT(raise(sigval) == 0); 2712 2713 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); 2714 2715 printf("Before exiting of the child process\n"); 2716 _exit(exitval); 2717 } 2718 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2719 2720 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2721 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2722 2723 validate_status_stopped(status, sigval); 2724 2725 lookup_me_totracee = magic_totracee; 2726 2727 printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", 2728 child, getpid()); 2729 ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); 2730 2731 ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, 2732 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, 2733 magic_totracee); 2734 2735 printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", 2736 child, getpid()); 2737 ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); 2738 2739 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, 2740 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, 2741 magic_fromtracee); 2742 2743 printf("Before resuming the child process where it left off and " 2744 "without signal to be sent\n"); 2745 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2746 2747 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2748 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2749 2750 validate_status_exited(status, exitval); 2751 2752 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2753 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2754} 2755 2756ATF_TC(read_d_write_d_handshake1); 2757ATF_TC_HEAD(read_d_write_d_handshake1, tc) 2758{ 2759 atf_tc_set_md_var(tc, "descr", 2760 "Verify PT_READ_D with PT_WRITE_D handshake"); 2761} 2762 2763ATF_TC_BODY(read_d_write_d_handshake1, tc) 2764{ 2765 const int exitval = 5; 2766 const int sigval = SIGSTOP; 2767 pid_t child, wpid; 2768 int lookup_me_fromtracee = 0; 2769 const int magic_fromtracee = (int)random(); 2770 int lookup_me_totracee = 0; 2771 const int magic_totracee = (int)random(); 2772#if defined(TWAIT_HAVE_STATUS) 2773 int status; 2774#endif 2775 2776 printf("Before forking process PID=%d\n", getpid()); 2777 ATF_REQUIRE((child = fork()) != -1); 2778 if (child == 0) { 2779 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2780 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2781 2782 lookup_me_fromtracee = magic_fromtracee; 2783 2784 printf("Before raising %s from child\n", strsignal(sigval)); 2785 FORKEE_ASSERT(raise(sigval) == 0); 2786 2787 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); 2788 2789 printf("Before exiting of the child process\n"); 2790 _exit(exitval); 2791 } 2792 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2793 2794 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2795 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2796 2797 validate_status_stopped(status, sigval); 2798 2799 printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", 2800 child, getpid()); 2801 errno = 0; 2802 lookup_me_fromtracee = 2803 ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); 2804 ATF_REQUIRE_EQ(errno, 0); 2805 2806 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, 2807 "got value %#x != expected %#x", lookup_me_fromtracee, 2808 magic_fromtracee); 2809 2810 printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", 2811 child, getpid()); 2812 ATF_REQUIRE 2813 (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) 2814 != -1); 2815 2816 printf("Before resuming the child process where it left off and " 2817 "without signal to be sent\n"); 2818 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2819 2820 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2821 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2822 2823 validate_status_exited(status, exitval); 2824 2825 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2826 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2827} 2828 2829ATF_TC(read_d_write_d_handshake2); 2830ATF_TC_HEAD(read_d_write_d_handshake2, tc) 2831{ 2832 atf_tc_set_md_var(tc, "descr", 2833 "Verify PT_WRITE_D with PT_READ_D handshake"); 2834} 2835 2836ATF_TC_BODY(read_d_write_d_handshake2, tc) 2837{ 2838 const int exitval = 5; 2839 const int sigval = SIGSTOP; 2840 pid_t child, wpid; 2841 int lookup_me_fromtracee = 0; 2842 const int magic_fromtracee = (int)random(); 2843 int lookup_me_totracee = 0; 2844 const int magic_totracee = (int)random(); 2845#if defined(TWAIT_HAVE_STATUS) 2846 int status; 2847#endif 2848 2849 printf("Before forking process PID=%d\n", getpid()); 2850 ATF_REQUIRE((child = fork()) != -1); 2851 if (child == 0) { 2852 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2853 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2854 2855 lookup_me_fromtracee = magic_fromtracee; 2856 2857 printf("Before raising %s from child\n", strsignal(sigval)); 2858 FORKEE_ASSERT(raise(sigval) == 0); 2859 2860 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); 2861 2862 printf("Before exiting of the child process\n"); 2863 _exit(exitval); 2864 } 2865 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2866 2867 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2868 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2869 2870 validate_status_stopped(status, sigval); 2871 2872 printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", 2873 child, getpid()); 2874 ATF_REQUIRE 2875 (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) 2876 != -1); 2877 2878 printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", 2879 child, getpid()); 2880 errno = 0; 2881 lookup_me_fromtracee = 2882 ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); 2883 ATF_REQUIRE_EQ(errno, 0); 2884 2885 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, 2886 "got value %#x != expected %#x", lookup_me_fromtracee, 2887 magic_fromtracee); 2888 2889 printf("Before resuming the child process where it left off and " 2890 "without signal to be sent\n"); 2891 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2892 2893 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2894 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2895 2896 validate_status_exited(status, exitval); 2897 2898 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2899 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2900} 2901 2902/* These dummy functions are used to be copied with ptrace(2) calls */ 2903static int __used 2904dummy_fn1(int a, int b, int c, int d) 2905{ 2906 2907 a *= 1; 2908 b += 2; 2909 c -= 3; 2910 d /= 4; 2911 2912 return a + b * c - d; 2913} 2914 2915static int __used 2916dummy_fn2(int a, int b, int c, int d) 2917{ 2918 2919 a *= 4; 2920 b += 3; 2921 c -= 2; 2922 d /= 1; 2923 2924 return a + b * c - d; 2925} 2926 2927static int __used 2928dummy_fn3(int a, int b, int c, int d) 2929{ 2930 2931 a *= 10; 2932 b += 20; 2933 c -= 30; 2934 d /= 40; 2935 2936 return a + b * c - d; 2937} 2938 2939static int __used 2940dummy_fn4(int a, int b, int c, int d) 2941{ 2942 2943 a *= 40; 2944 b += 30; 2945 c -= 20; 2946 d /= 10; 2947 2948 return a + b * c - d; 2949} 2950 2951ATF_TC(io_read_i1); 2952ATF_TC_HEAD(io_read_i1, tc) 2953{ 2954 atf_tc_set_md_var(tc, "descr", 2955 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)"); 2956} 2957 2958ATF_TC_BODY(io_read_i1, tc) 2959{ 2960 const int exitval = 5; 2961 const int sigval = SIGSTOP; 2962 pid_t child, wpid; 2963 uint8_t lookup_me = 0; 2964 uint8_t magic; 2965 memcpy(&magic, dummy_fn1, sizeof(magic)); 2966 struct ptrace_io_desc io = { 2967 .piod_op = PIOD_READ_I, 2968 .piod_offs = dummy_fn1, 2969 .piod_addr = &lookup_me, 2970 .piod_len = sizeof(lookup_me) 2971 }; 2972#if defined(TWAIT_HAVE_STATUS) 2973 int status; 2974#endif 2975 2976 printf("Before forking process PID=%d\n", getpid()); 2977 ATF_REQUIRE((child = fork()) != -1); 2978 if (child == 0) { 2979 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 2980 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2981 2982 printf("Before raising %s from child\n", strsignal(sigval)); 2983 FORKEE_ASSERT(raise(sigval) == 0); 2984 2985 printf("Before exiting of the child process\n"); 2986 _exit(exitval); 2987 } 2988 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2989 2990 printf("Before calling %s() for the child\n", TWAIT_FNAME); 2991 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2992 2993 validate_status_stopped(status, sigval); 2994 2995 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 2996 child, getpid()); 2997 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 2998 2999 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 3000 "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); 3001 3002 printf("Before resuming the child process where it left off and " 3003 "without signal to be sent\n"); 3004 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3005 3006 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3007 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3008 3009 validate_status_exited(status, exitval); 3010 3011 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3012 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3013} 3014 3015ATF_TC(io_read_i2); 3016ATF_TC_HEAD(io_read_i2, tc) 3017{ 3018 atf_tc_set_md_var(tc, "descr", 3019 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)"); 3020} 3021 3022ATF_TC_BODY(io_read_i2, tc) 3023{ 3024 const int exitval = 5; 3025 const int sigval = SIGSTOP; 3026 pid_t child, wpid; 3027 uint16_t lookup_me = 0; 3028 uint16_t magic; 3029 memcpy(&magic, dummy_fn1, sizeof(magic)); 3030 struct ptrace_io_desc io = { 3031 .piod_op = PIOD_READ_I, 3032 .piod_offs = dummy_fn1, 3033 .piod_addr = &lookup_me, 3034 .piod_len = sizeof(lookup_me) 3035 }; 3036#if defined(TWAIT_HAVE_STATUS) 3037 int status; 3038#endif 3039 3040 printf("Before forking process PID=%d\n", getpid()); 3041 ATF_REQUIRE((child = fork()) != -1); 3042 if (child == 0) { 3043 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3044 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3045 3046 printf("Before raising %s from child\n", strsignal(sigval)); 3047 FORKEE_ASSERT(raise(sigval) == 0); 3048 3049 printf("Before exiting of the child process\n"); 3050 _exit(exitval); 3051 } 3052 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3053 3054 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3055 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3056 3057 validate_status_stopped(status, sigval); 3058 3059 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 3060 child, getpid()); 3061 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 3062 3063 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 3064 "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic); 3065 3066 printf("Before resuming the child process where it left off and " 3067 "without signal to be sent\n"); 3068 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3069 3070 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3071 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3072 3073 validate_status_exited(status, exitval); 3074 3075 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3076 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3077} 3078 3079ATF_TC(io_read_i3); 3080ATF_TC_HEAD(io_read_i3, tc) 3081{ 3082 atf_tc_set_md_var(tc, "descr", 3083 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)"); 3084} 3085 3086ATF_TC_BODY(io_read_i3, tc) 3087{ 3088 const int exitval = 5; 3089 const int sigval = SIGSTOP; 3090 pid_t child, wpid; 3091 uint32_t lookup_me = 0; 3092 uint32_t magic; 3093 memcpy(&magic, dummy_fn1, sizeof(magic)); 3094 struct ptrace_io_desc io = { 3095 .piod_op = PIOD_READ_I, 3096 .piod_offs = dummy_fn1, 3097 .piod_addr = &lookup_me, 3098 .piod_len = sizeof(lookup_me) 3099 }; 3100#if defined(TWAIT_HAVE_STATUS) 3101 int status; 3102#endif 3103 3104 printf("Before forking process PID=%d\n", getpid()); 3105 ATF_REQUIRE((child = fork()) != -1); 3106 if (child == 0) { 3107 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3108 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3109 3110 printf("Before raising %s from child\n", strsignal(sigval)); 3111 FORKEE_ASSERT(raise(sigval) == 0); 3112 3113 printf("Before exiting of the child process\n"); 3114 _exit(exitval); 3115 } 3116 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3117 3118 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3119 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3120 3121 validate_status_stopped(status, sigval); 3122 3123 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 3124 child, getpid()); 3125 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 3126 3127 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 3128 "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic); 3129 3130 printf("Before resuming the child process where it left off and " 3131 "without signal to be sent\n"); 3132 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3133 3134 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3135 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3136 3137 validate_status_exited(status, exitval); 3138 3139 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3140 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3141} 3142 3143ATF_TC(io_read_i4); 3144ATF_TC_HEAD(io_read_i4, tc) 3145{ 3146 atf_tc_set_md_var(tc, "descr", 3147 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)"); 3148} 3149 3150ATF_TC_BODY(io_read_i4, tc) 3151{ 3152 const int exitval = 5; 3153 const int sigval = SIGSTOP; 3154 pid_t child, wpid; 3155 uint64_t lookup_me = 0; 3156 uint64_t magic; 3157 memcpy(&magic, dummy_fn1, sizeof(magic)); 3158 struct ptrace_io_desc io = { 3159 .piod_op = PIOD_READ_I, 3160 .piod_offs = dummy_fn1, 3161 .piod_addr = &lookup_me, 3162 .piod_len = sizeof(lookup_me) 3163 }; 3164#if defined(TWAIT_HAVE_STATUS) 3165 int status; 3166#endif 3167 3168 printf("Before forking process PID=%d\n", getpid()); 3169 ATF_REQUIRE((child = fork()) != -1); 3170 if (child == 0) { 3171 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3172 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3173 3174 printf("Before raising %s from child\n", strsignal(sigval)); 3175 FORKEE_ASSERT(raise(sigval) == 0); 3176 3177 printf("Before exiting of the child process\n"); 3178 _exit(exitval); 3179 } 3180 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3181 3182 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3183 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3184 3185 validate_status_stopped(status, sigval); 3186 3187 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 3188 child, getpid()); 3189 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 3190 3191 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 3192 "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic); 3193 3194 printf("Before resuming the child process where it left off and " 3195 "without signal to be sent\n"); 3196 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3197 3198 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3199 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3200 3201 validate_status_exited(status, exitval); 3202 3203 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3204 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3205} 3206 3207ATF_TC(read_i1); 3208ATF_TC_HEAD(read_i1, tc) 3209{ 3210 atf_tc_set_md_var(tc, "descr", 3211 "Verify PT_READ_I called once"); 3212} 3213 3214ATF_TC_BODY(read_i1, tc) 3215{ 3216 const int exitval = 5; 3217 const int sigval = SIGSTOP; 3218 pid_t child, wpid; 3219 int lookup_me = 0; 3220 int magic; 3221 memcpy(&magic, dummy_fn1, sizeof(magic)); 3222#if defined(TWAIT_HAVE_STATUS) 3223 int status; 3224#endif 3225 3226 printf("Before forking process PID=%d\n", getpid()); 3227 ATF_REQUIRE((child = fork()) != -1); 3228 if (child == 0) { 3229 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3230 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3231 3232 printf("Before raising %s from child\n", strsignal(sigval)); 3233 FORKEE_ASSERT(raise(sigval) == 0); 3234 3235 printf("Before exiting of the child process\n"); 3236 _exit(exitval); 3237 } 3238 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3239 3240 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3241 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3242 3243 validate_status_stopped(status, sigval); 3244 3245 printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", 3246 child, getpid()); 3247 errno = 0; 3248 lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0); 3249 ATF_REQUIRE_EQ(errno, 0); 3250 3251 ATF_REQUIRE_EQ_MSG(lookup_me, magic, 3252 "got value %#x != expected %#x", lookup_me, magic); 3253 3254 printf("Before resuming the child process where it left off and " 3255 "without signal to be sent\n"); 3256 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3257 3258 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3259 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3260 3261 validate_status_exited(status, exitval); 3262 3263 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3264 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3265} 3266 3267ATF_TC(read_i2); 3268ATF_TC_HEAD(read_i2, tc) 3269{ 3270 atf_tc_set_md_var(tc, "descr", 3271 "Verify PT_READ_I called twice"); 3272} 3273 3274ATF_TC_BODY(read_i2, tc) 3275{ 3276 const int exitval = 5; 3277 const int sigval = SIGSTOP; 3278 pid_t child, wpid; 3279 int lookup_me1 = 0; 3280 int lookup_me2 = 0; 3281 int magic1; 3282 int magic2; 3283 memcpy(&magic1, dummy_fn1, sizeof(magic1)); 3284 memcpy(&magic2, dummy_fn2, sizeof(magic2)); 3285#if defined(TWAIT_HAVE_STATUS) 3286 int status; 3287#endif 3288 3289 printf("Before forking process PID=%d\n", getpid()); 3290 ATF_REQUIRE((child = fork()) != -1); 3291 if (child == 0) { 3292 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3293 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3294 3295 printf("Before raising %s from child\n", strsignal(sigval)); 3296 FORKEE_ASSERT(raise(sigval) == 0); 3297 3298 printf("Before exiting of the child process\n"); 3299 _exit(exitval); 3300 } 3301 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3302 3303 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3304 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3305 3306 validate_status_stopped(status, sigval); 3307 3308 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", 3309 child, getpid()); 3310 errno = 0; 3311 lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0); 3312 ATF_REQUIRE_EQ(errno, 0); 3313 3314 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, 3315 "got value %#x != expected %#x", lookup_me1, magic1); 3316 3317 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", 3318 child, getpid()); 3319 errno = 0; 3320 lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0); 3321 ATF_REQUIRE_EQ(errno, 0); 3322 3323 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, 3324 "got value %#x != expected %#x", lookup_me2, magic2); 3325 3326 printf("Before resuming the child process where it left off and " 3327 "without signal to be sent\n"); 3328 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3329 3330 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3331 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3332 3333 validate_status_exited(status, exitval); 3334 3335 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3336 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3337} 3338 3339ATF_TC(read_i3); 3340ATF_TC_HEAD(read_i3, tc) 3341{ 3342 atf_tc_set_md_var(tc, "descr", 3343 "Verify PT_READ_I called three times"); 3344} 3345 3346ATF_TC_BODY(read_i3, tc) 3347{ 3348 const int exitval = 5; 3349 const int sigval = SIGSTOP; 3350 pid_t child, wpid; 3351 int lookup_me1 = 0; 3352 int lookup_me2 = 0; 3353 int lookup_me3 = 0; 3354 int magic1; 3355 int magic2; 3356 int magic3; 3357 memcpy(&magic1, dummy_fn1, sizeof(magic1)); 3358 memcpy(&magic2, dummy_fn2, sizeof(magic2)); 3359 memcpy(&magic3, dummy_fn3, sizeof(magic3)); 3360#if defined(TWAIT_HAVE_STATUS) 3361 int status; 3362#endif 3363 3364 printf("Before forking process PID=%d\n", getpid()); 3365 ATF_REQUIRE((child = fork()) != -1); 3366 if (child == 0) { 3367 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3368 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3369 3370 printf("Before raising %s from child\n", strsignal(sigval)); 3371 FORKEE_ASSERT(raise(sigval) == 0); 3372 3373 printf("Before exiting of the child process\n"); 3374 _exit(exitval); 3375 } 3376 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3377 3378 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3379 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3380 3381 validate_status_stopped(status, sigval); 3382 3383 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", 3384 child, getpid()); 3385 errno = 0; 3386 lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0); 3387 ATF_REQUIRE_EQ(errno, 0); 3388 3389 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, 3390 "got value %#x != expected %#x", lookup_me1, magic1); 3391 3392 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", 3393 child, getpid()); 3394 errno = 0; 3395 lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0); 3396 ATF_REQUIRE_EQ(errno, 0); 3397 3398 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, 3399 "got value %#x != expected %#x", lookup_me2, magic2); 3400 3401 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", 3402 child, getpid()); 3403 errno = 0; 3404 lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0); 3405 ATF_REQUIRE_EQ(errno, 0); 3406 3407 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, 3408 "got value %#x != expected %#x", lookup_me3, magic3); 3409 3410 printf("Before resuming the child process where it left off and " 3411 "without signal to be sent\n"); 3412 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3413 3414 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3415 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3416 3417 validate_status_exited(status, exitval); 3418 3419 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3420 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3421} 3422 3423ATF_TC(read_i4); 3424ATF_TC_HEAD(read_i4, tc) 3425{ 3426 atf_tc_set_md_var(tc, "descr", 3427 "Verify PT_READ_I called four times"); 3428} 3429 3430ATF_TC_BODY(read_i4, tc) 3431{ 3432 const int exitval = 5; 3433 const int sigval = SIGSTOP; 3434 pid_t child, wpid; 3435 int lookup_me1 = 0; 3436 int lookup_me2 = 0; 3437 int lookup_me3 = 0; 3438 int lookup_me4 = 0; 3439 int magic1; 3440 int magic2; 3441 int magic3; 3442 int magic4; 3443 memcpy(&magic1, dummy_fn1, sizeof(magic1)); 3444 memcpy(&magic2, dummy_fn2, sizeof(magic2)); 3445 memcpy(&magic3, dummy_fn3, sizeof(magic3)); 3446 memcpy(&magic4, dummy_fn4, sizeof(magic4)); 3447#if defined(TWAIT_HAVE_STATUS) 3448 int status; 3449#endif 3450 3451 printf("Before forking process PID=%d\n", getpid()); 3452 ATF_REQUIRE((child = fork()) != -1); 3453 if (child == 0) { 3454 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3455 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3456 3457 printf("Before raising %s from child\n", strsignal(sigval)); 3458 FORKEE_ASSERT(raise(sigval) == 0); 3459 3460 printf("Before exiting of the child process\n"); 3461 _exit(exitval); 3462 } 3463 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3464 3465 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3466 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3467 3468 validate_status_stopped(status, sigval); 3469 3470 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", 3471 child, getpid()); 3472 errno = 0; 3473 lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0); 3474 ATF_REQUIRE_EQ(errno, 0); 3475 3476 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, 3477 "got value %#x != expected %#x", lookup_me1, magic1); 3478 3479 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", 3480 child, getpid()); 3481 errno = 0; 3482 lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0); 3483 ATF_REQUIRE_EQ(errno, 0); 3484 3485 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, 3486 "got value %#x != expected %#x", lookup_me2, magic2); 3487 3488 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", 3489 child, getpid()); 3490 errno = 0; 3491 lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0); 3492 ATF_REQUIRE_EQ(errno, 0); 3493 3494 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, 3495 "got value %#x != expected %#x", lookup_me3, magic3); 3496 3497 printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n", 3498 child, getpid()); 3499 errno = 0; 3500 lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0); 3501 ATF_REQUIRE_EQ(errno, 0); 3502 3503 ATF_REQUIRE_EQ_MSG(lookup_me4, magic4, 3504 "got value %#x != expected %#x", lookup_me4, magic4); 3505 3506 printf("Before resuming the child process where it left off and " 3507 "without signal to be sent\n"); 3508 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3509 3510 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3511 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3512 3513 validate_status_exited(status, exitval); 3514 3515 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3516 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3517} 3518 3519#if defined(HAVE_GPREGS) 3520ATF_TC(regs1); 3521ATF_TC_HEAD(regs1, tc) 3522{ 3523 atf_tc_set_md_var(tc, "descr", 3524 "Verify plain PT_GETREGS call without further steps"); 3525} 3526 3527ATF_TC_BODY(regs1, tc) 3528{ 3529 const int exitval = 5; 3530 const int sigval = SIGSTOP; 3531 pid_t child, wpid; 3532#if defined(TWAIT_HAVE_STATUS) 3533 int status; 3534#endif 3535 struct reg r; 3536 3537 printf("Before forking process PID=%d\n", getpid()); 3538 ATF_REQUIRE((child = fork()) != -1); 3539 if (child == 0) { 3540 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3541 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3542 3543 printf("Before raising %s from child\n", strsignal(sigval)); 3544 FORKEE_ASSERT(raise(sigval) == 0); 3545 3546 printf("Before exiting of the child process\n"); 3547 _exit(exitval); 3548 } 3549 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3550 3551 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3552 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3553 3554 validate_status_stopped(status, sigval); 3555 3556 printf("Call GETREGS for the child process\n"); 3557 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 3558 3559 printf("Before resuming the child process where it left off and " 3560 "without signal to be sent\n"); 3561 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3562 3563 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3564 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3565 3566 validate_status_exited(status, exitval); 3567 3568 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3569 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3570} 3571#endif 3572 3573#if defined(HAVE_GPREGS) 3574ATF_TC(regs2); 3575ATF_TC_HEAD(regs2, tc) 3576{ 3577 atf_tc_set_md_var(tc, "descr", 3578 "Verify plain PT_GETREGS call and retrieve PC"); 3579} 3580 3581ATF_TC_BODY(regs2, tc) 3582{ 3583 const int exitval = 5; 3584 const int sigval = SIGSTOP; 3585 pid_t child, wpid; 3586#if defined(TWAIT_HAVE_STATUS) 3587 int status; 3588#endif 3589 struct reg r; 3590 3591 printf("Before forking process PID=%d\n", getpid()); 3592 ATF_REQUIRE((child = fork()) != -1); 3593 if (child == 0) { 3594 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3595 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3596 3597 printf("Before raising %s from child\n", strsignal(sigval)); 3598 FORKEE_ASSERT(raise(sigval) == 0); 3599 3600 printf("Before exiting of the child process\n"); 3601 _exit(exitval); 3602 } 3603 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3604 3605 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3606 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3607 3608 validate_status_stopped(status, sigval); 3609 3610 printf("Call GETREGS for the child process\n"); 3611 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 3612 3613 printf("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r)); 3614 3615 printf("Before resuming the child process where it left off and " 3616 "without signal to be sent\n"); 3617 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3618 3619 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3620 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3621 3622 validate_status_exited(status, exitval); 3623 3624 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3625 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3626} 3627#endif 3628 3629#if defined(HAVE_GPREGS) 3630ATF_TC(regs3); 3631ATF_TC_HEAD(regs3, tc) 3632{ 3633 atf_tc_set_md_var(tc, "descr", 3634 "Verify plain PT_GETREGS call and retrieve SP"); 3635} 3636 3637ATF_TC_BODY(regs3, tc) 3638{ 3639 const int exitval = 5; 3640 const int sigval = SIGSTOP; 3641 pid_t child, wpid; 3642#if defined(TWAIT_HAVE_STATUS) 3643 int status; 3644#endif 3645 struct reg r; 3646 3647 printf("Before forking process PID=%d\n", getpid()); 3648 ATF_REQUIRE((child = fork()) != -1); 3649 if (child == 0) { 3650 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3651 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3652 3653 printf("Before raising %s from child\n", strsignal(sigval)); 3654 FORKEE_ASSERT(raise(sigval) == 0); 3655 3656 printf("Before exiting of the child process\n"); 3657 _exit(exitval); 3658 } 3659 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3660 3661 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3662 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3663 3664 validate_status_stopped(status, sigval); 3665 3666 printf("Call GETREGS for the child process\n"); 3667 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 3668 3669 printf("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r)); 3670 3671 printf("Before resuming the child process where it left off and " 3672 "without signal to be sent\n"); 3673 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3674 3675 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3676 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3677 3678 validate_status_exited(status, exitval); 3679 3680 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3681 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3682} 3683#endif 3684 3685#if defined(HAVE_GPREGS) 3686ATF_TC(regs4); 3687ATF_TC_HEAD(regs4, tc) 3688{ 3689 atf_tc_set_md_var(tc, "descr", 3690 "Verify plain PT_GETREGS call and retrieve INTRV"); 3691} 3692 3693ATF_TC_BODY(regs4, tc) 3694{ 3695 const int exitval = 5; 3696 const int sigval = SIGSTOP; 3697 pid_t child, wpid; 3698#if defined(TWAIT_HAVE_STATUS) 3699 int status; 3700#endif 3701 struct reg r; 3702 3703 printf("Before forking process PID=%d\n", getpid()); 3704 ATF_REQUIRE((child = fork()) != -1); 3705 if (child == 0) { 3706 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3707 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3708 3709 printf("Before raising %s from child\n", strsignal(sigval)); 3710 FORKEE_ASSERT(raise(sigval) == 0); 3711 3712 printf("Before exiting of the child process\n"); 3713 _exit(exitval); 3714 } 3715 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3716 3717 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3718 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3719 3720 validate_status_stopped(status, sigval); 3721 3722 printf("Call GETREGS for the child process\n"); 3723 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 3724 3725 printf("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r)); 3726 3727 printf("Before resuming the child process where it left off and " 3728 "without signal to be sent\n"); 3729 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3730 3731 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3732 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3733 3734 validate_status_exited(status, exitval); 3735 3736 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3737 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3738} 3739#endif 3740 3741#if defined(HAVE_GPREGS) 3742ATF_TC(regs5); 3743ATF_TC_HEAD(regs5, tc) 3744{ 3745 atf_tc_set_md_var(tc, "descr", 3746 "Verify PT_GETREGS and PT_SETREGS calls without changing regs"); 3747} 3748 3749ATF_TC_BODY(regs5, tc) 3750{ 3751 const int exitval = 5; 3752 const int sigval = SIGSTOP; 3753 pid_t child, wpid; 3754#if defined(TWAIT_HAVE_STATUS) 3755 int status; 3756#endif 3757 struct reg r; 3758 3759 printf("Before forking process PID=%d\n", getpid()); 3760 ATF_REQUIRE((child = fork()) != -1); 3761 if (child == 0) { 3762 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3763 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3764 3765 printf("Before raising %s from child\n", strsignal(sigval)); 3766 FORKEE_ASSERT(raise(sigval) == 0); 3767 3768 printf("Before exiting of the child process\n"); 3769 _exit(exitval); 3770 } 3771 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3772 3773 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3774 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3775 3776 validate_status_stopped(status, sigval); 3777 3778 printf("Call GETREGS for the child process\n"); 3779 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 3780 3781 printf("Call SETREGS for the child process (without changed regs)\n"); 3782 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 3783 3784 printf("Before resuming the child process where it left off and " 3785 "without signal to be sent\n"); 3786 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3787 3788 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3789 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3790 3791 validate_status_exited(status, exitval); 3792 3793 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3794 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3795} 3796#endif 3797 3798#if defined(HAVE_FPREGS) 3799ATF_TC(fpregs1); 3800ATF_TC_HEAD(fpregs1, tc) 3801{ 3802 atf_tc_set_md_var(tc, "descr", 3803 "Verify plain PT_GETFPREGS call without further steps"); 3804} 3805 3806ATF_TC_BODY(fpregs1, tc) 3807{ 3808 const int exitval = 5; 3809 const int sigval = SIGSTOP; 3810 pid_t child, wpid; 3811#if defined(TWAIT_HAVE_STATUS) 3812 int status; 3813#endif 3814 struct fpreg r; 3815 3816 printf("Before forking process PID=%d\n", getpid()); 3817 ATF_REQUIRE((child = fork()) != -1); 3818 if (child == 0) { 3819 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3820 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3821 3822 printf("Before raising %s from child\n", strsignal(sigval)); 3823 FORKEE_ASSERT(raise(sigval) == 0); 3824 3825 printf("Before exiting of the child process\n"); 3826 _exit(exitval); 3827 } 3828 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3829 3830 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3831 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3832 3833 validate_status_stopped(status, sigval); 3834 3835 printf("Call GETFPREGS for the child process\n"); 3836 ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1); 3837 3838 printf("Before resuming the child process where it left off and " 3839 "without signal to be sent\n"); 3840 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3841 3842 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3843 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3844 3845 validate_status_exited(status, exitval); 3846 3847 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3848 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3849} 3850#endif 3851 3852#if defined(HAVE_FPREGS) 3853ATF_TC(fpregs2); 3854ATF_TC_HEAD(fpregs2, tc) 3855{ 3856 atf_tc_set_md_var(tc, "descr", 3857 "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing " 3858 "regs"); 3859} 3860 3861ATF_TC_BODY(fpregs2, tc) 3862{ 3863 const int exitval = 5; 3864 const int sigval = SIGSTOP; 3865 pid_t child, wpid; 3866#if defined(TWAIT_HAVE_STATUS) 3867 int status; 3868#endif 3869 struct fpreg r; 3870 3871 printf("Before forking process PID=%d\n", getpid()); 3872 ATF_REQUIRE((child = fork()) != -1); 3873 if (child == 0) { 3874 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3875 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3876 3877 printf("Before raising %s from child\n", strsignal(sigval)); 3878 FORKEE_ASSERT(raise(sigval) == 0); 3879 3880 printf("Before exiting of the child process\n"); 3881 _exit(exitval); 3882 } 3883 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3884 3885 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3886 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3887 3888 validate_status_stopped(status, sigval); 3889 3890 printf("Call GETFPREGS for the child process\n"); 3891 ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1); 3892 3893 printf("Call SETFPREGS for the child (without changed regs)\n"); 3894 ATF_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1); 3895 3896 printf("Before resuming the child process where it left off and " 3897 "without signal to be sent\n"); 3898 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3899 3900 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3901 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3902 3903 validate_status_exited(status, exitval); 3904 3905 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3906 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3907} 3908#endif 3909 3910#if defined(PT_STEP) 3911ATF_TC(step1); 3912ATF_TC_HEAD(step1, tc) 3913{ 3914 atf_tc_set_md_var(tc, "descr", 3915 "Verify single PT_STEP call"); 3916} 3917 3918ATF_TC_BODY(step1, tc) 3919{ 3920 const int exitval = 5; 3921 const int sigval = SIGSTOP; 3922 pid_t child, wpid; 3923#if defined(TWAIT_HAVE_STATUS) 3924 int status; 3925#endif 3926 int happy; 3927 3928 printf("Before forking process PID=%d\n", getpid()); 3929 ATF_REQUIRE((child = fork()) != -1); 3930 if (child == 0) { 3931 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3932 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3933 3934 happy = check_happy(100); 3935 3936 printf("Before raising %s from child\n", strsignal(sigval)); 3937 FORKEE_ASSERT(raise(sigval) == 0); 3938 3939 FORKEE_ASSERT_EQ(happy, check_happy(100)); 3940 3941 printf("Before exiting of the child process\n"); 3942 _exit(exitval); 3943 } 3944 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3945 3946 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3947 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3948 3949 validate_status_stopped(status, sigval); 3950 3951 printf("Before resuming the child process where it left off and " 3952 "without signal to be sent (use PT_STEP)\n"); 3953 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 3954 3955 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3956 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3957 3958 validate_status_stopped(status, SIGTRAP); 3959 3960 printf("Before resuming the child process where it left off and " 3961 "without signal to be sent\n"); 3962 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3963 3964 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3965 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3966 3967 validate_status_exited(status, exitval); 3968 3969 printf("Before calling %s() for the child\n", TWAIT_FNAME); 3970 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3971} 3972#endif 3973 3974#if defined(PT_STEP) 3975ATF_TC(step2); 3976ATF_TC_HEAD(step2, tc) 3977{ 3978 atf_tc_set_md_var(tc, "descr", 3979 "Verify PT_STEP called twice"); 3980} 3981 3982ATF_TC_BODY(step2, tc) 3983{ 3984 const int exitval = 5; 3985 const int sigval = SIGSTOP; 3986 pid_t child, wpid; 3987#if defined(TWAIT_HAVE_STATUS) 3988 int status; 3989#endif 3990 int happy; 3991 int N = 2; 3992 3993 printf("Before forking process PID=%d\n", getpid()); 3994 ATF_REQUIRE((child = fork()) != -1); 3995 if (child == 0) { 3996 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 3997 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3998 3999 happy = check_happy(999); 4000 4001 printf("Before raising %s from child\n", strsignal(sigval)); 4002 FORKEE_ASSERT(raise(sigval) == 0); 4003 4004 FORKEE_ASSERT_EQ(happy, check_happy(999)); 4005 4006 printf("Before exiting of the child process\n"); 4007 _exit(exitval); 4008 } 4009 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4010 4011 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4012 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4013 4014 validate_status_stopped(status, sigval); 4015 4016 while (N --> 0) { 4017 printf("Before resuming the child process where it left off " 4018 "and without signal to be sent (use PT_STEP)\n"); 4019 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 4020 4021 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4022 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4023 child); 4024 4025 validate_status_stopped(status, SIGTRAP); 4026 } 4027 4028 printf("Before resuming the child process where it left off and " 4029 "without signal to be sent\n"); 4030 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4031 4032 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4033 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4034 4035 validate_status_exited(status, exitval); 4036 4037 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4038 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4039} 4040#endif 4041 4042#if defined(PT_STEP) 4043ATF_TC(step3); 4044ATF_TC_HEAD(step3, tc) 4045{ 4046 atf_tc_set_md_var(tc, "descr", 4047 "Verify PT_STEP called three times"); 4048} 4049 4050ATF_TC_BODY(step3, tc) 4051{ 4052 const int exitval = 5; 4053 const int sigval = SIGSTOP; 4054 pid_t child, wpid; 4055#if defined(TWAIT_HAVE_STATUS) 4056 int status; 4057#endif 4058 int happy; 4059 int N = 3; 4060 4061 printf("Before forking process PID=%d\n", getpid()); 4062 ATF_REQUIRE((child = fork()) != -1); 4063 if (child == 0) { 4064 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4065 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4066 4067 happy = check_happy(999); 4068 4069 printf("Before raising %s from child\n", strsignal(sigval)); 4070 FORKEE_ASSERT(raise(sigval) == 0); 4071 4072 FORKEE_ASSERT_EQ(happy, check_happy(999)); 4073 4074 printf("Before exiting of the child process\n"); 4075 _exit(exitval); 4076 } 4077 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4078 4079 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4080 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4081 4082 validate_status_stopped(status, sigval); 4083 4084 while (N --> 0) { 4085 printf("Before resuming the child process where it left off " 4086 "and without signal to be sent (use PT_STEP)\n"); 4087 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 4088 4089 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4090 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4091 child); 4092 4093 validate_status_stopped(status, SIGTRAP); 4094 } 4095 4096 printf("Before resuming the child process where it left off and " 4097 "without signal to be sent\n"); 4098 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4099 4100 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4101 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4102 4103 validate_status_exited(status, exitval); 4104 4105 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4106 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4107} 4108#endif 4109 4110#if defined(PT_STEP) 4111ATF_TC(step4); 4112ATF_TC_HEAD(step4, tc) 4113{ 4114 atf_tc_set_md_var(tc, "descr", 4115 "Verify PT_STEP called four times"); 4116} 4117 4118ATF_TC_BODY(step4, tc) 4119{ 4120 const int exitval = 5; 4121 const int sigval = SIGSTOP; 4122 pid_t child, wpid; 4123#if defined(TWAIT_HAVE_STATUS) 4124 int status; 4125#endif 4126 int happy; 4127 int N = 4; 4128 4129 printf("Before forking process PID=%d\n", getpid()); 4130 ATF_REQUIRE((child = fork()) != -1); 4131 if (child == 0) { 4132 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4133 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4134 4135 happy = check_happy(999); 4136 4137 printf("Before raising %s from child\n", strsignal(sigval)); 4138 FORKEE_ASSERT(raise(sigval) == 0); 4139 4140 FORKEE_ASSERT_EQ(happy, check_happy(999)); 4141 4142 printf("Before exiting of the child process\n"); 4143 _exit(exitval); 4144 } 4145 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4146 4147 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4148 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4149 4150 validate_status_stopped(status, sigval); 4151 4152 while (N --> 0) { 4153 printf("Before resuming the child process where it left off " 4154 "and without signal to be sent (use PT_STEP)\n"); 4155 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 4156 4157 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4158 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 4159 child); 4160 4161 validate_status_stopped(status, SIGTRAP); 4162 } 4163 4164 printf("Before resuming the child process where it left off and " 4165 "without signal to be sent\n"); 4166 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4167 4168 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4169 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4170 4171 validate_status_exited(status, exitval); 4172 4173 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4174 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4175} 4176#endif 4177 4178ATF_TC(kill1); 4179ATF_TC_HEAD(kill1, tc) 4180{ 4181 atf_tc_set_md_var(tc, "descr", 4182 "Verify that PT_CONTINUE with SIGKILL terminates child"); 4183} 4184 4185ATF_TC_BODY(kill1, tc) 4186{ 4187 const int sigval = SIGSTOP, sigsent = SIGKILL; 4188 pid_t child, wpid; 4189#if defined(TWAIT_HAVE_STATUS) 4190 int status; 4191#endif 4192 4193 printf("Before forking process PID=%d\n", getpid()); 4194 ATF_REQUIRE((child = fork()) != -1); 4195 if (child == 0) { 4196 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4197 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4198 4199 printf("Before raising %s from child\n", strsignal(sigval)); 4200 FORKEE_ASSERT(raise(sigval) == 0); 4201 4202 /* NOTREACHED */ 4203 FORKEE_ASSERTX(0 && 4204 "Child should be terminated by a signal from its parent"); 4205 } 4206 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4207 4208 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4209 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4210 4211 validate_status_stopped(status, sigval); 4212 4213 printf("Before resuming the child process where it left off and " 4214 "without signal to be sent\n"); 4215 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 4216 4217 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4218 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4219 4220 validate_status_signaled(status, sigsent, 0); 4221 4222 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4223 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4224} 4225 4226ATF_TC(kill2); 4227ATF_TC_HEAD(kill2, tc) 4228{ 4229 atf_tc_set_md_var(tc, "descr", 4230 "Verify that PT_KILL terminates child"); 4231} 4232 4233ATF_TC_BODY(kill2, tc) 4234{ 4235 const int sigval = SIGSTOP; 4236 pid_t child, wpid; 4237#if defined(TWAIT_HAVE_STATUS) 4238 int status; 4239#endif 4240 4241 printf("Before forking process PID=%d\n", getpid()); 4242 ATF_REQUIRE((child = fork()) != -1); 4243 if (child == 0) { 4244 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4245 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4246 4247 printf("Before raising %s from child\n", strsignal(sigval)); 4248 FORKEE_ASSERT(raise(sigval) == 0); 4249 4250 /* NOTREACHED */ 4251 FORKEE_ASSERTX(0 && 4252 "Child should be terminated by a signal from its parent"); 4253 } 4254 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4255 4256 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4257 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4258 4259 validate_status_stopped(status, sigval); 4260 4261 printf("Before resuming the child process where it left off and " 4262 "without signal to be sent\n"); 4263 ATF_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 4264 4265 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4266 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4267 4268 validate_status_signaled(status, SIGKILL, 0); 4269 4270 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4271 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4272} 4273 4274ATF_TC(lwpinfo1); 4275ATF_TC_HEAD(lwpinfo1, tc) 4276{ 4277 atf_tc_set_md_var(tc, "descr", 4278 "Verify basic LWPINFO call for single thread (PT_TRACE_ME)"); 4279} 4280 4281ATF_TC_BODY(lwpinfo1, tc) 4282{ 4283 const int exitval = 5; 4284 const int sigval = SIGSTOP; 4285 pid_t child, wpid; 4286#if defined(TWAIT_HAVE_STATUS) 4287 int status; 4288#endif 4289 struct ptrace_lwpinfo info = {0, 0}; 4290 4291 printf("Before forking process PID=%d\n", getpid()); 4292 ATF_REQUIRE((child = fork()) != -1); 4293 if (child == 0) { 4294 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4295 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4296 4297 printf("Before raising %s from child\n", strsignal(sigval)); 4298 FORKEE_ASSERT(raise(sigval) == 0); 4299 4300 printf("Before exiting of the child process\n"); 4301 _exit(exitval); 4302 } 4303 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4304 4305 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4306 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4307 4308 validate_status_stopped(status, sigval); 4309 4310 printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4311 ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); 4312 4313 printf("Assert that there exists a thread\n"); 4314 ATF_REQUIRE(info.pl_lwpid > 0); 4315 4316 printf("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 4317 info.pl_lwpid); 4318 ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL, 4319 "Received event %d != expected event %d", 4320 info.pl_event, PL_EVENT_SIGNAL); 4321 4322 printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4323 ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); 4324 4325 printf("Assert that there are no more lwp threads in child\n"); 4326 ATF_REQUIRE_EQ(info.pl_lwpid, 0); 4327 4328 printf("Before resuming the child process where it left off and " 4329 "without signal to be sent\n"); 4330 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4331 4332 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4333 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4334 4335 validate_status_exited(status, exitval); 4336 4337 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4338 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4339} 4340 4341#if defined(TWAIT_HAVE_PID) 4342ATF_TC(lwpinfo2); 4343ATF_TC_HEAD(lwpinfo2, tc) 4344{ 4345 atf_tc_set_md_var(tc, "descr", 4346 "Verify basic LWPINFO call for single thread (PT_ATTACH from " 4347 "tracer)"); 4348} 4349 4350ATF_TC_BODY(lwpinfo2, tc) 4351{ 4352 struct msg_fds parent_tracee, parent_tracer; 4353 const int exitval_tracee = 5; 4354 const int exitval_tracer = 10; 4355 pid_t tracee, tracer, wpid; 4356 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 4357#if defined(TWAIT_HAVE_STATUS) 4358 int status; 4359#endif 4360 struct ptrace_lwpinfo info = {0, 0}; 4361 4362 printf("Spawn tracee\n"); 4363 ATF_REQUIRE(msg_open(&parent_tracee) == 0); 4364 ATF_REQUIRE(msg_open(&parent_tracer) == 0); 4365 tracee = atf_utils_fork(); 4366 if (tracee == 0) { 4367 4368 /* Wait for message from the parent */ 4369 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 4370 CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); 4371 4372 _exit(exitval_tracee); 4373 } 4374 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 4375 4376 printf("Spawn debugger\n"); 4377 tracer = atf_utils_fork(); 4378 if (tracer == 0) { 4379 /* No IPC to communicate with the child */ 4380 printf("Before calling PT_ATTACH from tracee %d\n", getpid()); 4381 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 4382 4383 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 4384 FORKEE_REQUIRE_SUCCESS( 4385 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4386 4387 forkee_status_stopped(status, SIGSTOP); 4388 4389 printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4390 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) 4391 != -1); 4392 4393 printf("Assert that there exists a thread\n"); 4394 FORKEE_ASSERTX(info.pl_lwpid > 0); 4395 4396 printf("Assert that lwp thread %d received event " 4397 "PL_EVENT_SIGNAL\n", info.pl_lwpid); 4398 FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL); 4399 4400 printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); 4401 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) 4402 != -1); 4403 4404 printf("Assert that there are no more lwp threads in child\n"); 4405 FORKEE_ASSERTX(info.pl_lwpid == 0); 4406 4407 /* Resume tracee with PT_CONTINUE */ 4408 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 4409 4410 /* Inform parent that tracer has attached to tracee */ 4411 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 4412 /* Wait for parent */ 4413 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 4414 4415 /* Wait for tracee and assert that it exited */ 4416 FORKEE_REQUIRE_SUCCESS( 4417 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 4418 4419 forkee_status_exited(status, exitval_tracee); 4420 4421 printf("Before exiting of the tracer process\n"); 4422 _exit(exitval_tracer); 4423 } 4424 4425 printf("Wait for the tracer to attach to the tracee\n"); 4426 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 4427 4428 printf("Resume the tracee and let it exit\n"); 4429 PARENT_TO_CHILD("tracee exit", parent_tracee, msg); 4430 4431 printf("Detect that tracee is zombie\n"); 4432 await_zombie(tracee); 4433 4434 printf("Assert that there is no status about tracee - " 4435 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 4436 TWAIT_REQUIRE_SUCCESS( 4437 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 4438 4439 printf("Resume the tracer and let it detect exited tracee\n"); 4440 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 4441 4442 printf("Wait for tracer to finish its job and exit - calling %s()\n", 4443 TWAIT_FNAME); 4444 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 4445 tracer); 4446 4447 validate_status_exited(status, exitval_tracer); 4448 4449 printf("Wait for tracee to finish its job and exit - calling %s()\n", 4450 TWAIT_FNAME); 4451 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 4452 tracee); 4453 4454 validate_status_exited(status, exitval_tracee); 4455 4456 msg_close(&parent_tracer); 4457 msg_close(&parent_tracee); 4458} 4459#endif 4460 4461ATF_TC(siginfo1); 4462ATF_TC_HEAD(siginfo1, tc) 4463{ 4464 atf_tc_set_md_var(tc, "descr", 4465 "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee"); 4466} 4467 4468ATF_TC_BODY(siginfo1, tc) 4469{ 4470 const int exitval = 5; 4471 const int sigval = SIGTRAP; 4472 pid_t child, wpid; 4473#if defined(TWAIT_HAVE_STATUS) 4474 int status; 4475#endif 4476 struct ptrace_siginfo info; 4477 memset(&info, 0, sizeof(info)); 4478 4479 printf("Before forking process PID=%d\n", getpid()); 4480 ATF_REQUIRE((child = fork()) != -1); 4481 if (child == 0) { 4482 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4483 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4484 4485 printf("Before raising %s from child\n", strsignal(sigval)); 4486 FORKEE_ASSERT(raise(sigval) == 0); 4487 4488 printf("Before exiting of the child process\n"); 4489 _exit(exitval); 4490 } 4491 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4492 4493 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4494 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4495 4496 validate_status_stopped(status, sigval); 4497 4498 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4499 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4500 4501 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 4502 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4503 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4504 info.psi_siginfo.si_errno); 4505 4506 printf("Before resuming the child process where it left off and " 4507 "without signal to be sent\n"); 4508 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4509 4510 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4511 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4512 4513 validate_status_exited(status, exitval); 4514 4515 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4516 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4517} 4518 4519ATF_TC(siginfo2); 4520ATF_TC_HEAD(siginfo2, tc) 4521{ 4522 atf_tc_set_md_var(tc, "descr", 4523 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without " 4524 "modification of SIGINT from tracee"); 4525} 4526 4527static int siginfo2_caught = 0; 4528 4529static void 4530siginfo2_sighandler(int sig) 4531{ 4532 FORKEE_ASSERT_EQ(sig, SIGINT); 4533 4534 ++siginfo2_caught; 4535} 4536 4537ATF_TC_BODY(siginfo2, tc) 4538{ 4539 const int exitval = 5; 4540 const int sigval = SIGINT; 4541 pid_t child, wpid; 4542 struct sigaction sa; 4543#if defined(TWAIT_HAVE_STATUS) 4544 int status; 4545#endif 4546 struct ptrace_siginfo info; 4547 memset(&info, 0, sizeof(info)); 4548 4549 printf("Before forking process PID=%d\n", getpid()); 4550 ATF_REQUIRE((child = fork()) != -1); 4551 if (child == 0) { 4552 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4553 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4554 4555 sa.sa_handler = siginfo2_sighandler; 4556 sa.sa_flags = SA_SIGINFO; 4557 sigemptyset(&sa.sa_mask); 4558 4559 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 4560 4561 printf("Before raising %s from child\n", strsignal(sigval)); 4562 FORKEE_ASSERT(raise(sigval) == 0); 4563 4564 FORKEE_ASSERT_EQ(siginfo2_caught, 1); 4565 4566 printf("Before exiting of the child process\n"); 4567 _exit(exitval); 4568 } 4569 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4570 4571 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4572 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4573 4574 validate_status_stopped(status, sigval); 4575 4576 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4577 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4578 4579 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 4580 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4581 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4582 info.psi_siginfo.si_errno); 4583 4584 printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 4585 ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 4586 4587 printf("Before resuming the child process where it left off and " 4588 "without signal to be sent\n"); 4589 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1); 4590 4591 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4592 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4593 4594 validate_status_exited(status, exitval); 4595 4596 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4597 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4598} 4599 4600ATF_TC(siginfo3); 4601ATF_TC_HEAD(siginfo3, tc) 4602{ 4603 atf_tc_set_md_var(tc, "descr", 4604 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with " 4605 "setting signal to new value"); 4606} 4607 4608static int siginfo3_caught = 0; 4609 4610static void 4611siginfo3_sigaction(int sig, siginfo_t *info, void *ctx) 4612{ 4613 FORKEE_ASSERT_EQ(sig, SIGTRAP); 4614 4615 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); 4616 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); 4617 4618 ++siginfo3_caught; 4619} 4620 4621ATF_TC_BODY(siginfo3, tc) 4622{ 4623 const int exitval = 5; 4624 const int sigval = SIGINT; 4625 const int sigfaked = SIGTRAP; 4626 const int sicodefaked = TRAP_BRKPT; 4627 pid_t child, wpid; 4628 struct sigaction sa; 4629#if defined(TWAIT_HAVE_STATUS) 4630 int status; 4631#endif 4632 struct ptrace_siginfo info; 4633 memset(&info, 0, sizeof(info)); 4634 4635 printf("Before forking process PID=%d\n", getpid()); 4636 ATF_REQUIRE((child = fork()) != -1); 4637 if (child == 0) { 4638 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4639 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4640 4641 sa.sa_sigaction = siginfo3_sigaction; 4642 sa.sa_flags = SA_SIGINFO; 4643 sigemptyset(&sa.sa_mask); 4644 4645 FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1); 4646 4647 printf("Before raising %s from child\n", strsignal(sigval)); 4648 FORKEE_ASSERT(raise(sigval) == 0); 4649 4650 FORKEE_ASSERT_EQ(siginfo3_caught, 1); 4651 4652 printf("Before exiting of the child process\n"); 4653 _exit(exitval); 4654 } 4655 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4656 4657 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4658 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4659 4660 validate_status_stopped(status, sigval); 4661 4662 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4663 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4664 4665 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 4666 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4667 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4668 info.psi_siginfo.si_errno); 4669 4670 printf("Before setting new faked signal to signo=%d si_code=%d\n", 4671 sigfaked, sicodefaked); 4672 info.psi_siginfo.si_signo = sigfaked; 4673 info.psi_siginfo.si_code = sicodefaked; 4674 4675 printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 4676 ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 4677 4678 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4679 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4680 4681 printf("Before checking siginfo_t\n"); 4682 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 4683 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 4684 4685 printf("Before resuming the child process where it left off and " 4686 "without signal to be sent\n"); 4687 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1); 4688 4689 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4690 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4691 4692 validate_status_exited(status, exitval); 4693 4694 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4695 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4696} 4697 4698ATF_TC(siginfo4); 4699ATF_TC_HEAD(siginfo4, tc) 4700{ 4701 atf_tc_set_md_var(tc, "descr", 4702 "Detect SIGTRAP TRAP_EXEC from tracee"); 4703} 4704 4705ATF_TC_BODY(siginfo4, tc) 4706{ 4707 const int sigval = SIGTRAP; 4708 pid_t child, wpid; 4709#if defined(TWAIT_HAVE_STATUS) 4710 int status; 4711#endif 4712 4713 struct ptrace_siginfo info; 4714 memset(&info, 0, sizeof(info)); 4715 4716 printf("Before forking process PID=%d\n", getpid()); 4717 ATF_REQUIRE((child = fork()) != -1); 4718 if (child == 0) { 4719 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4720 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4721 4722 printf("Before calling execve(2) from child\n"); 4723 execlp("/bin/echo", "/bin/echo", NULL); 4724 4725 FORKEE_ASSERT(0 && "Not reached"); 4726 } 4727 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4728 4729 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4730 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4731 4732 validate_status_stopped(status, sigval); 4733 4734 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4735 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4736 4737 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 4738 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4739 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4740 info.psi_siginfo.si_errno); 4741 4742 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4743 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4744 4745 printf("Before resuming the child process where it left off and " 4746 "without signal to be sent\n"); 4747 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4748 4749 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4750 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4751 4752 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4753 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4754} 4755 4756#if defined(TWAIT_HAVE_PID) 4757ATF_TC(siginfo5); 4758ATF_TC_HEAD(siginfo5, tc) 4759{ 4760 atf_tc_set_md_var(tc, "descr", 4761 "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK " 4762 "set to PTRACE_FORK and reports correct signal information"); 4763} 4764 4765ATF_TC_BODY(siginfo5, tc) 4766{ 4767 const int exitval = 5; 4768 const int exitval2 = 15; 4769 const int sigval = SIGSTOP; 4770 pid_t child, child2, wpid; 4771#if defined(TWAIT_HAVE_STATUS) 4772 int status; 4773#endif 4774 ptrace_state_t state; 4775 const int slen = sizeof(state); 4776 ptrace_event_t event; 4777 const int elen = sizeof(event); 4778 struct ptrace_siginfo info; 4779 4780 memset(&info, 0, sizeof(info)); 4781 4782 printf("Before forking process PID=%d\n", getpid()); 4783 ATF_REQUIRE((child = fork()) != -1); 4784 if (child == 0) { 4785 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4786 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4787 4788 printf("Before raising %s from child\n", strsignal(sigval)); 4789 FORKEE_ASSERT(raise(sigval) == 0); 4790 4791 FORKEE_ASSERT((child2 = fork()) != 1); 4792 4793 if (child2 == 0) 4794 _exit(exitval2); 4795 4796 FORKEE_REQUIRE_SUCCESS 4797 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4798 4799 forkee_status_exited(status, exitval2); 4800 4801 printf("Before exiting of the child process\n"); 4802 _exit(exitval); 4803 } 4804 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4805 4806 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4807 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4808 4809 validate_status_stopped(status, sigval); 4810 4811 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4812 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4813 4814 printf("Before checking siginfo_t\n"); 4815 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4816 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4817 4818 printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 4819 event.pe_set_event = PTRACE_FORK; 4820 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4821 4822 printf("Before resuming the child process where it left off and " 4823 "without signal to be sent\n"); 4824 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4825 4826 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); 4827 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4828 4829 validate_status_stopped(status, SIGTRAP); 4830 4831 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4832 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4833 4834 printf("Before checking siginfo_t\n"); 4835 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4836 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); 4837 4838 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4839 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4840 4841 child2 = state.pe_other_pid; 4842 printf("Reported PTRACE_FORK event with forkee %d\n", child2); 4843 4844 printf("Before calling %s() for the forkee %d of the child %d\n", 4845 TWAIT_FNAME, child2, child); 4846 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4847 child2); 4848 4849 validate_status_stopped(status, SIGTRAP); 4850 4851 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4852 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4853 4854 printf("Before checking siginfo_t\n"); 4855 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4856 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); 4857 4858 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 4859 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4860 ATF_REQUIRE_EQ(state.pe_other_pid, child); 4861 4862 printf("Before resuming the forkee process where it left off and " 4863 "without signal to be sent\n"); 4864 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 4865 4866 printf("Before resuming the child process where it left off and " 4867 "without signal to be sent\n"); 4868 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4869 4870 printf("Before calling %s() for the forkee - expected exited\n", 4871 TWAIT_FNAME); 4872 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4873 child2); 4874 4875 validate_status_exited(status, exitval2); 4876 4877 printf("Before calling %s() for the forkee - expected no process\n", 4878 TWAIT_FNAME); 4879 TWAIT_REQUIRE_FAILURE(ECHILD, 4880 wpid = TWAIT_GENERIC(child2, &status, 0)); 4881 4882 printf("Before calling %s() for the child - expected stopped " 4883 "SIGCHLD\n", TWAIT_FNAME); 4884 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4885 4886 validate_status_stopped(status, SIGCHLD); 4887 4888 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4889 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4890 4891 printf("Before checking siginfo_t\n"); 4892 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD); 4893 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED); 4894 4895 printf("Before resuming the child process where it left off and " 4896 "without signal to be sent\n"); 4897 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4898 4899 printf("Before calling %s() for the child - expected exited\n", 4900 TWAIT_FNAME); 4901 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4902 4903 validate_status_exited(status, exitval); 4904 4905 printf("Before calling %s() for the child - expected no process\n", 4906 TWAIT_FNAME); 4907 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4908} 4909#endif 4910 4911#if defined(PT_STEP) 4912ATF_TC(siginfo6); 4913ATF_TC_HEAD(siginfo6, tc) 4914{ 4915 atf_tc_set_md_var(tc, "descr", 4916 "Verify single PT_STEP call with signal information check"); 4917} 4918 4919ATF_TC_BODY(siginfo6, tc) 4920{ 4921 const int exitval = 5; 4922 const int sigval = SIGSTOP; 4923 pid_t child, wpid; 4924#if defined(TWAIT_HAVE_STATUS) 4925 int status; 4926#endif 4927 int happy; 4928 struct ptrace_siginfo info; 4929 4930 memset(&info, 0, sizeof(info)); 4931 4932 printf("Before forking process PID=%d\n", getpid()); 4933 ATF_REQUIRE((child = fork()) != -1); 4934 if (child == 0) { 4935 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 4936 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4937 4938 happy = check_happy(100); 4939 4940 printf("Before raising %s from child\n", strsignal(sigval)); 4941 FORKEE_ASSERT(raise(sigval) == 0); 4942 4943 FORKEE_ASSERT_EQ(happy, check_happy(100)); 4944 4945 printf("Before exiting of the child process\n"); 4946 _exit(exitval); 4947 } 4948 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4949 4950 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4951 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4952 4953 validate_status_stopped(status, sigval); 4954 4955 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4956 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4957 4958 printf("Before checking siginfo_t\n"); 4959 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4960 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4961 4962 printf("Before resuming the child process where it left off and " 4963 "without signal to be sent (use PT_STEP)\n"); 4964 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 4965 4966 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4967 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4968 4969 validate_status_stopped(status, SIGTRAP); 4970 4971 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4972 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4973 4974 printf("Before checking siginfo_t\n"); 4975 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 4976 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 4977 4978 printf("Before resuming the child process where it left off and " 4979 "without signal to be sent\n"); 4980 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4981 4982 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4983 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4984 4985 validate_status_exited(status, exitval); 4986 4987 printf("Before calling %s() for the child\n", TWAIT_FNAME); 4988 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4989} 4990#endif 4991 4992ATF_TP_ADD_TCS(tp) 4993{ 4994 setvbuf(stdout, NULL, _IONBF, 0); 4995 setvbuf(stderr, NULL, _IONBF, 0); 4996 ATF_TP_ADD_TC(tp, traceme1); 4997 ATF_TP_ADD_TC(tp, traceme2); 4998 ATF_TP_ADD_TC(tp, traceme3); 4999 ATF_TP_ADD_TC(tp, traceme4); 5000 5001 ATF_TP_ADD_TC_HAVE_PID(tp, attach1); 5002 ATF_TP_ADD_TC_HAVE_PID(tp, attach2); 5003 ATF_TP_ADD_TC(tp, attach3); 5004 ATF_TP_ADD_TC(tp, attach4); 5005 ATF_TP_ADD_TC_HAVE_PID(tp, attach5); 5006 ATF_TP_ADD_TC_HAVE_PID(tp, attach6); 5007 ATF_TP_ADD_TC_HAVE_PID(tp, attach7); 5008 5009 ATF_TP_ADD_TC(tp, eventmask1); 5010 ATF_TP_ADD_TC(tp, eventmask2); 5011 5012 ATF_TP_ADD_TC_HAVE_PID(tp, fork1); 5013 ATF_TP_ADD_TC(tp, fork2); 5014 5015 ATF_TP_ADD_TC_HAVE_PID(tp, vfork1); 5016 ATF_TP_ADD_TC(tp, vfork2); 5017 5018 ATF_TP_ADD_TC(tp, io_read_d1); 5019 ATF_TP_ADD_TC(tp, io_read_d2); 5020 ATF_TP_ADD_TC(tp, io_read_d3); 5021 ATF_TP_ADD_TC(tp, io_read_d4); 5022 5023 ATF_TP_ADD_TC(tp, io_write_d1); 5024 ATF_TP_ADD_TC(tp, io_write_d2); 5025 ATF_TP_ADD_TC(tp, io_write_d3); 5026 ATF_TP_ADD_TC(tp, io_write_d4); 5027 5028 ATF_TP_ADD_TC(tp, read_d1); 5029 ATF_TP_ADD_TC(tp, read_d2); 5030 ATF_TP_ADD_TC(tp, read_d3); 5031 ATF_TP_ADD_TC(tp, read_d4); 5032 5033 ATF_TP_ADD_TC(tp, write_d1); 5034 ATF_TP_ADD_TC(tp, write_d2); 5035 ATF_TP_ADD_TC(tp, write_d3); 5036 ATF_TP_ADD_TC(tp, write_d4); 5037 5038 ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1); 5039 ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2); 5040 5041 ATF_TP_ADD_TC(tp, read_d_write_d_handshake1); 5042 ATF_TP_ADD_TC(tp, read_d_write_d_handshake2); 5043 5044 ATF_TP_ADD_TC(tp, io_read_i1); 5045 ATF_TP_ADD_TC(tp, io_read_i2); 5046 ATF_TP_ADD_TC(tp, io_read_i3); 5047 ATF_TP_ADD_TC(tp, io_read_i4); 5048 5049 ATF_TP_ADD_TC(tp, read_i1); 5050 ATF_TP_ADD_TC(tp, read_i2); 5051 ATF_TP_ADD_TC(tp, read_i3); 5052 ATF_TP_ADD_TC(tp, read_i4); 5053 5054 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); 5055 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2); 5056 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3); 5057 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4); 5058 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5); 5059 5060 ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1); 5061 ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2); 5062 5063 ATF_TP_ADD_TC_PT_STEP(tp, step1); 5064 ATF_TP_ADD_TC_PT_STEP(tp, step2); 5065 ATF_TP_ADD_TC_PT_STEP(tp, step3); 5066 ATF_TP_ADD_TC_PT_STEP(tp, step4); 5067 5068 ATF_TP_ADD_TC(tp, kill1); 5069 ATF_TP_ADD_TC(tp, kill2); 5070 5071 ATF_TP_ADD_TC(tp, lwpinfo1); 5072 ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2); 5073 5074 ATF_TP_ADD_TC(tp, siginfo1); 5075 ATF_TP_ADD_TC(tp, siginfo2); 5076 ATF_TP_ADD_TC(tp, siginfo3); 5077 ATF_TP_ADD_TC(tp, siginfo4); 5078 ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5); 5079 ATF_TP_ADD_TC_PT_STEP(tp, siginfo6); 5080 5081 return atf_no_error(); 5082} 5083