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