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