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