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