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