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