t_ptrace_wait.c revision 1.185
1/* $NetBSD: t_ptrace_wait.c,v 1.185 2020/05/05 00:15:45 kamil Exp $ */ 2 3/*- 4 * Copyright (c) 2016, 2017, 2018, 2019, 2020 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.185 2020/05/05 00:15:45 kamil Exp $"); 31 32#define __LEGACY_PT_LWPINFO 33 34#include <sys/param.h> 35#include <sys/types.h> 36#include <sys/exec_elf.h> 37#include <sys/mman.h> 38#include <sys/ptrace.h> 39#include <sys/resource.h> 40#include <sys/stat.h> 41#include <sys/syscall.h> 42#include <sys/sysctl.h> 43#include <sys/uio.h> 44#include <sys/wait.h> 45#include <machine/reg.h> 46#include <assert.h> 47#include <elf.h> 48#include <err.h> 49#include <errno.h> 50#include <fcntl.h> 51#include <lwp.h> 52#include <pthread.h> 53#include <sched.h> 54#include <signal.h> 55#include <spawn.h> 56#include <stdint.h> 57#include <stdio.h> 58#include <stdlib.h> 59#include <strings.h> 60#include <time.h> 61#include <unistd.h> 62 63#if defined(__i386__) || defined(__x86_64__) 64#include <cpuid.h> 65#include <x86/cpu_extended_state.h> 66#include <x86/specialreg.h> 67#endif 68 69#include <libelf.h> 70#include <gelf.h> 71 72#include <atf-c.h> 73 74#ifdef ENABLE_TESTS 75 76/* Assumptions in the kernel code that must be kept. */ 77__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) == 78 sizeof(((siginfo_t *)0)->si_pe_report_event)); 79__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 80 sizeof(((siginfo_t *)0)->si_pe_other_pid)); 81__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) == 82 sizeof(((siginfo_t *)0)->si_pe_lwp)); 83__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 84 sizeof(((struct ptrace_state *)0)->pe_lwp)); 85 86#include "h_macros.h" 87 88#include "t_ptrace_wait.h" 89#include "msg.h" 90 91#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 92 strerror(errno)) 93#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 94 "%d(%s) != %d", res, strerror(res), exp) 95 96static int debug = 0; 97 98#define DPRINTF(a, ...) do \ 99 if (debug) \ 100 printf("%s() %d.%d %s:%d " a, \ 101 __func__, getpid(), _lwp_self(), __FILE__, __LINE__, ##__VA_ARGS__); \ 102 while (/*CONSTCOND*/0) 103 104/// ---------------------------------------------------------------------------- 105 106ATF_TC(traceme_pid1_parent); 107ATF_TC_HEAD(traceme_pid1_parent, tc) 108{ 109 atf_tc_set_md_var(tc, "descr", 110 "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 111} 112 113ATF_TC_BODY(traceme_pid1_parent, tc) 114{ 115 struct msg_fds parent_child; 116 int exitval_child1 = 1, exitval_child2 = 2; 117 pid_t child1, child2, wpid; 118 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 119#if defined(TWAIT_HAVE_STATUS) 120 int status; 121#endif 122 123 SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 124 125 DPRINTF("Before forking process PID=%d\n", getpid()); 126 SYSCALL_REQUIRE((child1 = fork()) != -1); 127 if (child1 == 0) { 128 DPRINTF("Before forking process PID=%d\n", getpid()); 129 SYSCALL_REQUIRE((child2 = fork()) != -1); 130 if (child2 != 0) { 131 DPRINTF("Parent process PID=%d, child2's PID=%d\n", 132 getpid(), child2); 133 _exit(exitval_child1); 134 } 135 CHILD_FROM_PARENT("exit child1", parent_child, msg); 136 137 DPRINTF("Assert that our parent is PID1 (initproc)\n"); 138 FORKEE_ASSERT_EQ(getppid(), 1); 139 140 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 141 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 142 SYSCALL_REQUIRE_ERRNO(errno, EPERM); 143 144 CHILD_TO_PARENT("child2 exiting", parent_child, msg); 145 146 _exit(exitval_child2); 147 } 148 DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 149 150 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 151 TWAIT_REQUIRE_SUCCESS( 152 wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 153 154 validate_status_exited(status, exitval_child1); 155 156 DPRINTF("Notify that child1 is dead\n"); 157 PARENT_TO_CHILD("exit child1", parent_child, msg); 158 159 DPRINTF("Wait for exiting of child2\n"); 160 PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 161} 162 163/// ---------------------------------------------------------------------------- 164 165static void 166traceme_vfork_exec(bool masked, bool ignored) 167{ 168 const int sigval = SIGTRAP; 169 pid_t child, wpid; 170#if defined(TWAIT_HAVE_STATUS) 171 int status; 172#endif 173 struct sigaction sa; 174 struct ptrace_siginfo info; 175 sigset_t intmask; 176 struct kinfo_proc2 kp; 177 size_t len = sizeof(kp); 178 179 int name[6]; 180 const size_t namelen = __arraycount(name); 181 ki_sigset_t kp_sigmask; 182 ki_sigset_t kp_sigignore; 183 184 memset(&info, 0, sizeof(info)); 185 186 DPRINTF("Before forking process PID=%d\n", getpid()); 187 SYSCALL_REQUIRE((child = vfork()) != -1); 188 if (child == 0) { 189 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 190 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 191 192 if (masked) { 193 sigemptyset(&intmask); 194 sigaddset(&intmask, sigval); 195 sigprocmask(SIG_BLOCK, &intmask, NULL); 196 } 197 198 if (ignored) { 199 memset(&sa, 0, sizeof(sa)); 200 sa.sa_handler = SIG_IGN; 201 sigemptyset(&sa.sa_mask); 202 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 203 } 204 205 DPRINTF("Before calling execve(2) from child\n"); 206 execlp("/bin/echo", "/bin/echo", NULL); 207 208 /* NOTREACHED */ 209 FORKEE_ASSERTX(0 && "Not reached"); 210 } 211 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 212 213 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 214 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 215 216 validate_status_stopped(status, sigval); 217 218 name[0] = CTL_KERN, 219 name[1] = KERN_PROC2, 220 name[2] = KERN_PROC_PID; 221 name[3] = getpid(); 222 name[4] = sizeof(kp); 223 name[5] = 1; 224 225 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 226 227 if (masked) 228 kp_sigmask = kp.p_sigmask; 229 230 if (ignored) 231 kp_sigignore = kp.p_sigignore; 232 233 name[3] = getpid(); 234 235 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 236 237 if (masked) { 238 DPRINTF("kp_sigmask=" 239 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 240 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 241 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 242 243 DPRINTF("kp.p_sigmask=" 244 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 245 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 246 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 247 248 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 249 sizeof(kp_sigmask))); 250 } 251 252 if (ignored) { 253 DPRINTF("kp_sigignore=" 254 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 255 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 256 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 257 258 DPRINTF("kp.p_sigignore=" 259 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 260 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 261 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 262 263 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 264 sizeof(kp_sigignore))); 265 } 266 267 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 268 SYSCALL_REQUIRE( 269 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 270 271 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 272 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 273 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 274 info.psi_siginfo.si_errno); 275 276 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 277 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 278 279 DPRINTF("Before resuming the child process where it left off and " 280 "without signal to be sent\n"); 281 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 282 283 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 284 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 285 286 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 287 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 288} 289 290#define TRACEME_VFORK_EXEC(test, masked, ignored) \ 291ATF_TC(test); \ 292ATF_TC_HEAD(test, tc) \ 293{ \ 294 atf_tc_set_md_var(tc, "descr", \ 295 "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed " \ 296 "child%s%s", masked ? " with masked signal" : "", \ 297 masked ? " with ignored signal" : ""); \ 298} \ 299 \ 300ATF_TC_BODY(test, tc) \ 301{ \ 302 \ 303 traceme_vfork_exec(masked, ignored); \ 304} 305 306TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false) 307TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false) 308TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true) 309 310/// ---------------------------------------------------------------------------- 311 312#if defined(TWAIT_HAVE_PID) 313static void 314tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 315 bool stopped) 316{ 317 /* 318 * notimeout - disable timeout in await zombie function 319 * unrelated - attach from unrelated tracer reparented to initproc 320 * stopped - attach to a stopped process 321 */ 322 323 struct msg_fds parent_tracee, parent_tracer; 324 const int exitval_tracee = 5; 325 const int exitval_tracer = 10; 326 pid_t tracee, tracer, wpid; 327 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 328#if defined(TWAIT_HAVE_STATUS) 329 int status; 330#endif 331 332 /* 333 * Only a subset of options are supported. 334 */ 335 ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 336 (!notimeout && unrelated && !stopped) || 337 (notimeout && !unrelated && !stopped) || 338 (!notimeout && unrelated && stopped)); 339 340 DPRINTF("Spawn tracee\n"); 341 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 342 tracee = atf_utils_fork(); 343 if (tracee == 0) { 344 if (stopped) { 345 DPRINTF("Stop self PID %d\n", getpid()); 346 raise(SIGSTOP); 347 } 348 349 // Wait for parent to let us exit 350 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 351 _exit(exitval_tracee); 352 } 353 354 DPRINTF("Spawn debugger\n"); 355 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 356 tracer = atf_utils_fork(); 357 if (tracer == 0) { 358 if(unrelated) { 359 /* Fork again and drop parent to reattach to PID 1 */ 360 tracer = atf_utils_fork(); 361 if (tracer != 0) 362 _exit(exitval_tracer); 363 } 364 365 if (stopped) { 366 DPRINTF("Await for a stopped parent PID %d\n", tracee); 367 await_stopped(tracee); 368 } 369 370 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 371 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 372 373 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 374 FORKEE_REQUIRE_SUCCESS( 375 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 376 377 forkee_status_stopped(status, SIGSTOP); 378 379 /* Resume tracee with PT_CONTINUE */ 380 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 381 382 /* Inform parent that tracer has attached to tracee */ 383 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 384 385 /* Wait for parent to tell use that tracee should have exited */ 386 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 387 388 /* Wait for tracee and assert that it exited */ 389 FORKEE_REQUIRE_SUCCESS( 390 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 391 392 forkee_status_exited(status, exitval_tracee); 393 DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 394 395 DPRINTF("Before exiting of the tracer process\n"); 396 _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 397 } 398 399 if (unrelated) { 400 DPRINTF("Wait for the tracer process (direct child) to exit " 401 "calling %s()\n", TWAIT_FNAME); 402 TWAIT_REQUIRE_SUCCESS( 403 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 404 405 validate_status_exited(status, exitval_tracer); 406 407 DPRINTF("Wait for the non-exited tracee process with %s()\n", 408 TWAIT_FNAME); 409 TWAIT_REQUIRE_SUCCESS( 410 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 411 } 412 413 DPRINTF("Wait for the tracer to attach to the tracee\n"); 414 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 415 416 DPRINTF("Resume the tracee and let it exit\n"); 417 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 418 419 DPRINTF("Detect that tracee is zombie\n"); 420 if (notimeout) 421 await_zombie_raw(tracee, 0); 422 else 423 await_zombie(tracee); 424 425 DPRINTF("Assert that there is no status about tracee %d - " 426 "Tracer must detect zombie first - calling %s()\n", tracee, 427 TWAIT_FNAME); 428 TWAIT_REQUIRE_SUCCESS( 429 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 430 431 if (unrelated) { 432 DPRINTF("Resume the tracer and let it detect exited tracee\n"); 433 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 434 } else { 435 DPRINTF("Tell the tracer child should have exited\n"); 436 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 437 DPRINTF("Wait for tracer to finish its job and exit - calling " 438 "%s()\n", TWAIT_FNAME); 439 440 DPRINTF("Wait from tracer child to complete waiting for " 441 "tracee\n"); 442 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 443 tracer); 444 445 validate_status_exited(status, exitval_tracer); 446 } 447 448 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 449 TWAIT_FNAME); 450 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 451 452 validate_status_exited(status, exitval_tracee); 453 454 msg_close(&parent_tracer); 455 msg_close(&parent_tracee); 456} 457 458ATF_TC(tracer_sees_terminaton_before_the_parent); 459ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 460{ 461 atf_tc_set_md_var(tc, "descr", 462 "Assert that tracer sees process termination before the parent"); 463} 464 465ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 466{ 467 468 tracer_sees_terminaton_before_the_parent_raw(false, false, false); 469} 470 471ATF_TC(tracer_sysctl_lookup_without_duplicates); 472ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 473{ 474 atf_tc_set_md_var(tc, "timeout", "15"); 475 atf_tc_set_md_var(tc, "descr", 476 "Assert that await_zombie() in attach1 always finds a single " 477 "process and no other error is reported"); 478} 479 480ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 481{ 482 time_t start, end; 483 double diff; 484 unsigned long N = 0; 485 486 /* 487 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 488 * This test body isn't specific to this race, however it's just good 489 * enough for this purposes, no need to invent a dedicated code flow. 490 */ 491 492 start = time(NULL); 493 while (true) { 494 DPRINTF("Step: %lu\n", N); 495 tracer_sees_terminaton_before_the_parent_raw(true, false, 496 false); 497 end = time(NULL); 498 diff = difftime(end, start); 499 if (diff >= 5.0) 500 break; 501 ++N; 502 } 503 DPRINTF("Iterations: %lu\n", N); 504} 505 506ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 507ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 508{ 509 atf_tc_set_md_var(tc, "descr", 510 "Assert that tracer sees process termination before the parent"); 511} 512 513ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 514{ 515 516 tracer_sees_terminaton_before_the_parent_raw(false, true, false); 517} 518 519ATF_TC(tracer_attach_to_unrelated_stopped_process); 520ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 521{ 522 atf_tc_set_md_var(tc, "descr", 523 "Assert that tracer can attach to an unrelated stopped process"); 524} 525 526ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 527{ 528 529 tracer_sees_terminaton_before_the_parent_raw(false, true, true); 530} 531#endif 532 533/// ---------------------------------------------------------------------------- 534 535static void 536parent_attach_to_its_child(bool stopped) 537{ 538 struct msg_fds parent_tracee; 539 const int exitval_tracee = 5; 540 pid_t tracee, wpid; 541 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 542#if defined(TWAIT_HAVE_STATUS) 543 int status; 544#endif 545 546 DPRINTF("Spawn tracee\n"); 547 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 548 tracee = atf_utils_fork(); 549 if (tracee == 0) { 550 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 551 DPRINTF("Parent should now attach to tracee\n"); 552 553 if (stopped) { 554 DPRINTF("Stop self PID %d\n", getpid()); 555 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 556 } 557 558 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 559 /* Wait for message from the parent */ 560 _exit(exitval_tracee); 561 } 562 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 563 564 if (stopped) { 565 DPRINTF("Await for a stopped tracee PID %d\n", tracee); 566 await_stopped(tracee); 567 } 568 569 DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 570 SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 571 572 DPRINTF("Wait for the stopped tracee process with %s()\n", 573 TWAIT_FNAME); 574 TWAIT_REQUIRE_SUCCESS( 575 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 576 577 validate_status_stopped(status, SIGSTOP); 578 579 DPRINTF("Resume tracee with PT_CONTINUE\n"); 580 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 581 582 DPRINTF("Let the tracee exit now\n"); 583 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 584 585 DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 586 TWAIT_REQUIRE_SUCCESS( 587 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 588 589 validate_status_exited(status, exitval_tracee); 590 591 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 592 TWAIT_REQUIRE_FAILURE(ECHILD, 593 wpid = TWAIT_GENERIC(tracee, &status, 0)); 594 595 msg_close(&parent_tracee); 596} 597 598ATF_TC(parent_attach_to_its_child); 599ATF_TC_HEAD(parent_attach_to_its_child, tc) 600{ 601 atf_tc_set_md_var(tc, "descr", 602 "Assert that tracer parent can PT_ATTACH to its child"); 603} 604 605ATF_TC_BODY(parent_attach_to_its_child, tc) 606{ 607 608 parent_attach_to_its_child(false); 609} 610 611ATF_TC(parent_attach_to_its_stopped_child); 612ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 613{ 614 atf_tc_set_md_var(tc, "descr", 615 "Assert that tracer parent can PT_ATTACH to its stopped child"); 616} 617 618ATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 619{ 620 621 parent_attach_to_its_child(true); 622} 623 624/// ---------------------------------------------------------------------------- 625 626static void 627child_attach_to_its_parent(bool stopped) 628{ 629 struct msg_fds parent_tracee; 630 const int exitval_tracer = 5; 631 pid_t tracer, wpid; 632 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 633#if defined(TWAIT_HAVE_STATUS) 634 int status; 635#endif 636 637 DPRINTF("Spawn tracer\n"); 638 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 639 tracer = atf_utils_fork(); 640 if (tracer == 0) { 641 /* Wait for message from the parent */ 642 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 643 644 if (stopped) { 645 DPRINTF("Await for a stopped parent PID %d\n", 646 getppid()); 647 await_stopped(getppid()); 648 } 649 650 DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 651 getppid()); 652 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 653 654 DPRINTF("Wait for the stopped parent process with %s()\n", 655 TWAIT_FNAME); 656 FORKEE_REQUIRE_SUCCESS( 657 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 658 659 forkee_status_stopped(status, SIGSTOP); 660 661 DPRINTF("Resume parent with PT_DETACH\n"); 662 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 663 != -1); 664 665 /* Tell parent we are ready */ 666 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 667 668 _exit(exitval_tracer); 669 } 670 671 DPRINTF("Wait for the tracer to become ready\n"); 672 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 673 674 if (stopped) { 675 DPRINTF("Stop self PID %d\n", getpid()); 676 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 677 } 678 679 DPRINTF("Allow the tracer to exit now\n"); 680 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 681 682 DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 683 TWAIT_REQUIRE_SUCCESS( 684 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 685 686 validate_status_exited(status, exitval_tracer); 687 688 DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 689 TWAIT_REQUIRE_FAILURE(ECHILD, 690 wpid = TWAIT_GENERIC(tracer, &status, 0)); 691 692 msg_close(&parent_tracee); 693} 694 695ATF_TC(child_attach_to_its_parent); 696ATF_TC_HEAD(child_attach_to_its_parent, tc) 697{ 698 atf_tc_set_md_var(tc, "descr", 699 "Assert that tracer child can PT_ATTACH to its parent"); 700} 701 702ATF_TC_BODY(child_attach_to_its_parent, tc) 703{ 704 705 child_attach_to_its_parent(false); 706} 707 708ATF_TC(child_attach_to_its_stopped_parent); 709ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 710{ 711 atf_tc_set_md_var(tc, "descr", 712 "Assert that tracer child can PT_ATTACH to its stopped parent"); 713} 714 715ATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 716{ 717 /* 718 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 719 * this causes a pipe (established from atf-run) to be broken. 720 * atf-run uses this mechanism to monitor whether a test is alive. 721 * 722 * As a workaround spawn this test as a subprocess. 723 */ 724 725 const int exitval = 15; 726 pid_t child, wpid; 727#if defined(TWAIT_HAVE_STATUS) 728 int status; 729#endif 730 731 SYSCALL_REQUIRE((child = fork()) != -1); 732 if (child == 0) { 733 child_attach_to_its_parent(true); 734 _exit(exitval); 735 } else { 736 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 737 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 738 739 validate_status_exited(status, exitval); 740 741 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 742 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 743 } 744} 745 746/// ---------------------------------------------------------------------------- 747 748#if defined(TWAIT_HAVE_PID) 749 750enum tracee_sees_its_original_parent_type { 751 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 752 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 753 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 754}; 755 756static void 757tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 758{ 759 struct msg_fds parent_tracer, parent_tracee; 760 const int exitval_tracee = 5; 761 const int exitval_tracer = 10; 762 pid_t parent, tracee, tracer, wpid; 763 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 764#if defined(TWAIT_HAVE_STATUS) 765 int status; 766#endif 767 /* sysctl(3) - kinfo_proc2 */ 768 int name[CTL_MAXNAME]; 769 struct kinfo_proc2 kp; 770 size_t len = sizeof(kp); 771 unsigned int namelen; 772 773 /* procfs - status */ 774 FILE *fp; 775 struct stat st; 776 const char *fname = "/proc/curproc/status"; 777 char s_executable[MAXPATHLEN]; 778 int s_pid, s_ppid; 779 int rv; 780 781 if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 782 SYSCALL_REQUIRE( 783 (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 784 if (rv != 0) 785 atf_tc_skip("/proc/curproc/status not found"); 786 } 787 788 DPRINTF("Spawn tracee\n"); 789 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 790 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 791 tracee = atf_utils_fork(); 792 if (tracee == 0) { 793 parent = getppid(); 794 795 /* Emit message to the parent */ 796 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 797 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 798 799 switch (type) { 800 case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 801 FORKEE_ASSERT_EQ(parent, getppid()); 802 break; 803 case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 804 namelen = 0; 805 name[namelen++] = CTL_KERN; 806 name[namelen++] = KERN_PROC2; 807 name[namelen++] = KERN_PROC_PID; 808 name[namelen++] = getpid(); 809 name[namelen++] = len; 810 name[namelen++] = 1; 811 812 FORKEE_ASSERT_EQ( 813 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 814 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 815 break; 816 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 817 /* 818 * Format: 819 * EXECUTABLE PID PPID ... 820 */ 821 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 822 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 823 FORKEE_ASSERT_EQ(fclose(fp), 0); 824 FORKEE_ASSERT_EQ(parent, s_ppid); 825 break; 826 } 827 828 _exit(exitval_tracee); 829 } 830 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 831 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 832 833 DPRINTF("Spawn debugger\n"); 834 tracer = atf_utils_fork(); 835 if (tracer == 0) { 836 /* No IPC to communicate with the child */ 837 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 838 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 839 840 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 841 FORKEE_REQUIRE_SUCCESS( 842 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 843 844 forkee_status_stopped(status, SIGSTOP); 845 846 /* Resume tracee with PT_CONTINUE */ 847 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 848 849 /* Inform parent that tracer has attached to tracee */ 850 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 851 852 /* Wait for parent to tell use that tracee should have exited */ 853 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 854 855 /* Wait for tracee and assert that it exited */ 856 FORKEE_REQUIRE_SUCCESS( 857 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 858 859 forkee_status_exited(status, exitval_tracee); 860 861 DPRINTF("Before exiting of the tracer process\n"); 862 _exit(exitval_tracer); 863 } 864 865 DPRINTF("Wait for the tracer to attach to the tracee\n"); 866 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 867 868 DPRINTF("Resume the tracee and let it exit\n"); 869 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 870 871 DPRINTF("Detect that tracee is zombie\n"); 872 await_zombie(tracee); 873 874 DPRINTF("Assert that there is no status about tracee - " 875 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 876 TWAIT_REQUIRE_SUCCESS( 877 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 878 879 DPRINTF("Tell the tracer child should have exited\n"); 880 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 881 882 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 883 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 884 tracer); 885 886 validate_status_exited(status, exitval_tracer); 887 888 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 889 TWAIT_FNAME); 890 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 891 tracee); 892 893 validate_status_exited(status, exitval_tracee); 894 895 msg_close(&parent_tracer); 896 msg_close(&parent_tracee); 897} 898 899#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 900ATF_TC(test); \ 901ATF_TC_HEAD(test, tc) \ 902{ \ 903 atf_tc_set_md_var(tc, "descr", \ 904 "Assert that tracee sees its original parent when being traced " \ 905 "(check " descr ")"); \ 906} \ 907 \ 908ATF_TC_BODY(test, tc) \ 909{ \ 910 \ 911 tracee_sees_its_original_parent(type); \ 912} 913 914TRACEE_SEES_ITS_ORIGINAL_PARENT( 915 tracee_sees_its_original_parent_getppid, 916 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 917 "getppid(2)"); 918TRACEE_SEES_ITS_ORIGINAL_PARENT( 919 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 920 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 921 "sysctl(3) and kinfo_proc2"); 922TRACEE_SEES_ITS_ORIGINAL_PARENT( 923 tracee_sees_its_original_parent_procfs_status, 924 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 925 "the status file in procfs"); 926#endif 927 928/// ---------------------------------------------------------------------------- 929 930static void 931ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 932{ 933 const int exitval = 5; 934 const int sigval = SIGINT; 935 const int sigfaked = SIGTRAP; 936 const int sicodefaked = TRAP_BRKPT; 937 pid_t child, wpid; 938 struct sigaction sa; 939#if defined(TWAIT_HAVE_STATUS) 940 int status; 941#endif 942 struct ptrace_siginfo info; 943 memset(&info, 0, sizeof(info)); 944 945 DPRINTF("Before forking process PID=%d\n", getpid()); 946 SYSCALL_REQUIRE((child = fork()) != -1); 947 if (child == 0) { 948 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 949 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 950 951 sa.sa_sigaction = sah; 952 sa.sa_flags = SA_SIGINFO; 953 sigemptyset(&sa.sa_mask); 954 955 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 956 != -1); 957 958 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 959 FORKEE_ASSERT(raise(sigval) == 0); 960 961 FORKEE_ASSERT_EQ(*signal_caught, 1); 962 963 DPRINTF("Before exiting of the child process\n"); 964 _exit(exitval); 965 } 966 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 967 968 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 969 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 970 971 validate_status_stopped(status, sigval); 972 973 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 974 SYSCALL_REQUIRE( 975 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 976 977 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 978 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 979 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 980 info.psi_siginfo.si_errno); 981 982 if (faked) { 983 DPRINTF("Before setting new faked signal to signo=%d " 984 "si_code=%d\n", sigfaked, sicodefaked); 985 info.psi_siginfo.si_signo = sigfaked; 986 info.psi_siginfo.si_code = sicodefaked; 987 } 988 989 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 990 SYSCALL_REQUIRE( 991 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 992 993 if (faked) { 994 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 995 "child\n"); 996 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 997 sizeof(info)) != -1); 998 999 DPRINTF("Before checking siginfo_t\n"); 1000 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 1001 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 1002 } 1003 1004 DPRINTF("Before resuming the child process where it left off and " 1005 "without signal to be sent\n"); 1006 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 1007 faked ? sigfaked : sigval) != -1); 1008 1009 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1010 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1011 1012 validate_status_exited(status, exitval); 1013 1014 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1015 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1016} 1017 1018#define PTRACE_SIGINFO(test, faked) \ 1019ATF_TC(test); \ 1020ATF_TC_HEAD(test, tc) \ 1021{ \ 1022 atf_tc_set_md_var(tc, "descr", \ 1023 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 1024 "with%s setting signal to new value", faked ? "" : "out"); \ 1025} \ 1026 \ 1027static int test##_caught = 0; \ 1028 \ 1029static void \ 1030test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 1031{ \ 1032 if (faked) { \ 1033 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 1034 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 1035 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 1036 } else { \ 1037 FORKEE_ASSERT_EQ(sig, SIGINT); \ 1038 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 1039 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 1040 } \ 1041 \ 1042 ++ test##_caught; \ 1043} \ 1044 \ 1045ATF_TC_BODY(test, tc) \ 1046{ \ 1047 \ 1048 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 1049} 1050 1051PTRACE_SIGINFO(siginfo_set_unmodified, false) 1052PTRACE_SIGINFO(siginfo_set_faked, true) 1053 1054/// ---------------------------------------------------------------------------- 1055 1056static void 1057traceme_exec(bool masked, bool ignored) 1058{ 1059 const int sigval = SIGTRAP; 1060 pid_t child, wpid; 1061#if defined(TWAIT_HAVE_STATUS) 1062 int status; 1063#endif 1064 struct sigaction sa; 1065 struct ptrace_siginfo info; 1066 sigset_t intmask; 1067 struct kinfo_proc2 kp; 1068 size_t len = sizeof(kp); 1069 1070 int name[6]; 1071 const size_t namelen = __arraycount(name); 1072 ki_sigset_t kp_sigmask; 1073 ki_sigset_t kp_sigignore; 1074 1075 memset(&info, 0, sizeof(info)); 1076 1077 DPRINTF("Before forking process PID=%d\n", getpid()); 1078 SYSCALL_REQUIRE((child = fork()) != -1); 1079 if (child == 0) { 1080 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1081 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1082 1083 if (masked) { 1084 sigemptyset(&intmask); 1085 sigaddset(&intmask, sigval); 1086 sigprocmask(SIG_BLOCK, &intmask, NULL); 1087 } 1088 1089 if (ignored) { 1090 memset(&sa, 0, sizeof(sa)); 1091 sa.sa_handler = SIG_IGN; 1092 sigemptyset(&sa.sa_mask); 1093 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 1094 } 1095 1096 DPRINTF("Before calling execve(2) from child\n"); 1097 execlp("/bin/echo", "/bin/echo", NULL); 1098 1099 FORKEE_ASSERT(0 && "Not reached"); 1100 } 1101 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1102 1103 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1104 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1105 1106 validate_status_stopped(status, sigval); 1107 1108 name[0] = CTL_KERN, 1109 name[1] = KERN_PROC2, 1110 name[2] = KERN_PROC_PID; 1111 name[3] = getpid(); 1112 name[4] = sizeof(kp); 1113 name[5] = 1; 1114 1115 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1116 1117 if (masked) 1118 kp_sigmask = kp.p_sigmask; 1119 1120 if (ignored) 1121 kp_sigignore = kp.p_sigignore; 1122 1123 name[3] = getpid(); 1124 1125 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1126 1127 if (masked) { 1128 DPRINTF("kp_sigmask=" 1129 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1130 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1131 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1132 1133 DPRINTF("kp.p_sigmask=" 1134 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1135 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1136 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1137 1138 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 1139 sizeof(kp_sigmask))); 1140 } 1141 1142 if (ignored) { 1143 DPRINTF("kp_sigignore=" 1144 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1145 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1146 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1147 1148 DPRINTF("kp.p_sigignore=" 1149 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1150 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1151 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1152 1153 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 1154 sizeof(kp_sigignore))); 1155 } 1156 1157 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1158 SYSCALL_REQUIRE( 1159 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1160 1161 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1162 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1163 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1164 info.psi_siginfo.si_errno); 1165 1166 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1167 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1168 1169 DPRINTF("Before resuming the child process where it left off and " 1170 "without signal to be sent\n"); 1171 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1172 1173 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1174 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1175 1176 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1177 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1178} 1179 1180#define TRACEME_EXEC(test, masked, ignored) \ 1181ATF_TC(test); \ 1182ATF_TC_HEAD(test, tc) \ 1183{ \ 1184 atf_tc_set_md_var(tc, "descr", \ 1185 "Detect SIGTRAP TRAP_EXEC from " \ 1186 "child%s%s", masked ? " with masked signal" : "", \ 1187 masked ? " with ignored signal" : ""); \ 1188} \ 1189 \ 1190ATF_TC_BODY(test, tc) \ 1191{ \ 1192 \ 1193 traceme_exec(masked, ignored); \ 1194} 1195 1196TRACEME_EXEC(traceme_exec, false, false) 1197TRACEME_EXEC(traceme_signalmasked_exec, true, false) 1198TRACEME_EXEC(traceme_signalignored_exec, false, true) 1199 1200/// ---------------------------------------------------------------------------- 1201 1202#define TRACE_THREADS_NUM 100 1203 1204static volatile int done; 1205pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 1206 1207static void * 1208trace_threads_cb(void *arg __unused) 1209{ 1210 1211 pthread_mutex_lock(&trace_threads_mtx); 1212 done++; 1213 pthread_mutex_unlock(&trace_threads_mtx); 1214 1215 while (done < TRACE_THREADS_NUM) 1216 sched_yield(); 1217 1218 return NULL; 1219} 1220 1221static void 1222trace_threads(bool trace_create, bool trace_exit, bool masked) 1223{ 1224 const int sigval = SIGSTOP; 1225 pid_t child, wpid; 1226#if defined(TWAIT_HAVE_STATUS) 1227 int status; 1228#endif 1229 ptrace_state_t state; 1230 const int slen = sizeof(state); 1231 ptrace_event_t event; 1232 const int elen = sizeof(event); 1233 struct ptrace_siginfo info; 1234 1235 sigset_t intmask; 1236 1237 pthread_t t[TRACE_THREADS_NUM]; 1238 int rv; 1239 size_t n; 1240 lwpid_t lid; 1241 1242 /* Track created and exited threads */ 1243 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 1244 1245 DPRINTF("Before forking process PID=%d\n", getpid()); 1246 SYSCALL_REQUIRE((child = fork()) != -1); 1247 if (child == 0) { 1248 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1249 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1250 1251 if (masked) { 1252 sigemptyset(&intmask); 1253 sigaddset(&intmask, SIGTRAP); 1254 sigprocmask(SIG_BLOCK, &intmask, NULL); 1255 } 1256 1257 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1258 FORKEE_ASSERT(raise(sigval) == 0); 1259 1260 for (n = 0; n < __arraycount(t); n++) { 1261 rv = pthread_create(&t[n], NULL, trace_threads_cb, 1262 NULL); 1263 FORKEE_ASSERT(rv == 0); 1264 } 1265 1266 for (n = 0; n < __arraycount(t); n++) { 1267 rv = pthread_join(t[n], NULL); 1268 FORKEE_ASSERT(rv == 0); 1269 } 1270 1271 /* 1272 * There is race between _exit() and pthread_join() detaching 1273 * a thread. For simplicity kill the process after detecting 1274 * LWP events. 1275 */ 1276 while (true) 1277 continue; 1278 1279 FORKEE_ASSERT(0 && "Not reached"); 1280 } 1281 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1282 1283 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1284 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1285 1286 validate_status_stopped(status, sigval); 1287 1288 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1289 SYSCALL_REQUIRE( 1290 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1291 1292 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1293 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1294 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1295 info.psi_siginfo.si_errno); 1296 1297 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1298 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1299 1300 DPRINTF("Set LWP event mask for the child %d\n", child); 1301 memset(&event, 0, sizeof(event)); 1302 if (trace_create) 1303 event.pe_set_event |= PTRACE_LWP_CREATE; 1304 if (trace_exit) 1305 event.pe_set_event |= PTRACE_LWP_EXIT; 1306 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1307 1308 DPRINTF("Before resuming the child process where it left off and " 1309 "without signal to be sent\n"); 1310 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1311 1312 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 1313 DPRINTF("Before calling %s() for the child - expected stopped " 1314 "SIGTRAP\n", TWAIT_FNAME); 1315 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1316 child); 1317 1318 validate_status_stopped(status, SIGTRAP); 1319 1320 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1321 "child\n"); 1322 SYSCALL_REQUIRE( 1323 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1324 1325 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1326 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1327 "si_errno=%#x\n", 1328 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1329 info.psi_siginfo.si_errno); 1330 1331 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1332 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 1333 1334 SYSCALL_REQUIRE( 1335 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1336 1337 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 1338 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 1339 1340 lid = state.pe_lwp; 1341 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 1342 1343 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 1344 1345 DPRINTF("Before resuming the child process where it left off " 1346 "and without signal to be sent\n"); 1347 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1348 } 1349 1350 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 1351 DPRINTF("Before calling %s() for the child - expected stopped " 1352 "SIGTRAP\n", TWAIT_FNAME); 1353 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1354 child); 1355 1356 validate_status_stopped(status, SIGTRAP); 1357 1358 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1359 "child\n"); 1360 SYSCALL_REQUIRE( 1361 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1362 1363 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1364 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1365 "si_errno=%#x\n", 1366 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1367 info.psi_siginfo.si_errno); 1368 1369 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1370 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 1371 1372 SYSCALL_REQUIRE( 1373 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1374 1375 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 1376 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 1377 1378 lid = state.pe_lwp; 1379 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 1380 1381 if (trace_create) { 1382 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 1383 ATF_REQUIRE_EQ(*count, 1); 1384 *count = 0; 1385 } 1386 1387 DPRINTF("Before resuming the child process where it left off " 1388 "and without signal to be sent\n"); 1389 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1390 } 1391 1392 kill(child, SIGKILL); 1393 1394 DPRINTF("Before calling %s() for the child - expected exited\n", 1395 TWAIT_FNAME); 1396 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1397 1398 validate_status_signaled(status, SIGKILL, 0); 1399 1400 DPRINTF("Before calling %s() for the child - expected no process\n", 1401 TWAIT_FNAME); 1402 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1403} 1404 1405#define TRACE_THREADS(test, trace_create, trace_exit, mask) \ 1406ATF_TC(test); \ 1407ATF_TC_HEAD(test, tc) \ 1408{ \ 1409 atf_tc_set_md_var(tc, "descr", \ 1410 "Verify spawning threads with%s tracing LWP create and" \ 1411 "with%s tracing LWP exit", trace_create ? "" : "out", \ 1412 trace_exit ? "" : "out"); \ 1413} \ 1414 \ 1415ATF_TC_BODY(test, tc) \ 1416{ \ 1417 \ 1418 trace_threads(trace_create, trace_exit, mask); \ 1419} 1420 1421TRACE_THREADS(trace_thread_nolwpevents, false, false, false) 1422TRACE_THREADS(trace_thread_lwpexit, false, true, false) 1423TRACE_THREADS(trace_thread_lwpcreate, true, false, false) 1424TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false) 1425 1426TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true) 1427TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true) 1428TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true) 1429 1430/// ---------------------------------------------------------------------------- 1431 1432static void * 1433thread_and_exec_thread_cb(void *arg __unused) 1434{ 1435 1436 execlp("/bin/echo", "/bin/echo", NULL); 1437 1438 abort(); 1439} 1440 1441static void 1442threads_and_exec(void) 1443{ 1444 const int sigval = SIGSTOP; 1445 pid_t child, wpid; 1446#if defined(TWAIT_HAVE_STATUS) 1447 int status; 1448#endif 1449 ptrace_state_t state; 1450 const int slen = sizeof(state); 1451 ptrace_event_t event; 1452 const int elen = sizeof(event); 1453 struct ptrace_siginfo info; 1454 1455 pthread_t t; 1456 lwpid_t lid; 1457 1458 DPRINTF("Before forking process PID=%d\n", getpid()); 1459 SYSCALL_REQUIRE((child = fork()) != -1); 1460 if (child == 0) { 1461 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1462 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1463 1464 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1465 FORKEE_ASSERT(raise(sigval) == 0); 1466 1467 FORKEE_ASSERT(pthread_create(&t, NULL, 1468 thread_and_exec_thread_cb, NULL) == 0); 1469 1470 for (;;) 1471 continue; 1472 1473 FORKEE_ASSERT(0 && "Not reached"); 1474 } 1475 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1476 1477 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1478 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1479 1480 validate_status_stopped(status, sigval); 1481 1482 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1483 SYSCALL_REQUIRE( 1484 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1485 1486 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1487 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1488 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1489 info.psi_siginfo.si_errno); 1490 1491 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1492 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1493 1494 DPRINTF("Set LWP event mask for the child %d\n", child); 1495 memset(&event, 0, sizeof(event)); 1496 event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; 1497 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1498 1499 DPRINTF("Before resuming the child process where it left off and " 1500 "without signal to be sent\n"); 1501 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1502 1503 DPRINTF("Before calling %s() for the child - expected stopped " 1504 "SIGTRAP\n", TWAIT_FNAME); 1505 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1506 child); 1507 1508 validate_status_stopped(status, SIGTRAP); 1509 1510 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1511 "child\n"); 1512 SYSCALL_REQUIRE( 1513 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1514 1515 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1516 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1517 "si_errno=%#x\n", 1518 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1519 info.psi_siginfo.si_errno); 1520 1521 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1522 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 1523 1524 SYSCALL_REQUIRE( 1525 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1526 1527 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 1528 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 1529 1530 lid = state.pe_lwp; 1531 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 1532 1533 DPRINTF("Before resuming the child process where it left off " 1534 "and without signal to be sent\n"); 1535 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1536 1537 DPRINTF("Before calling %s() for the child - expected stopped " 1538 "SIGTRAP\n", TWAIT_FNAME); 1539 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1540 child); 1541 1542 validate_status_stopped(status, SIGTRAP); 1543 1544 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1545 "child\n"); 1546 SYSCALL_REQUIRE( 1547 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1548 1549 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1550 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1551 "si_errno=%#x\n", 1552 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1553 info.psi_siginfo.si_errno); 1554 1555 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1556 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 1557 1558 SYSCALL_REQUIRE( 1559 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1560 1561 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 1562 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 1563 1564 lid = state.pe_lwp; 1565 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 1566 1567 DPRINTF("Before resuming the child process where it left off " 1568 "and without signal to be sent\n"); 1569 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1570 1571 DPRINTF("Before calling %s() for the child - expected stopped " 1572 "SIGTRAP\n", TWAIT_FNAME); 1573 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1574 child); 1575 1576 validate_status_stopped(status, SIGTRAP); 1577 1578 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1579 "child\n"); 1580 SYSCALL_REQUIRE( 1581 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1582 1583 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1584 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1585 "si_errno=%#x\n", 1586 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1587 info.psi_siginfo.si_errno); 1588 1589 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1590 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1591 1592 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 1593 1594 DPRINTF("Before calling %s() for the child - expected exited\n", 1595 TWAIT_FNAME); 1596 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1597 1598 validate_status_signaled(status, SIGKILL, 0); 1599 1600 DPRINTF("Before calling %s() for the child - expected no process\n", 1601 TWAIT_FNAME); 1602 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1603} 1604 1605ATF_TC(threads_and_exec); 1606ATF_TC_HEAD(threads_and_exec, tc) 1607{ 1608 atf_tc_set_md_var(tc, "descr", 1609 "Verify that multithreaded application on exec() will report " 1610 "LWP_EXIT events"); 1611} 1612 1613ATF_TC_BODY(threads_and_exec, tc) 1614{ 1615 1616 threads_and_exec(); 1617} 1618 1619/// ---------------------------------------------------------------------------- 1620 1621ATF_TC(suspend_no_deadlock); 1622ATF_TC_HEAD(suspend_no_deadlock, tc) 1623{ 1624 atf_tc_set_md_var(tc, "descr", 1625 "Verify that the while the only thread within a process is " 1626 "suspended, the whole process cannot be unstopped"); 1627} 1628 1629ATF_TC_BODY(suspend_no_deadlock, tc) 1630{ 1631 const int exitval = 5; 1632 const int sigval = SIGSTOP; 1633 pid_t child, wpid; 1634#if defined(TWAIT_HAVE_STATUS) 1635 int status; 1636#endif 1637 struct ptrace_siginfo psi; 1638 1639 DPRINTF("Before forking process PID=%d\n", getpid()); 1640 SYSCALL_REQUIRE((child = fork()) != -1); 1641 if (child == 0) { 1642 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1643 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1644 1645 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1646 FORKEE_ASSERT(raise(sigval) == 0); 1647 1648 DPRINTF("Before exiting of the child process\n"); 1649 _exit(exitval); 1650 } 1651 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1652 1653 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1654 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1655 1656 validate_status_stopped(status, sigval); 1657 1658 DPRINTF("Before reading siginfo and lwpid_t\n"); 1659 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 1660 1661 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 1662 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 1663 1664 DPRINTF("Before resuming the child process where it left off and " 1665 "without signal to be sent\n"); 1666 ATF_REQUIRE_ERRNO(EDEADLK, 1667 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 1668 1669 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 1670 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 1671 1672 DPRINTF("Before resuming the child process where it left off and " 1673 "without signal to be sent\n"); 1674 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1675 1676 DPRINTF("Before calling %s() for the child - expected exited\n", 1677 TWAIT_FNAME); 1678 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1679 1680 validate_status_exited(status, exitval); 1681 1682 DPRINTF("Before calling %s() for the child - expected no process\n", 1683 TWAIT_FNAME); 1684 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1685} 1686 1687/// ---------------------------------------------------------------------------- 1688 1689static pthread_barrier_t barrier1_resume; 1690static pthread_barrier_t barrier2_resume; 1691 1692static void * 1693resume_thread(void *arg) 1694{ 1695 1696 raise(SIGUSR1); 1697 1698 pthread_barrier_wait(&barrier1_resume); 1699 1700 /* Debugger will suspend the process here */ 1701 1702 pthread_barrier_wait(&barrier2_resume); 1703 1704 raise(SIGUSR2); 1705 1706 return infinite_thread(arg); 1707} 1708 1709ATF_TC(resume); 1710ATF_TC_HEAD(resume, tc) 1711{ 1712 atf_tc_set_md_var(tc, "descr", 1713 "Verify that a thread can be suspended by a debugger and later " 1714 "resumed by the debugger"); 1715} 1716 1717ATF_TC_BODY(resume, tc) 1718{ 1719 const int sigval = SIGSTOP; 1720 pid_t child, wpid; 1721#if defined(TWAIT_HAVE_STATUS) 1722 int status; 1723#endif 1724 lwpid_t lid; 1725 struct ptrace_siginfo psi; 1726 pthread_t t; 1727 1728 DPRINTF("Before forking process PID=%d\n", getpid()); 1729 SYSCALL_REQUIRE((child = fork()) != -1); 1730 if (child == 0) { 1731 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1732 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1733 1734 pthread_barrier_init(&barrier1_resume, NULL, 2); 1735 pthread_barrier_init(&barrier2_resume, NULL, 2); 1736 1737 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1738 FORKEE_ASSERT(raise(sigval) == 0); 1739 1740 DPRINTF("Before creating new thread in child\n"); 1741 FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0); 1742 1743 pthread_barrier_wait(&barrier1_resume); 1744 1745 pthread_barrier_wait(&barrier2_resume); 1746 1747 infinite_thread(NULL); 1748 } 1749 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1750 1751 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1752 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1753 1754 validate_status_stopped(status, sigval); 1755 1756 DPRINTF("Before resuming the child process where it left off and " 1757 "without signal to be sent\n"); 1758 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1759 1760 DPRINTF("Before calling %s() for the child - expected stopped " 1761 "SIGUSR1\n", TWAIT_FNAME); 1762 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1763 1764 validate_status_stopped(status, SIGUSR1); 1765 1766 DPRINTF("Before reading siginfo and lwpid_t\n"); 1767 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 1768 1769 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 1770 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 1771 1772 lid = psi.psi_lwpid; 1773 1774 DPRINTF("Before resuming the child process where it left off and " 1775 "without signal to be sent\n"); 1776 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1777 1778 DPRINTF("Before suspending the parent for 1 second, we expect no signals\n"); 1779 SYSCALL_REQUIRE(sleep(1) == 0); 1780 1781#if defined(TWAIT_HAVE_OPTIONS) 1782 DPRINTF("Before calling %s() for the child - expected no status\n", 1783 TWAIT_FNAME); 1784 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0); 1785#endif 1786 1787 DPRINTF("Before resuming the child process where it left off and " 1788 "without signal to be sent\n"); 1789 SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1); 1790 1791 DPRINTF("Before calling %s() for the child - expected stopped " 1792 "SIGSTOP\n", TWAIT_FNAME); 1793 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1794 1795 validate_status_stopped(status, SIGSTOP); 1796 1797 DPRINTF("Before resuming LWP %d\n", lid); 1798 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1); 1799 1800 DPRINTF("Before resuming the child process where it left off and " 1801 "without signal to be sent\n"); 1802 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1803 1804 DPRINTF("Before calling %s() for the child - expected stopped " 1805 "SIGUSR2\n", TWAIT_FNAME); 1806 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1807 1808 validate_status_stopped(status, SIGUSR2); 1809 1810 DPRINTF("Before resuming the child process where it left off and " 1811 "without signal to be sent\n"); 1812 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 1813 1814 DPRINTF("Before calling %s() for the child - expected exited\n", 1815 TWAIT_FNAME); 1816 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1817 1818 validate_status_signaled(status, SIGKILL, 0); 1819 1820 DPRINTF("Before calling %s() for the child - expected no process\n", 1821 TWAIT_FNAME); 1822 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1823} 1824 1825/// ---------------------------------------------------------------------------- 1826 1827static void 1828user_va0_disable(int operation) 1829{ 1830 pid_t child, wpid; 1831#if defined(TWAIT_HAVE_STATUS) 1832 int status; 1833#endif 1834 const int sigval = SIGSTOP; 1835 int rv; 1836 1837 struct ptrace_siginfo info; 1838 1839 if (get_user_va0_disable() == 0) 1840 atf_tc_skip("vm.user_va0_disable is set to 0"); 1841 1842 memset(&info, 0, sizeof(info)); 1843 1844 DPRINTF("Before forking process PID=%d\n", getpid()); 1845 SYSCALL_REQUIRE((child = fork()) != -1); 1846 if (child == 0) { 1847 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1848 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1849 1850 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1851 FORKEE_ASSERT(raise(sigval) == 0); 1852 1853 /* NOTREACHED */ 1854 FORKEE_ASSERTX(0 && "This shall not be reached"); 1855 __unreachable(); 1856 } 1857 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1858 1859 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1860 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1861 1862 validate_status_stopped(status, sigval); 1863 1864 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1865 "child\n"); 1866 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1867 sizeof(info)) != -1); 1868 1869 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1870 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1871 "si_errno=%#x\n", 1872 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1873 info.psi_siginfo.si_errno); 1874 1875 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1876 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1877 1878 DPRINTF("Before resuming the child process in PC=0x0 " 1879 "and without signal to be sent\n"); 1880 errno = 0; 1881 rv = ptrace(operation, child, (void *)0, 0); 1882 ATF_REQUIRE_EQ(errno, EINVAL); 1883 ATF_REQUIRE_EQ(rv, -1); 1884 1885 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 1886 1887 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1888 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1889 validate_status_signaled(status, SIGKILL, 0); 1890 1891 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1892 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1893} 1894 1895#define USER_VA0_DISABLE(test, operation) \ 1896ATF_TC(test); \ 1897ATF_TC_HEAD(test, tc) \ 1898{ \ 1899 atf_tc_set_md_var(tc, "descr", \ 1900 "Verify behavior of " #operation " with PC set to 0x0"); \ 1901} \ 1902 \ 1903ATF_TC_BODY(test, tc) \ 1904{ \ 1905 \ 1906 user_va0_disable(operation); \ 1907} 1908 1909USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 1910USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 1911USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 1912 1913/// ---------------------------------------------------------------------------- 1914 1915/* 1916 * Parse the core file and find the requested note. If the reading or parsing 1917 * fails, the test is failed. If the note is found, it is read onto buf, up to 1918 * buf_len. The actual length of the note is returned (which can be greater 1919 * than buf_len, indicating that it has been truncated). If the note is not 1920 * found, -1 is returned. 1921 * 1922 * If the note_name ends in '*', then we find the first note that matches 1923 * the note_name prefix up to the '*' character, e.g.: 1924 * 1925 * NetBSD-CORE@* 1926 * 1927 * finds the first note whose name prefix matches "NetBSD-CORE@". 1928 */ 1929static ssize_t core_find_note(const char *core_path, 1930 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 1931{ 1932 int core_fd; 1933 Elf *core_elf; 1934 size_t core_numhdr, i; 1935 ssize_t ret = -1; 1936 size_t name_len = strlen(note_name); 1937 bool prefix_match = false; 1938 1939 if (note_name[name_len - 1] == '*') { 1940 prefix_match = true; 1941 name_len--; 1942 } else { 1943 /* note: we assume note name will be null-terminated */ 1944 name_len++; 1945 } 1946 1947 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 1948 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 1949 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 1950 1951 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 1952 for (i = 0; i < core_numhdr && ret == -1; i++) { 1953 GElf_Phdr core_hdr; 1954 size_t offset; 1955 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 1956 if (core_hdr.p_type != PT_NOTE) 1957 continue; 1958 1959 for (offset = core_hdr.p_offset; 1960 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 1961 Elf64_Nhdr note_hdr; 1962 char name_buf[64]; 1963 1964 switch (gelf_getclass(core_elf)) { 1965 case ELFCLASS64: 1966 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 1967 sizeof(note_hdr), offset) 1968 == sizeof(note_hdr)); 1969 offset += sizeof(note_hdr); 1970 break; 1971 case ELFCLASS32: 1972 { 1973 Elf32_Nhdr tmp_hdr; 1974 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 1975 sizeof(tmp_hdr), offset) 1976 == sizeof(tmp_hdr)); 1977 offset += sizeof(tmp_hdr); 1978 note_hdr.n_namesz = tmp_hdr.n_namesz; 1979 note_hdr.n_descsz = tmp_hdr.n_descsz; 1980 note_hdr.n_type = tmp_hdr.n_type; 1981 } 1982 break; 1983 } 1984 1985 /* indicates end of notes */ 1986 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 1987 break; 1988 if (((prefix_match && 1989 note_hdr.n_namesz > name_len) || 1990 (!prefix_match && 1991 note_hdr.n_namesz == name_len)) && 1992 note_hdr.n_namesz <= sizeof(name_buf)) { 1993 SYSCALL_REQUIRE(pread(core_fd, name_buf, 1994 note_hdr.n_namesz, offset) 1995 == (ssize_t)(size_t)note_hdr.n_namesz); 1996 1997 if (!strncmp(note_name, name_buf, name_len) && 1998 note_hdr.n_type == note_type) 1999 ret = note_hdr.n_descsz; 2000 } 2001 2002 offset += note_hdr.n_namesz; 2003 /* fix to alignment */ 2004 offset = roundup(offset, core_hdr.p_align); 2005 2006 /* if name & type matched above */ 2007 if (ret != -1) { 2008 ssize_t read_len = MIN(buf_len, 2009 note_hdr.n_descsz); 2010 SYSCALL_REQUIRE(pread(core_fd, buf, 2011 read_len, offset) == read_len); 2012 break; 2013 } 2014 2015 offset += note_hdr.n_descsz; 2016 /* fix to alignment */ 2017 offset = roundup(offset, core_hdr.p_align); 2018 } 2019 } 2020 2021 elf_end(core_elf); 2022 close(core_fd); 2023 2024 return ret; 2025} 2026 2027ATF_TC(core_dump_procinfo); 2028ATF_TC_HEAD(core_dump_procinfo, tc) 2029{ 2030 atf_tc_set_md_var(tc, "descr", 2031 "Trigger a core dump and verify its contents."); 2032} 2033 2034ATF_TC_BODY(core_dump_procinfo, tc) 2035{ 2036 const int exitval = 5; 2037 pid_t child, wpid; 2038#if defined(TWAIT_HAVE_STATUS) 2039 const int sigval = SIGTRAP; 2040 int status; 2041#endif 2042 char core_path[] = "/tmp/core.XXXXXX"; 2043 int core_fd; 2044 struct netbsd_elfcore_procinfo procinfo; 2045 2046 DPRINTF("Before forking process PID=%d\n", getpid()); 2047 SYSCALL_REQUIRE((child = fork()) != -1); 2048 if (child == 0) { 2049 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2050 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2051 2052 DPRINTF("Before triggering SIGTRAP\n"); 2053 trigger_trap(); 2054 2055 DPRINTF("Before exiting of the child process\n"); 2056 _exit(exitval); 2057 } 2058 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2059 2060 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2061 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2062 2063 validate_status_stopped(status, sigval); 2064 2065 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 2066 close(core_fd); 2067 2068 DPRINTF("Call DUMPCORE for the child process\n"); 2069 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 2070 != -1); 2071 2072 DPRINTF("Read core file\n"); 2073 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 2074 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 2075 sizeof(procinfo)); 2076 2077 ATF_CHECK_EQ(procinfo.cpi_version, 1); 2078 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 2079 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 2080 ATF_CHECK_EQ(procinfo.cpi_pid, child); 2081 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 2082 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 2083 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 2084 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 2085 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 2086 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 2087 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 2088 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 2089 ATF_CHECK(procinfo.cpi_siglwp > 0); 2090 2091 unlink(core_path); 2092 2093 DPRINTF("Before resuming the child process where it left off and " 2094 "without signal to be sent\n"); 2095 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2096 2097 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2098 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2099 2100 validate_status_exited(status, exitval); 2101 2102 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2103 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2104} 2105 2106/// ---------------------------------------------------------------------------- 2107 2108#if defined(TWAIT_HAVE_STATUS) 2109 2110#define THREAD_CONCURRENT_BREAKPOINT_NUM 50 2111#define THREAD_CONCURRENT_SIGNALS_NUM 50 2112#define THREAD_CONCURRENT_WATCHPOINT_NUM 50 2113 2114/* List of signals to use for the test */ 2115const int thread_concurrent_signals_list[] = { 2116 SIGIO, 2117 SIGXCPU, 2118 SIGXFSZ, 2119 SIGVTALRM, 2120 SIGPROF, 2121 SIGWINCH, 2122 SIGINFO, 2123 SIGUSR1, 2124 SIGUSR2 2125}; 2126 2127enum thread_concurrent_signal_handling { 2128 /* the signal is discarded by debugger */ 2129 TCSH_DISCARD, 2130 /* the handler is set to SIG_IGN */ 2131 TCSH_SIG_IGN, 2132 /* an actual handler is used */ 2133 TCSH_HANDLER 2134}; 2135 2136static pthread_barrier_t thread_concurrent_barrier; 2137static pthread_key_t thread_concurrent_key; 2138static uint32_t thread_concurrent_watchpoint_var = 0; 2139 2140static void * 2141thread_concurrent_breakpoint_thread(void *arg) 2142{ 2143 static volatile int watchme = 1; 2144 pthread_barrier_wait(&thread_concurrent_barrier); 2145 DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self()); 2146 check_happy(watchme); 2147 return NULL; 2148} 2149 2150static void 2151thread_concurrent_sig_handler(int sig) 2152{ 2153 void *tls_val = pthread_getspecific(thread_concurrent_key); 2154 DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 2155 FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key, 2156 (void*)((uintptr_t)tls_val + 1)) == 0); 2157} 2158 2159static void * 2160thread_concurrent_signals_thread(void *arg) 2161{ 2162 int sigval = thread_concurrent_signals_list[ 2163 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 2164 enum thread_concurrent_signal_handling *signal_handle = arg; 2165 void *tls_val; 2166 2167 pthread_barrier_wait(&thread_concurrent_barrier); 2168 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 2169 _lwp_self()); 2170 pthread_kill(pthread_self(), sigval); 2171 if (*signal_handle == TCSH_HANDLER) { 2172 tls_val = pthread_getspecific(thread_concurrent_key); 2173 DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 2174 FORKEE_ASSERT(tls_val == (void*)1); 2175 } 2176 return NULL; 2177} 2178 2179static void * 2180thread_concurrent_watchpoint_thread(void *arg) 2181{ 2182 pthread_barrier_wait(&thread_concurrent_barrier); 2183 DPRINTF("Before modifying var from LWP %d\n", _lwp_self()); 2184 thread_concurrent_watchpoint_var = 1; 2185 return NULL; 2186} 2187 2188#if defined(__i386__) || defined(__x86_64__) 2189enum thread_concurrent_sigtrap_event { 2190 TCSE_UNKNOWN, 2191 TCSE_BREAKPOINT, 2192 TCSE_WATCHPOINT 2193}; 2194 2195static void 2196thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid); 2197static enum thread_concurrent_sigtrap_event 2198thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info); 2199#endif 2200 2201static void 2202thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle, 2203 int breakpoint_threads, int signal_threads, int watchpoint_threads) 2204{ 2205 const int exitval = 5; 2206 const int sigval = SIGSTOP; 2207 pid_t child, wpid; 2208 int status; 2209 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 2210 = {{0, 0}}; 2211 struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 2212 = {{0, 0}}; 2213 struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 2214 = {{0, 0}}; 2215 ptrace_event_t event; 2216 int i; 2217 2218#if defined(HAVE_DBREGS) 2219 if (!can_we_set_dbregs()) { 2220 atf_tc_skip("Either run this test as root or set sysctl(3) " 2221 "security.models.extensions.user_set_dbregs to 1"); 2222 } 2223#endif 2224 2225 atf_tc_skip("PR kern/54960"); 2226 2227 /* Protect against out-of-bounds array access. */ 2228 ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM); 2229 ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM); 2230 ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM); 2231 2232 DPRINTF("Before forking process PID=%d\n", getpid()); 2233 SYSCALL_REQUIRE((child = fork()) != -1); 2234 if (child == 0) { 2235 pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM]; 2236 pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM]; 2237 pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM]; 2238 2239 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2240 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2241 2242 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2243 FORKEE_ASSERT(raise(sigval) == 0); 2244 2245 if (signal_handle != TCSH_DISCARD) { 2246 struct sigaction sa; 2247 unsigned int j; 2248 2249 memset(&sa, 0, sizeof(sa)); 2250 if (signal_handle == TCSH_SIG_IGN) 2251 sa.sa_handler = SIG_IGN; 2252 else 2253 sa.sa_handler = thread_concurrent_sig_handler; 2254 sigemptyset(&sa.sa_mask); 2255 2256 for (j = 0; 2257 j < __arraycount(thread_concurrent_signals_list); 2258 j++) 2259 FORKEE_ASSERT(sigaction( 2260 thread_concurrent_signals_list[j], &sa, NULL) 2261 != -1); 2262 } 2263 2264 DPRINTF("Before starting threads from the child\n"); 2265 FORKEE_ASSERT(pthread_barrier_init( 2266 &thread_concurrent_barrier, NULL, 2267 breakpoint_threads + signal_threads + watchpoint_threads) 2268 == 0); 2269 FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL) 2270 == 0); 2271 2272 for (i = 0; i < signal_threads; i++) { 2273 FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL, 2274 thread_concurrent_signals_thread, 2275 &signal_handle) == 0); 2276 } 2277 for (i = 0; i < breakpoint_threads; i++) { 2278 FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL, 2279 thread_concurrent_breakpoint_thread, NULL) == 0); 2280 } 2281 for (i = 0; i < watchpoint_threads; i++) { 2282 FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL, 2283 thread_concurrent_watchpoint_thread, NULL) == 0); 2284 } 2285 2286 DPRINTF("Before joining threads from the child\n"); 2287 for (i = 0; i < watchpoint_threads; i++) { 2288 FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0); 2289 } 2290 for (i = 0; i < breakpoint_threads; i++) { 2291 FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0); 2292 } 2293 for (i = 0; i < signal_threads; i++) { 2294 FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0); 2295 } 2296 2297 FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0); 2298 FORKEE_ASSERT(pthread_barrier_destroy( 2299 &thread_concurrent_barrier) == 0); 2300 2301 DPRINTF("Before exiting of the child process\n"); 2302 _exit(exitval); 2303 } 2304 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2305 2306 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2307 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2308 2309 validate_status_stopped(status, sigval); 2310 2311 DPRINTF("Set LWP event mask for the child process\n"); 2312 memset(&event, 0, sizeof(event)); 2313 event.pe_set_event |= PTRACE_LWP_CREATE; 2314 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event)) 2315 != -1); 2316 2317 DPRINTF("Before resuming the child process where it left off\n"); 2318 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2319 2320 DPRINTF("Before entering signal collection loop\n"); 2321 while (1) { 2322 ptrace_siginfo_t info; 2323 2324 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2325 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2326 child); 2327 if (WIFEXITED(status)) 2328 break; 2329 /* Note: we use validate_status_stopped() to get nice error 2330 * message. Signal is irrelevant since it won't be reached. 2331 */ 2332 else if (!WIFSTOPPED(status)) 2333 validate_status_stopped(status, 0); 2334 2335 DPRINTF("Before calling PT_GET_SIGINFO\n"); 2336 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 2337 sizeof(info)) != -1); 2338 2339 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 2340 info.psi_siginfo.si_signo, info.psi_lwpid, 2341 WSTOPSIG(status)); 2342 2343 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status), 2344 "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid, 2345 WSTOPSIG(status), info.psi_siginfo.si_signo); 2346 2347 if (WSTOPSIG(status) != SIGTRAP) { 2348 int expected_sig = 2349 thread_concurrent_signals_list[info.psi_lwpid % 2350 __arraycount(thread_concurrent_signals_list)]; 2351 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 2352 "lwp=%d, expected %d, got %d", info.psi_lwpid, 2353 expected_sig, WSTOPSIG(status)); 2354 2355 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 2356 } else if (info.psi_siginfo.si_code == TRAP_LWP) { 2357#if defined(__i386__) || defined(__x86_64__) 2358 thread_concurrent_lwp_setup(child, info.psi_lwpid); 2359#endif 2360 } else { 2361#if defined(__i386__) || defined(__x86_64__) 2362 switch (thread_concurrent_handle_sigtrap(child, &info)) { 2363 case TCSE_UNKNOWN: 2364 /* already reported inside the function */ 2365 break; 2366 case TCSE_BREAKPOINT: 2367 *FIND_EVENT_COUNT(bp_counts, 2368 info.psi_lwpid) += 1; 2369 break; 2370 case TCSE_WATCHPOINT: 2371 *FIND_EVENT_COUNT(wp_counts, 2372 info.psi_lwpid) += 1; 2373 break; 2374 } 2375#else 2376 ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n", 2377 info.psi_siginfo.si_code); 2378#endif 2379 } 2380 2381 DPRINTF("Before resuming the child process\n"); 2382 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 2383 signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP 2384 ? WSTOPSIG(status) : 0) != -1); 2385 } 2386 2387 for (i = 0; i < signal_threads; i++) 2388 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 2389 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 2390 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 2391 for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++) 2392 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0, 2393 "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d", 2394 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 2395 2396 for (i = 0; i < breakpoint_threads; i++) 2397 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1, 2398 "bp_counts[%d].lec_count=%d; lec_lwp=%d", 2399 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 2400 for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++) 2401 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0, 2402 "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d", 2403 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 2404 2405 for (i = 0; i < watchpoint_threads; i++) 2406 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1, 2407 "wp_counts[%d].lec_count=%d; lec_lwp=%d", 2408 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 2409 for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++) 2410 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0, 2411 "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d", 2412 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 2413 2414 validate_status_exited(status, exitval); 2415} 2416 2417#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr) \ 2418ATF_TC(test); \ 2419ATF_TC_HEAD(test, tc) \ 2420{ \ 2421 atf_tc_set_md_var(tc, "descr", descr); \ 2422} \ 2423 \ 2424ATF_TC_BODY(test, tc) \ 2425{ \ 2426 thread_concurrent_test(sig_hdl, bps, sigs, wps); \ 2427} 2428 2429THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD, 2430 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 2431 "Verify that concurrent signals issued to a single thread are reported " 2432 "correctly"); 2433THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN, 2434 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 2435 "Verify that concurrent signals issued to a single thread are reported " 2436 "correctly and passed back to SIG_IGN handler"); 2437THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER, 2438 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 2439 "Verify that concurrent signals issued to a single thread are reported " 2440 "correctly and passed back to a handler function"); 2441 2442#if defined(__i386__) || defined(__x86_64__) 2443THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD, 2444 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0, 2445 "Verify that concurrent breakpoints are reported correctly"); 2446THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD, 2447 0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 2448 "Verify that concurrent breakpoints are reported correctly"); 2449THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD, 2450 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 2451 "Verify that concurrent breakpoints and watchpoints are reported " 2452 "correctly"); 2453 2454THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD, 2455 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 2456 "Verify that concurrent breakpoints and signals are reported correctly"); 2457THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN, 2458 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 2459 "Verify that concurrent breakpoints and signals are reported correctly " 2460 "and passed back to SIG_IGN handler"); 2461THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER, 2462 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 2463 "Verify that concurrent breakpoints and signals are reported correctly " 2464 "and passed back to a handler function"); 2465 2466THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD, 2467 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 2468 "Verify that concurrent watchpoints and signals are reported correctly"); 2469THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN, 2470 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 2471 "Verify that concurrent watchpoints and signals are reported correctly " 2472 "and passed back to SIG_IGN handler"); 2473THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER, 2474 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 2475 "Verify that concurrent watchpoints and signals are reported correctly " 2476 "and passed back to a handler function"); 2477 2478THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD, 2479 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 2480 THREAD_CONCURRENT_WATCHPOINT_NUM, 2481 "Verify that concurrent breakpoints, watchpoints and signals are reported " 2482 "correctly"); 2483THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN, 2484 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 2485 THREAD_CONCURRENT_WATCHPOINT_NUM, 2486 "Verify that concurrent breakpoints, watchpoints and signals are reported " 2487 "correctly and passed back to SIG_IGN handler"); 2488THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER, 2489 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 2490 THREAD_CONCURRENT_WATCHPOINT_NUM, 2491 "Verify that concurrent breakpoints, watchpoints and signals are reported " 2492 "correctly and passed back to a handler function"); 2493#endif 2494 2495#endif /*defined(TWAIT_HAVE_STATUS)*/ 2496 2497/// ---------------------------------------------------------------------------- 2498 2499#include "t_ptrace_register_wait.h" 2500#include "t_ptrace_syscall_wait.h" 2501#include "t_ptrace_step_wait.h" 2502#include "t_ptrace_kill_wait.h" 2503#include "t_ptrace_bytetransfer_wait.h" 2504#include "t_ptrace_clone_wait.h" 2505#include "t_ptrace_fork_wait.h" 2506#include "t_ptrace_signal_wait.h" 2507#include "t_ptrace_eventmask_wait.h" 2508#include "t_ptrace_lwp_wait.h" 2509 2510/// ---------------------------------------------------------------------------- 2511 2512#include "t_ptrace_amd64_wait.h" 2513#include "t_ptrace_i386_wait.h" 2514#include "t_ptrace_x86_wait.h" 2515 2516/// ---------------------------------------------------------------------------- 2517 2518#else 2519ATF_TC(dummy); 2520ATF_TC_HEAD(dummy, tc) 2521{ 2522 atf_tc_set_md_var(tc, "descr", "A dummy test"); 2523} 2524 2525ATF_TC_BODY(dummy, tc) 2526{ 2527 2528 // Dummy, skipped 2529 // The ATF framework requires at least a single defined test. 2530} 2531#endif 2532 2533ATF_TP_ADD_TCS(tp) 2534{ 2535 setvbuf(stdout, NULL, _IONBF, 0); 2536 setvbuf(stderr, NULL, _IONBF, 0); 2537 2538#ifdef ENABLE_TESTS 2539 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 2540 2541 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 2542 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 2543 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 2544 2545 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 2546 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 2547 ATF_TP_ADD_TC_HAVE_PID(tp, 2548 unrelated_tracer_sees_terminaton_before_the_parent); 2549 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 2550 2551 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 2552 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 2553 2554 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 2555 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 2556 2557 ATF_TP_ADD_TC_HAVE_PID(tp, 2558 tracee_sees_its_original_parent_getppid); 2559 ATF_TP_ADD_TC_HAVE_PID(tp, 2560 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 2561 ATF_TP_ADD_TC_HAVE_PID(tp, 2562 tracee_sees_its_original_parent_procfs_status); 2563 2564 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 2565 ATF_TP_ADD_TC(tp, siginfo_set_faked); 2566 2567 ATF_TP_ADD_TC(tp, traceme_exec); 2568 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 2569 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 2570 2571 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 2572 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 2573 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 2574 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 2575 2576 ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap); 2577 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap); 2578 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap); 2579 2580 ATF_TP_ADD_TC(tp, threads_and_exec); 2581 2582 ATF_TP_ADD_TC(tp, suspend_no_deadlock); 2583 2584 ATF_TP_ADD_TC(tp, resume); 2585 2586 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 2587 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 2588 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 2589 2590 ATF_TP_ADD_TC(tp, core_dump_procinfo); 2591 2592#if defined(TWAIT_HAVE_STATUS) 2593 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 2594 ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign); 2595 ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler); 2596#if defined(__i386__) || defined(__x86_64__) 2597 ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints); 2598 ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints); 2599 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp); 2600 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig); 2601 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign); 2602 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler); 2603 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig); 2604 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign); 2605 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler); 2606 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig); 2607 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign); 2608 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler); 2609#endif 2610#endif 2611 2612 ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER(); 2613 ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL(); 2614 ATF_TP_ADD_TCS_PTRACE_WAIT_STEP(); 2615 ATF_TP_ADD_TCS_PTRACE_WAIT_KILL(); 2616 ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER(); 2617 ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE(); 2618 ATF_TP_ADD_TCS_PTRACE_WAIT_FORK(); 2619 ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL(); 2620 ATF_TP_ADD_TCS_PTRACE_WAIT_EVENTMASK(); 2621 ATF_TP_ADD_TCS_PTRACE_WAIT_LWP(); 2622 2623 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 2624 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 2625 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 2626 2627#else 2628 ATF_TP_ADD_TC(tp, dummy); 2629#endif 2630 2631 return atf_no_error(); 2632} 2633