1 /* $NetBSD: t_ptrace_fork_wait.h,v 1.7 2020/06/09 00:28:57 kamil Exp $ */ 2 3 /*- 4 * Copyright (c) 2016, 2017, 2018, 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 30 static void 31 fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork, 32 bool trackvforkdone, bool newpgrp) 33 { 34 const int exitval = 5; 35 const int exitval2 = 0; /* This matched exit status from /bin/echo */ 36 const int sigval = SIGSTOP; 37 pid_t child, child2 = 0, wpid; 38 #if defined(TWAIT_HAVE_STATUS) 39 int status; 40 #endif 41 sigset_t set; 42 ptrace_state_t state; 43 const int slen = sizeof(state); 44 ptrace_event_t event; 45 const int elen = sizeof(event); 46 47 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 48 49 if (newpgrp) 50 atf_tc_skip("kernel panic (pg_jobc going negative)"); 51 52 DPRINTF("Before forking process PID=%d\n", getpid()); 53 SYSCALL_REQUIRE((child = fork()) != -1); 54 if (child == 0) { 55 if (newpgrp) { 56 DPRINTF("Before entering new process group"); 57 setpgid(0, 0); 58 } 59 60 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 61 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 62 63 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 64 FORKEE_ASSERT(raise(sigval) == 0); 65 66 if (strcmp(fn, "spawn") == 0) { 67 FORKEE_ASSERT_EQ(posix_spawn(&child2, 68 arg[0], NULL, NULL, arg, NULL), 0); 69 } else { 70 if (strcmp(fn, "fork") == 0) { 71 FORKEE_ASSERT((child2 = fork()) != -1); 72 } else if (strcmp(fn, "vfork") == 0) { 73 FORKEE_ASSERT((child2 = vfork()) != -1); 74 } 75 76 if (child2 == 0) 77 _exit(exitval2); 78 } 79 FORKEE_REQUIRE_SUCCESS 80 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 81 82 forkee_status_exited(status, exitval2); 83 84 DPRINTF("Before exiting of the child process\n"); 85 _exit(exitval); 86 } 87 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 88 89 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 90 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 91 92 validate_status_stopped(status, sigval); 93 94 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 95 trackspawn ? "|PTRACE_POSIX_SPAWN" : "", 96 trackfork ? "|PTRACE_FORK" : "", 97 trackvfork ? "|PTRACE_VFORK" : "", 98 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 99 event.pe_set_event = 0; 100 if (trackspawn) 101 event.pe_set_event |= PTRACE_POSIX_SPAWN; 102 if (trackfork) 103 event.pe_set_event |= PTRACE_FORK; 104 if (trackvfork) 105 event.pe_set_event |= PTRACE_VFORK; 106 if (trackvforkdone) 107 event.pe_set_event |= PTRACE_VFORK_DONE; 108 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 109 110 /* 111 * Ignore interception of the SIGCHLD signals. 112 * 113 * SIGCHLD once blocked is discarded by the kernel as it has the 114 * SA_IGNORE property. During the fork(2) operation all signals can be 115 * shortly blocked and missed (unless there is a registered signal 116 * handler in the traced child). This leads to a race in this test if 117 * there would be an intention to catch SIGCHLD. 118 */ 119 sigemptyset(&set); 120 sigaddset(&set, SIGCHLD); 121 SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1); 122 123 DPRINTF("Before resuming the child process where it left off and " 124 "without signal to be sent\n"); 125 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 126 127 #if defined(TWAIT_HAVE_PID) 128 if ((trackspawn && strcmp(fn, "spawn") == 0) || 129 (trackfork && strcmp(fn, "fork") == 0) || 130 (trackvfork && strcmp(fn, "vfork") == 0)) { 131 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 132 child); 133 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 134 child); 135 136 validate_status_stopped(status, SIGTRAP); 137 138 SYSCALL_REQUIRE( 139 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 140 if (trackspawn && strcmp(fn, "spawn") == 0) { 141 ATF_REQUIRE_EQ( 142 state.pe_report_event & PTRACE_POSIX_SPAWN, 143 PTRACE_POSIX_SPAWN); 144 } 145 if (trackfork && strcmp(fn, "fork") == 0) { 146 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 147 PTRACE_FORK); 148 } 149 if (trackvfork && strcmp(fn, "vfork") == 0) { 150 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 151 PTRACE_VFORK); 152 } 153 154 child2 = state.pe_other_pid; 155 DPRINTF("Reported ptrace event with forkee %d\n", child2); 156 157 DPRINTF("Before calling %s() for the forkee %d of the child " 158 "%d\n", TWAIT_FNAME, child2, child); 159 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 160 child2); 161 162 validate_status_stopped(status, SIGTRAP); 163 164 SYSCALL_REQUIRE( 165 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 166 if (trackspawn && strcmp(fn, "spawn") == 0) { 167 ATF_REQUIRE_EQ( 168 state.pe_report_event & PTRACE_POSIX_SPAWN, 169 PTRACE_POSIX_SPAWN); 170 } 171 if (trackfork && strcmp(fn, "fork") == 0) { 172 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 173 PTRACE_FORK); 174 } 175 if (trackvfork && strcmp(fn, "vfork") == 0) { 176 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 177 PTRACE_VFORK); 178 } 179 180 ATF_REQUIRE_EQ(state.pe_other_pid, child); 181 182 DPRINTF("Before resuming the forkee process where it left off " 183 "and without signal to be sent\n"); 184 SYSCALL_REQUIRE( 185 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 186 187 DPRINTF("Before resuming the child process where it left off " 188 "and without signal to be sent\n"); 189 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 190 } 191 #endif 192 193 if (trackvforkdone && strcmp(fn, "vfork") == 0) { 194 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 195 child); 196 TWAIT_REQUIRE_SUCCESS( 197 wpid = TWAIT_GENERIC(child, &status, 0), child); 198 199 validate_status_stopped(status, SIGTRAP); 200 201 SYSCALL_REQUIRE( 202 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 203 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 204 205 child2 = state.pe_other_pid; 206 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 207 child2); 208 209 DPRINTF("Before resuming the child process where it left off " 210 "and without signal to be sent\n"); 211 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 212 } 213 214 #if defined(TWAIT_HAVE_PID) 215 if ((trackspawn && strcmp(fn, "spawn") == 0) || 216 (trackfork && strcmp(fn, "fork") == 0) || 217 (trackvfork && strcmp(fn, "vfork") == 0)) { 218 DPRINTF("Before calling %s() for the forkee - expected exited" 219 "\n", TWAIT_FNAME); 220 TWAIT_REQUIRE_SUCCESS( 221 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 222 223 validate_status_exited(status, exitval2); 224 225 DPRINTF("Before calling %s() for the forkee - expected no " 226 "process\n", TWAIT_FNAME); 227 TWAIT_REQUIRE_FAILURE(ECHILD, 228 wpid = TWAIT_GENERIC(child2, &status, 0)); 229 } 230 #endif 231 232 DPRINTF("Before calling %s() for the child - expected exited\n", 233 TWAIT_FNAME); 234 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 235 236 validate_status_exited(status, exitval); 237 238 DPRINTF("Before calling %s() for the child - expected no process\n", 239 TWAIT_FNAME); 240 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 241 } 242 243 #define FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp) \ 244 ATF_TC(name); \ 245 ATF_TC_HEAD(name, tc) \ 246 { \ 247 atf_tc_set_md_var(tc, "descr", "Verify " fun "() " \ 248 "called with 0%s%s%s%s in EVENT_MASK%s", \ 249 tspawn ? "|PTRACE_POSIX_SPAWN" : "", \ 250 tfork ? "|PTRACE_FORK" : "", \ 251 tvfork ? "|PTRACE_VFORK" : "", \ 252 tvforkdone ? "|PTRACE_VFORK_DONE" : "", \ 253 newpgrp ? " and the traced processes call setpgrp(0,0)":"");\ 254 } \ 255 \ 256 ATF_TC_BODY(name, tc) \ 257 { \ 258 \ 259 fork_body(fun, tspawn, tfork, tvfork, tvforkdone, newpgrp); \ 260 } 261 262 #define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone) \ 263 FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false) 264 265 FORK_TEST(fork1, "fork", false, false, false, false) 266 #if defined(TWAIT_HAVE_PID) 267 FORK_TEST(fork2, "fork", false, true, false, false) 268 FORK_TEST(fork3, "fork", false, false, true, false) 269 FORK_TEST(fork4, "fork", false, true, true, false) 270 #endif 271 FORK_TEST(fork5, "fork", false, false, false, true) 272 #if defined(TWAIT_HAVE_PID) 273 FORK_TEST(fork6, "fork", false, true, false, true) 274 FORK_TEST(fork7, "fork", false, false, true, true) 275 FORK_TEST(fork8, "fork", false, true, true, true) 276 #endif 277 FORK_TEST(fork9, "fork", true, false, false, false) 278 #if defined(TWAIT_HAVE_PID) 279 FORK_TEST(fork10, "fork", true, true, false, false) 280 FORK_TEST(fork11, "fork", true, false, true, false) 281 FORK_TEST(fork12, "fork", true, true, true, false) 282 #endif 283 FORK_TEST(fork13, "fork", true, false, false, true) 284 #if defined(TWAIT_HAVE_PID) 285 FORK_TEST(fork14, "fork", true, true, false, true) 286 FORK_TEST(fork15, "fork", true, false, true, true) 287 FORK_TEST(fork16, "fork", true, true, true, true) 288 #endif 289 290 #if defined(TWAIT_HAVE_PID) 291 FORK_TEST2(fork_setpgid, "fork", true, true, true, true, true) 292 #endif 293 294 FORK_TEST(vfork1, "vfork", false, false, false, false) 295 #if defined(TWAIT_HAVE_PID) 296 FORK_TEST(vfork2, "vfork", false, true, false, false) 297 FORK_TEST(vfork3, "vfork", false, false, true, false) 298 FORK_TEST(vfork4, "vfork", false, true, true, false) 299 #endif 300 FORK_TEST(vfork5, "vfork", false, false, false, true) 301 #if defined(TWAIT_HAVE_PID) 302 FORK_TEST(vfork6, "vfork", false, true, false, true) 303 FORK_TEST(vfork7, "vfork", false, false, true, true) 304 FORK_TEST(vfork8, "vfork", false, true, true, true) 305 #endif 306 FORK_TEST(vfork9, "vfork", true, false, false, false) 307 #if defined(TWAIT_HAVE_PID) 308 FORK_TEST(vfork10, "vfork", true, true, false, false) 309 FORK_TEST(vfork11, "vfork", true, false, true, false) 310 FORK_TEST(vfork12, "vfork", true, true, true, false) 311 #endif 312 FORK_TEST(vfork13, "vfork", true, false, false, true) 313 #if defined(TWAIT_HAVE_PID) 314 FORK_TEST(vfork14, "vfork", true, true, false, true) 315 FORK_TEST(vfork15, "vfork", true, false, true, true) 316 FORK_TEST(vfork16, "vfork", true, true, true, true) 317 #endif 318 319 #if defined(TWAIT_HAVE_PID) 320 FORK_TEST2(vfork_setpgid, "vfork", true, true, true, true, true) 321 #endif 322 323 FORK_TEST(posix_spawn1, "spawn", false, false, false, false) 324 FORK_TEST(posix_spawn2, "spawn", false, true, false, false) 325 FORK_TEST(posix_spawn3, "spawn", false, false, true, false) 326 FORK_TEST(posix_spawn4, "spawn", false, true, true, false) 327 FORK_TEST(posix_spawn5, "spawn", false, false, false, true) 328 FORK_TEST(posix_spawn6, "spawn", false, true, false, true) 329 FORK_TEST(posix_spawn7, "spawn", false, false, true, true) 330 FORK_TEST(posix_spawn8, "spawn", false, true, true, true) 331 #if defined(TWAIT_HAVE_PID) 332 FORK_TEST(posix_spawn9, "spawn", true, false, false, false) 333 FORK_TEST(posix_spawn10, "spawn", true, true, false, false) 334 FORK_TEST(posix_spawn11, "spawn", true, false, true, false) 335 FORK_TEST(posix_spawn12, "spawn", true, true, true, false) 336 FORK_TEST(posix_spawn13, "spawn", true, false, false, true) 337 FORK_TEST(posix_spawn14, "spawn", true, true, false, true) 338 FORK_TEST(posix_spawn15, "spawn", true, false, true, true) 339 FORK_TEST(posix_spawn16, "spawn", true, true, true, true) 340 #endif 341 342 #if defined(TWAIT_HAVE_PID) 343 FORK_TEST2(posix_spawn_setpgid, "spawn", true, true, true, true, true) 344 #endif 345 346 /// ---------------------------------------------------------------------------- 347 348 #if defined(TWAIT_HAVE_PID) 349 static void 350 unrelated_tracer_fork_body(const char *fn, bool trackspawn, bool trackfork, 351 bool trackvfork, bool trackvforkdone, bool newpgrp) 352 { 353 const int sigval = SIGSTOP; 354 struct msg_fds parent_tracee, parent_tracer; 355 const int exitval = 10; 356 const int exitval2 = 0; /* This matched exit status from /bin/echo */ 357 pid_t tracee, tracer, wpid; 358 pid_t tracee2 = 0; 359 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 360 #if defined(TWAIT_HAVE_STATUS) 361 int status; 362 #endif 363 364 sigset_t set; 365 struct ptrace_siginfo info; 366 ptrace_state_t state; 367 const int slen = sizeof(state); 368 ptrace_event_t event; 369 const int elen = sizeof(event); 370 371 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 372 373 if (newpgrp) 374 atf_tc_skip("kernel panic (pg_jobc going negative)"); 375 376 DPRINTF("Spawn tracee\n"); 377 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 378 tracee = atf_utils_fork(); 379 if (tracee == 0) { 380 if (newpgrp) { 381 DPRINTF("Before entering new process group"); 382 setpgid(0, 0); 383 } 384 385 // Wait for parent to let us crash 386 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 387 388 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 389 FORKEE_ASSERT(raise(sigval) == 0); 390 391 if (strcmp(fn, "spawn") == 0) { 392 FORKEE_ASSERT_EQ(posix_spawn(&tracee2, 393 arg[0], NULL, NULL, arg, NULL), 0); 394 } else { 395 if (strcmp(fn, "fork") == 0) { 396 FORKEE_ASSERT((tracee2 = fork()) != -1); 397 } else if (strcmp(fn, "vfork") == 0) { 398 FORKEE_ASSERT((tracee2 = vfork()) != -1); 399 } 400 401 if (tracee2 == 0) 402 _exit(exitval2); 403 } 404 FORKEE_REQUIRE_SUCCESS 405 (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 406 407 forkee_status_exited(status, exitval2); 408 409 DPRINTF("Before exiting of the child process\n"); 410 _exit(exitval); 411 } 412 413 DPRINTF("Spawn debugger\n"); 414 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 415 tracer = atf_utils_fork(); 416 if (tracer == 0) { 417 /* Fork again and drop parent to reattach to PID 1 */ 418 tracer = atf_utils_fork(); 419 if (tracer != 0) 420 _exit(exitval); 421 422 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 423 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 424 425 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 426 FORKEE_REQUIRE_SUCCESS( 427 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 428 429 forkee_status_stopped(status, SIGSTOP); 430 431 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 432 "traced process\n"); 433 SYSCALL_REQUIRE( 434 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 435 436 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 437 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 438 "si_errno=%#x\n", info.psi_siginfo.si_signo, 439 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 440 441 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 442 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 443 444 /* Resume tracee with PT_CONTINUE */ 445 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 446 447 /* Inform parent that tracer has attached to tracee */ 448 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 449 450 /* Wait for parent to tell use that tracee should have exited */ 451 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 452 453 /* Wait for tracee and assert that it exited */ 454 FORKEE_REQUIRE_SUCCESS( 455 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 456 457 forkee_status_stopped(status, sigval); 458 459 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 460 "traced process\n"); 461 SYSCALL_REQUIRE( 462 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 463 464 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 465 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 466 "si_errno=%#x\n", info.psi_siginfo.si_signo, 467 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 468 469 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 470 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 471 472 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 473 trackspawn ? "|PTRACE_POSIX_SPAWN" : "", 474 trackfork ? "|PTRACE_FORK" : "", 475 trackvfork ? "|PTRACE_VFORK" : "", 476 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", tracee); 477 event.pe_set_event = 0; 478 if (trackspawn) 479 event.pe_set_event |= PTRACE_POSIX_SPAWN; 480 if (trackfork) 481 event.pe_set_event |= PTRACE_FORK; 482 if (trackvfork) 483 event.pe_set_event |= PTRACE_VFORK; 484 if (trackvforkdone) 485 event.pe_set_event |= PTRACE_VFORK_DONE; 486 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) 487 != -1); 488 489 /* 490 * Ignore interception of the SIGCHLD signals. 491 * 492 * SIGCHLD once blocked is discarded by the kernel as it has the 493 * SA_IGNORE property. During the fork(2) operation all signals 494 * can be shortly blocked and missed (unless there is a 495 * registered signal handler in the traced child). This leads to 496 * a race in this test if there would be an intention to catch 497 * SIGCHLD. 498 */ 499 sigemptyset(&set); 500 sigaddset(&set, SIGCHLD); 501 SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, tracee, &set, 502 sizeof(set)) != -1); 503 504 DPRINTF("Before resuming the child process where it left off " 505 "and without signal to be sent\n"); 506 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 507 508 if ((trackspawn && strcmp(fn, "spawn") == 0) || 509 (trackfork && strcmp(fn, "fork") == 0) || 510 (trackvfork && strcmp(fn, "vfork") == 0)) { 511 DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME, 512 tracee); 513 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), 514 tracee); 515 516 validate_status_stopped(status, SIGTRAP); 517 518 SYSCALL_REQUIRE( 519 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 520 if (trackspawn && strcmp(fn, "spawn") == 0) { 521 ATF_REQUIRE_EQ( 522 state.pe_report_event & PTRACE_POSIX_SPAWN, 523 PTRACE_POSIX_SPAWN); 524 } 525 if (trackfork && strcmp(fn, "fork") == 0) { 526 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 527 PTRACE_FORK); 528 } 529 if (trackvfork && strcmp(fn, "vfork") == 0) { 530 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 531 PTRACE_VFORK); 532 } 533 534 tracee2 = state.pe_other_pid; 535 DPRINTF("Reported ptrace event with forkee %d\n", tracee2); 536 537 DPRINTF("Before calling %s() for the forkee %d of the tracee " 538 "%d\n", TWAIT_FNAME, tracee2, tracee); 539 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), 540 tracee2); 541 542 validate_status_stopped(status, SIGTRAP); 543 544 SYSCALL_REQUIRE( 545 ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1); 546 if (trackspawn && strcmp(fn, "spawn") == 0) { 547 ATF_REQUIRE_EQ( 548 state.pe_report_event & PTRACE_POSIX_SPAWN, 549 PTRACE_POSIX_SPAWN); 550 } 551 if (trackfork && strcmp(fn, "fork") == 0) { 552 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 553 PTRACE_FORK); 554 } 555 if (trackvfork && strcmp(fn, "vfork") == 0) { 556 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 557 PTRACE_VFORK); 558 } 559 560 ATF_REQUIRE_EQ(state.pe_other_pid, tracee); 561 562 DPRINTF("Before resuming the forkee process where it left off " 563 "and without signal to be sent\n"); 564 SYSCALL_REQUIRE( 565 ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1); 566 567 DPRINTF("Before resuming the tracee process where it left off " 568 "and without signal to be sent\n"); 569 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 570 } 571 572 if (trackvforkdone && strcmp(fn, "vfork") == 0) { 573 DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME, 574 tracee); 575 TWAIT_REQUIRE_SUCCESS( 576 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 577 578 validate_status_stopped(status, SIGTRAP); 579 580 SYSCALL_REQUIRE( 581 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 582 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 583 584 tracee2 = state.pe_other_pid; 585 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 586 tracee2); 587 588 DPRINTF("Before resuming the tracee process where it left off " 589 "and without signal to be sent\n"); 590 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 591 } 592 593 594 if ((trackspawn && strcmp(fn, "spawn") == 0) || 595 (trackfork && strcmp(fn, "fork") == 0) || 596 (trackvfork && strcmp(fn, "vfork") == 0)) { 597 DPRINTF("Before calling %s() for the forkee - expected exited" 598 "\n", TWAIT_FNAME); 599 TWAIT_REQUIRE_SUCCESS( 600 wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 601 602 validate_status_exited(status, exitval2); 603 604 DPRINTF("Before calling %s() for the forkee - expected no " 605 "process\n", TWAIT_FNAME); 606 TWAIT_REQUIRE_FAILURE(ECHILD, 607 wpid = TWAIT_GENERIC(tracee2, &status, 0)); 608 } 609 610 DPRINTF("Before calling %s() for the tracee - expected exited\n", 611 TWAIT_FNAME); 612 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 613 614 validate_status_exited(status, exitval); 615 616 /* Inform parent that tracer is exiting normally */ 617 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 618 619 DPRINTF("Before exiting of the tracer process\n"); 620 _exit(0 /* collect by initproc */); 621 } 622 623 DPRINTF("Wait for the tracer process (direct child) to exit " 624 "calling %s()\n", TWAIT_FNAME); 625 TWAIT_REQUIRE_SUCCESS( 626 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 627 628 validate_status_exited(status, exitval); 629 630 DPRINTF("Wait for the non-exited tracee process with %s()\n", 631 TWAIT_FNAME); 632 TWAIT_REQUIRE_SUCCESS( 633 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 634 635 DPRINTF("Wait for the tracer to attach to the tracee\n"); 636 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 637 638 DPRINTF("Resume the tracee and let it crash\n"); 639 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 640 641 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 642 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 643 644 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 645 TWAIT_FNAME); 646 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 647 648 validate_status_exited(status, exitval); 649 650 DPRINTF("Await normal exit of tracer\n"); 651 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 652 653 msg_close(&parent_tracer); 654 msg_close(&parent_tracee); 655 } 656 657 #define UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp)\ 658 ATF_TC(name); \ 659 ATF_TC_HEAD(name, tc) \ 660 { \ 661 atf_tc_set_md_var(tc, "descr", "Verify " fun "() " \ 662 "called with 0%s%s%s%s in EVENT_MASK%s", \ 663 tspawn ? "|PTRACE_POSIX_SPAWN" : "", \ 664 tfork ? "|PTRACE_FORK" : "", \ 665 tvfork ? "|PTRACE_VFORK" : "", \ 666 tvforkdone ? "|PTRACE_VFORK_DONE" : "", \ 667 newpgrp ? " and the traced processes call setpgrp(0,0)":"");\ 668 } \ 669 \ 670 ATF_TC_BODY(name, tc) \ 671 { \ 672 \ 673 unrelated_tracer_fork_body(fun, tspawn, tfork, tvfork, \ 674 tvforkdone, newpgrp); \ 675 } 676 677 #define UNRELATED_TRACER_FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone) \ 678 UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false) 679 680 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork1, "fork", false, false, false, false) 681 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork2, "fork", false, true, false, false) 682 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork3, "fork", false, false, true, false) 683 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork4, "fork", false, true, true, false) 684 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork5, "fork", false, false, false, true) 685 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork6, "fork", false, true, false, true) 686 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork7, "fork", false, false, true, true) 687 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork8, "fork", false, true, true, true) 688 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork9, "fork", true, false, false, false) 689 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork10, "fork", true, true, false, false) 690 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork11, "fork", true, false, true, false) 691 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork12, "fork", true, true, true, false) 692 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork13, "fork", true, false, false, true) 693 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork14, "fork", true, true, false, true) 694 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork15, "fork", true, false, true, true) 695 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork16, "fork", true, true, true, true) 696 697 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_fork_setpgid, "fork", true, true, true, true, true) 698 699 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork1, "vfork", false, false, false, false) 700 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork2, "vfork", false, true, false, false) 701 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork3, "vfork", false, false, true, false) 702 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork4, "vfork", false, true, true, false) 703 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork5, "vfork", false, false, false, true) 704 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork6, "vfork", false, true, false, true) 705 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork7, "vfork", false, false, true, true) 706 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork8, "vfork", false, true, true, true) 707 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork9, "vfork", true, false, false, false) 708 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork10, "vfork", true, true, false, false) 709 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork11, "vfork", true, false, true, false) 710 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork12, "vfork", true, true, true, false) 711 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork13, "vfork", true, false, false, true) 712 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork14, "vfork", true, true, false, true) 713 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork15, "vfork", true, false, true, true) 714 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork16, "vfork", true, true, true, true) 715 716 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_vfork_setpgid, "vfork", true, true, true, true, true) 717 718 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn1, "spawn", false, false, false, false) 719 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn2, "spawn", false, true, false, false) 720 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn3, "spawn", false, false, true, false) 721 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn4, "spawn", false, true, true, false) 722 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn5, "spawn", false, false, false, true) 723 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn6, "spawn", false, true, false, true) 724 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn7, "spawn", false, false, true, true) 725 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn8, "spawn", false, true, true, true) 726 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn9, "spawn", true, false, false, false) 727 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn10, "spawn", true, true, false, false) 728 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn11, "spawn", true, false, true, false) 729 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn12, "spawn", true, true, true, false) 730 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn13, "spawn", true, false, false, true) 731 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn14, "spawn", true, true, false, true) 732 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn15, "spawn", true, false, true, true) 733 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn16, "spawn", true, true, true, true) 734 735 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_posix_spawn_setpgid, "spawn", true, true, true, true, true) 736 #endif 737 738 /// ---------------------------------------------------------------------------- 739 740 #if defined(TWAIT_HAVE_PID) 741 static void 742 fork_detach_forker_body(const char *fn, bool kill_process) 743 { 744 const int exitval = 5; 745 const int exitval2 = 0; /* Matches exit value from /bin/echo */ 746 const int sigval = SIGSTOP; 747 pid_t child, child2 = 0, wpid; 748 #if defined(TWAIT_HAVE_STATUS) 749 int status; 750 #endif 751 ptrace_state_t state; 752 const int slen = sizeof(state); 753 ptrace_event_t event; 754 const int elen = sizeof(event); 755 756 int op; 757 758 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 759 760 DPRINTF("Before forking process PID=%d\n", getpid()); 761 SYSCALL_REQUIRE((child = fork()) != -1); 762 if (child == 0) { 763 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 764 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 765 766 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 767 FORKEE_ASSERT(raise(sigval) == 0); 768 769 if (strcmp(fn, "spawn") == 0) { 770 FORKEE_ASSERT_EQ(posix_spawn(&child2, 771 arg[0], NULL, NULL, arg, NULL), 0); 772 } else { 773 if (strcmp(fn, "fork") == 0) { 774 FORKEE_ASSERT((child2 = fork()) != -1); 775 } else { 776 FORKEE_ASSERT((child2 = vfork()) != -1); 777 } 778 779 if (child2 == 0) 780 _exit(exitval2); 781 } 782 783 FORKEE_REQUIRE_SUCCESS 784 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 785 786 forkee_status_exited(status, exitval2); 787 788 DPRINTF("Before exiting of the child process\n"); 789 _exit(exitval); 790 } 791 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 792 793 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 794 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 795 796 validate_status_stopped(status, sigval); 797 798 DPRINTF("Set EVENT_MASK for the child %d\n", child); 799 event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK 800 | PTRACE_VFORK_DONE; 801 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 802 803 DPRINTF("Before resuming the child process where it left off and " 804 "without signal to be sent\n"); 805 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 806 807 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child); 808 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 809 810 validate_status_stopped(status, SIGTRAP); 811 812 SYSCALL_REQUIRE( 813 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 814 815 if (strcmp(fn, "spawn") == 0) 816 op = PTRACE_POSIX_SPAWN; 817 else if (strcmp(fn, "fork") == 0) 818 op = PTRACE_FORK; 819 else 820 op = PTRACE_VFORK; 821 822 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 823 824 child2 = state.pe_other_pid; 825 DPRINTF("Reported ptrace event with forkee %d\n", child2); 826 827 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 828 strcmp(fn, "vfork") == 0) 829 op = kill_process ? PT_KILL : PT_DETACH; 830 else 831 op = PT_CONTINUE; 832 SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1); 833 834 DPRINTF("Before calling %s() for the forkee %d of the child %d\n", 835 TWAIT_FNAME, child2, child); 836 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2); 837 838 validate_status_stopped(status, SIGTRAP); 839 840 SYSCALL_REQUIRE( 841 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 842 if (strcmp(fn, "spawn") == 0) 843 op = PTRACE_POSIX_SPAWN; 844 else if (strcmp(fn, "fork") == 0) 845 op = PTRACE_FORK; 846 else 847 op = PTRACE_VFORK; 848 849 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 850 ATF_REQUIRE_EQ(state.pe_other_pid, child); 851 852 DPRINTF("Before resuming the forkee process where it left off " 853 "and without signal to be sent\n"); 854 SYSCALL_REQUIRE( 855 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 856 857 if (strcmp(fn, "vforkdone") == 0) { 858 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 859 child); 860 TWAIT_REQUIRE_SUCCESS( 861 wpid = TWAIT_GENERIC(child, &status, 0), child); 862 863 validate_status_stopped(status, SIGTRAP); 864 865 SYSCALL_REQUIRE( 866 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 867 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 868 869 child2 = state.pe_other_pid; 870 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 871 child2); 872 873 op = kill_process ? PT_KILL : PT_DETACH; 874 DPRINTF("Before resuming the child process where it left off " 875 "and without signal to be sent\n"); 876 SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1); 877 } 878 879 DPRINTF("Before calling %s() for the forkee - expected exited\n", 880 TWAIT_FNAME); 881 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2); 882 883 validate_status_exited(status, exitval2); 884 885 DPRINTF("Before calling %s() for the forkee - expected no process\n", 886 TWAIT_FNAME); 887 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0)); 888 889 DPRINTF("Before calling %s() for the forkee - expected exited\n", 890 TWAIT_FNAME); 891 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 892 893 if (kill_process) { 894 validate_status_signaled(status, SIGKILL, 0); 895 } else { 896 validate_status_exited(status, exitval); 897 } 898 899 DPRINTF("Before calling %s() for the child - expected no process\n", 900 TWAIT_FNAME); 901 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 902 } 903 904 #define FORK_DETACH_FORKER(name,event,kprocess) \ 905 ATF_TC(name); \ 906 ATF_TC_HEAD(name, tc) \ 907 { \ 908 atf_tc_set_md_var(tc, "descr", "Verify %s " event, \ 909 kprocess ? "killed" : "detached"); \ 910 } \ 911 \ 912 ATF_TC_BODY(name, tc) \ 913 { \ 914 \ 915 fork_detach_forker_body(event, kprocess); \ 916 } 917 918 FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false) 919 FORK_DETACH_FORKER(fork_detach_forker, "fork", false) 920 FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false) 921 FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false) 922 923 FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true) 924 FORK_DETACH_FORKER(fork_kill_forker, "fork", true) 925 FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true) 926 FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true) 927 #endif 928 929 /// ---------------------------------------------------------------------------- 930 931 #if defined(TWAIT_HAVE_PID) 932 static void 933 unrelated_tracer_fork_detach_forker_body(const char *fn, bool kill_process) 934 { 935 const int sigval = SIGSTOP; 936 struct msg_fds parent_tracee, parent_tracer; 937 const int exitval = 10; 938 const int exitval2 = 0; /* This matched exit status from /bin/echo */ 939 pid_t tracee, tracer, wpid; 940 pid_t tracee2 = 0; 941 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 942 #if defined(TWAIT_HAVE_STATUS) 943 int status; 944 #endif 945 int op; 946 947 struct ptrace_siginfo info; 948 ptrace_state_t state; 949 const int slen = sizeof(state); 950 ptrace_event_t event; 951 const int elen = sizeof(event); 952 953 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 954 955 DPRINTF("Spawn tracee\n"); 956 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 957 tracee = atf_utils_fork(); 958 if (tracee == 0) { 959 // Wait for parent to let us crash 960 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 961 962 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 963 FORKEE_ASSERT(raise(sigval) == 0); 964 965 if (strcmp(fn, "spawn") == 0) { 966 FORKEE_ASSERT_EQ(posix_spawn(&tracee2, 967 arg[0], NULL, NULL, arg, NULL), 0); 968 } else { 969 if (strcmp(fn, "fork") == 0) { 970 FORKEE_ASSERT((tracee2 = fork()) != -1); 971 } else { 972 FORKEE_ASSERT((tracee2 = vfork()) != -1); 973 } 974 975 if (tracee2 == 0) 976 _exit(exitval2); 977 } 978 979 FORKEE_REQUIRE_SUCCESS 980 (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 981 982 forkee_status_exited(status, exitval2); 983 984 DPRINTF("Before exiting of the child process\n"); 985 _exit(exitval); 986 } 987 988 DPRINTF("Spawn debugger\n"); 989 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 990 tracer = atf_utils_fork(); 991 if (tracer == 0) { 992 /* Fork again and drop parent to reattach to PID 1 */ 993 tracer = atf_utils_fork(); 994 if (tracer != 0) 995 _exit(exitval); 996 997 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 998 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 999 1000 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 1001 FORKEE_REQUIRE_SUCCESS( 1002 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1003 1004 forkee_status_stopped(status, SIGSTOP); 1005 1006 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 1007 "traced process\n"); 1008 SYSCALL_REQUIRE( 1009 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1010 1011 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1012 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1013 "si_errno=%#x\n", info.psi_siginfo.si_signo, 1014 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 1015 1016 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 1017 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 1018 1019 /* Resume tracee with PT_CONTINUE */ 1020 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1021 1022 /* Inform parent that tracer has attached to tracee */ 1023 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 1024 1025 /* Wait for parent to tell use that tracee should have exited */ 1026 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 1027 1028 /* Wait for tracee and assert that it exited */ 1029 FORKEE_REQUIRE_SUCCESS( 1030 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1031 1032 forkee_status_stopped(status, sigval); 1033 1034 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 1035 "traced process\n"); 1036 SYSCALL_REQUIRE( 1037 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1038 1039 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1040 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1041 "si_errno=%#x\n", info.psi_siginfo.si_signo, 1042 info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 1043 1044 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 1045 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 1046 1047 DPRINTF("Set EVENT_MASK for the child %d\n", tracee); 1048 event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK 1049 | PTRACE_VFORK_DONE; 1050 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) != -1); 1051 1052 DPRINTF("Before resuming the child process where it left off and " 1053 "without signal to be sent\n"); 1054 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1055 1056 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, tracee); 1057 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1058 1059 validate_status_stopped(status, SIGTRAP); 1060 1061 SYSCALL_REQUIRE( 1062 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 1063 1064 if (strcmp(fn, "spawn") == 0) 1065 op = PTRACE_POSIX_SPAWN; 1066 else if (strcmp(fn, "fork") == 0) 1067 op = PTRACE_FORK; 1068 else 1069 op = PTRACE_VFORK; 1070 1071 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 1072 1073 tracee2 = state.pe_other_pid; 1074 DPRINTF("Reported ptrace event with forkee %d\n", tracee2); 1075 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 1076 strcmp(fn, "vfork") == 0) 1077 op = kill_process ? PT_KILL : PT_DETACH; 1078 else 1079 op = PT_CONTINUE; 1080 SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1); 1081 1082 DPRINTF("Before calling %s() for the forkee %d of the tracee %d\n", 1083 TWAIT_FNAME, tracee2, tracee); 1084 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 1085 1086 validate_status_stopped(status, SIGTRAP); 1087 1088 SYSCALL_REQUIRE( 1089 ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1); 1090 if (strcmp(fn, "spawn") == 0) 1091 op = PTRACE_POSIX_SPAWN; 1092 else if (strcmp(fn, "fork") == 0) 1093 op = PTRACE_FORK; 1094 else 1095 op = PTRACE_VFORK; 1096 1097 ATF_REQUIRE_EQ(state.pe_report_event & op, op); 1098 ATF_REQUIRE_EQ(state.pe_other_pid, tracee); 1099 1100 DPRINTF("Before resuming the forkee process where it left off " 1101 "and without signal to be sent\n"); 1102 SYSCALL_REQUIRE( 1103 ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1); 1104 1105 if (strcmp(fn, "vforkdone") == 0) { 1106 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 1107 tracee); 1108 TWAIT_REQUIRE_SUCCESS( 1109 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1110 1111 validate_status_stopped(status, SIGTRAP); 1112 1113 SYSCALL_REQUIRE( 1114 ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1); 1115 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 1116 1117 tracee2 = state.pe_other_pid; 1118 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 1119 tracee2); 1120 1121 op = kill_process ? PT_KILL : PT_DETACH; 1122 DPRINTF("Before resuming the child process where it left off " 1123 "and without signal to be sent\n"); 1124 SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1); 1125 } 1126 1127 DPRINTF("Before calling %s() for the forkee - expected exited\n", 1128 TWAIT_FNAME); 1129 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2); 1130 1131 validate_status_exited(status, exitval2); 1132 1133 DPRINTF("Before calling %s() for the forkee - expected no process\n", 1134 TWAIT_FNAME); 1135 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(tracee2, &status, 0)); 1136 1137 if (kill_process) { 1138 DPRINTF("Before calling %s() for the forkee - expected signaled\n", 1139 TWAIT_FNAME); 1140 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1141 1142 validate_status_signaled(status, SIGKILL, 0); 1143 } 1144 1145 /* Inform parent that tracer is exiting normally */ 1146 CHILD_TO_PARENT("tracer done", parent_tracer, msg); 1147 1148 DPRINTF("Before exiting of the tracer process\n"); 1149 _exit(0 /* collect by initproc */); 1150 } 1151 1152 DPRINTF("Wait for the tracer process (direct child) to exit " 1153 "calling %s()\n", TWAIT_FNAME); 1154 TWAIT_REQUIRE_SUCCESS( 1155 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 1156 1157 validate_status_exited(status, exitval); 1158 1159 DPRINTF("Wait for the non-exited tracee process with %s()\n", 1160 TWAIT_FNAME); 1161 TWAIT_REQUIRE_SUCCESS( 1162 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 1163 1164 DPRINTF("Wait for the tracer to attach to the tracee\n"); 1165 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 1166 1167 DPRINTF("Resume the tracee and let it crash\n"); 1168 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 1169 1170 DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 1171 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 1172 1173 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 1174 TWAIT_FNAME); 1175 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1176 1177 if (kill_process) { 1178 validate_status_signaled(status, SIGKILL, 0); 1179 } else { 1180 validate_status_exited(status, exitval); 1181 } 1182 1183 DPRINTF("Await normal exit of tracer\n"); 1184 PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 1185 1186 msg_close(&parent_tracer); 1187 msg_close(&parent_tracee); 1188 } 1189 1190 #define UNRELATED_TRACER_FORK_DETACH_FORKER(name,event,kprocess) \ 1191 ATF_TC(name); \ 1192 ATF_TC_HEAD(name, tc) \ 1193 { \ 1194 atf_tc_set_md_var(tc, "descr", "Verify %s " event, \ 1195 kprocess ? "killed" : "detached"); \ 1196 } \ 1197 \ 1198 ATF_TC_BODY(name, tc) \ 1199 { \ 1200 \ 1201 unrelated_tracer_fork_detach_forker_body(event, kprocess); \ 1202 } 1203 1204 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_detach_spawner, "spawn", false) 1205 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_detach_forker, "fork", false) 1206 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforker, "vfork", false) 1207 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforkerdone, "vforkdone", false) 1208 1209 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_kill_spawner, "spawn", true) 1210 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_kill_forker, "fork", true) 1211 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforker, "vfork", true) 1212 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforkerdone, "vforkdone", true) 1213 #endif 1214 1215 /// ---------------------------------------------------------------------------- 1216 1217 static void 1218 traceme_vfork_fork_body(pid_t (*fn)(void)) 1219 { 1220 const int exitval = 5; 1221 const int exitval2 = 15; 1222 pid_t child, child2 = 0, wpid; 1223 #if defined(TWAIT_HAVE_STATUS) 1224 int status; 1225 #endif 1226 1227 DPRINTF("Before forking process PID=%d\n", getpid()); 1228 SYSCALL_REQUIRE((child = vfork()) != -1); 1229 if (child == 0) { 1230 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1231 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1232 1233 FORKEE_ASSERT((child2 = (fn)()) != -1); 1234 1235 if (child2 == 0) 1236 _exit(exitval2); 1237 1238 FORKEE_REQUIRE_SUCCESS 1239 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 1240 1241 forkee_status_exited(status, exitval2); 1242 1243 DPRINTF("Before exiting of the child process\n"); 1244 _exit(exitval); 1245 } 1246 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1247 1248 DPRINTF("Before calling %s() for the child - expected exited\n", 1249 TWAIT_FNAME); 1250 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1251 1252 validate_status_exited(status, exitval); 1253 1254 DPRINTF("Before calling %s() for the child - expected no process\n", 1255 TWAIT_FNAME); 1256 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1257 } 1258 1259 #define TRACEME_VFORK_FORK_TEST(name,fun) \ 1260 ATF_TC(name); \ 1261 ATF_TC_HEAD(name, tc) \ 1262 { \ 1263 atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) " \ 1264 "called from vfork(2)ed child"); \ 1265 } \ 1266 \ 1267 ATF_TC_BODY(name, tc) \ 1268 { \ 1269 \ 1270 traceme_vfork_fork_body(fun); \ 1271 } 1272 1273 TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork) 1274 TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork) 1275 1276 /// ---------------------------------------------------------------------------- 1277 1278 #if defined(TWAIT_HAVE_PID) 1279 static void 1280 fork2_body(const char *fn, bool masked, bool ignored) 1281 { 1282 const int exitval = 5; 1283 const int exitval2 = 0; /* Match exit status from /bin/echo */ 1284 const int sigval = SIGSTOP; 1285 pid_t child, child2 = 0, wpid; 1286 #if defined(TWAIT_HAVE_STATUS) 1287 int status; 1288 #endif 1289 ptrace_state_t state; 1290 const int slen = sizeof(state); 1291 ptrace_event_t event; 1292 const int elen = sizeof(event); 1293 struct sigaction sa; 1294 struct ptrace_siginfo info; 1295 sigset_t intmask; 1296 struct kinfo_proc2 kp; 1297 size_t len = sizeof(kp); 1298 1299 int name[6]; 1300 const size_t namelen = __arraycount(name); 1301 sigset_t set; 1302 ki_sigset_t kp_sigmask; 1303 ki_sigset_t kp_sigignore; 1304 1305 char * const arg[] = { __UNCONST("/bin/echo"), NULL }; 1306 1307 DPRINTF("Before forking process PID=%d\n", getpid()); 1308 SYSCALL_REQUIRE((child = fork()) != -1); 1309 if (child == 0) { 1310 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1311 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1312 1313 if (masked) { 1314 sigemptyset(&intmask); 1315 sigaddset(&intmask, SIGTRAP); 1316 sigprocmask(SIG_BLOCK, &intmask, NULL); 1317 } 1318 1319 if (ignored) { 1320 memset(&sa, 0, sizeof(sa)); 1321 sa.sa_handler = SIG_IGN; 1322 sigemptyset(&sa.sa_mask); 1323 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 1324 } 1325 1326 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1327 FORKEE_ASSERT(raise(sigval) == 0); 1328 1329 if (strcmp(fn, "spawn") == 0) { 1330 FORKEE_ASSERT_EQ(posix_spawn(&child2, 1331 arg[0], NULL, NULL, arg, NULL), 0); 1332 } else { 1333 if (strcmp(fn, "fork") == 0) { 1334 FORKEE_ASSERT((child2 = fork()) != -1); 1335 } else { 1336 FORKEE_ASSERT((child2 = vfork()) != -1); 1337 } 1338 if (child2 == 0) 1339 _exit(exitval2); 1340 } 1341 1342 FORKEE_REQUIRE_SUCCESS 1343 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 1344 1345 forkee_status_exited(status, exitval2); 1346 1347 DPRINTF("Before exiting of the child process\n"); 1348 _exit(exitval); 1349 } 1350 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1351 1352 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1353 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1354 1355 validate_status_stopped(status, sigval); 1356 1357 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1358 SYSCALL_REQUIRE( 1359 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1360 1361 DPRINTF("Before checking siginfo_t\n"); 1362 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1363 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1364 1365 name[0] = CTL_KERN, 1366 name[1] = KERN_PROC2, 1367 name[2] = KERN_PROC_PID; 1368 name[3] = child; 1369 name[4] = sizeof(kp); 1370 name[5] = 1; 1371 1372 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1373 1374 kp_sigmask = kp.p_sigmask; 1375 kp_sigignore = kp.p_sigignore; 1376 1377 DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", 1378 strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "", 1379 strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "", 1380 strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "", 1381 strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child); 1382 event.pe_set_event = 0; 1383 if (strcmp(fn, "spawn") == 0) 1384 event.pe_set_event |= PTRACE_POSIX_SPAWN; 1385 if (strcmp(fn, "fork") == 0) 1386 event.pe_set_event |= PTRACE_FORK; 1387 if (strcmp(fn, "vfork") == 0) 1388 event.pe_set_event |= PTRACE_VFORK; 1389 if (strcmp(fn, "vforkdone") == 0) 1390 event.pe_set_event |= PTRACE_VFORK_DONE; 1391 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1392 1393 /* 1394 * Ignore interception of the SIGCHLD signals. 1395 * 1396 * SIGCHLD once blocked is discarded by the kernel as it has the 1397 * SA_IGNORE property. During the fork(2) operation all signals can be 1398 * shortly blocked and missed (unless there is a registered signal 1399 * handler in the traced child). This leads to a race in this test if 1400 * there would be an intention to catch SIGCHLD. 1401 */ 1402 sigemptyset(&set); 1403 sigaddset(&set, SIGCHLD); 1404 SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1); 1405 1406 DPRINTF("Before resuming the child process where it left off and " 1407 "without signal to be sent\n"); 1408 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1409 1410 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 1411 strcmp(fn, "vfork") == 0) { 1412 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 1413 child); 1414 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1415 child); 1416 1417 validate_status_stopped(status, SIGTRAP); 1418 1419 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1420 1421 if (masked) { 1422 DPRINTF("kp_sigmask=" 1423 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1424 PRIx32 "\n", 1425 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1426 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1427 1428 DPRINTF("kp.p_sigmask=" 1429 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1430 PRIx32 "\n", 1431 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1432 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1433 1434 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask, 1435 SIGTRAP)); 1436 } 1437 1438 if (ignored) { 1439 DPRINTF("kp_sigignore=" 1440 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1441 PRIx32 "\n", 1442 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1443 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1444 1445 DPRINTF("kp.p_sigignore=" 1446 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1447 PRIx32 "\n", 1448 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1449 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1450 1451 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore, 1452 SIGTRAP)); 1453 } 1454 1455 SYSCALL_REQUIRE( 1456 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1457 if (strcmp(fn, "spawn") == 0) { 1458 ATF_REQUIRE_EQ( 1459 state.pe_report_event & PTRACE_POSIX_SPAWN, 1460 PTRACE_POSIX_SPAWN); 1461 } 1462 if (strcmp(fn, "fork") == 0) { 1463 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 1464 PTRACE_FORK); 1465 } 1466 if (strcmp(fn, "vfork") == 0) { 1467 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 1468 PTRACE_VFORK); 1469 } 1470 1471 child2 = state.pe_other_pid; 1472 DPRINTF("Reported ptrace event with forkee %d\n", child2); 1473 1474 DPRINTF("Before calling %s() for the forkee %d of the child " 1475 "%d\n", TWAIT_FNAME, child2, child); 1476 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 1477 child2); 1478 1479 validate_status_stopped(status, SIGTRAP); 1480 1481 name[3] = child2; 1482 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1483 1484 if (masked) { 1485 DPRINTF("kp_sigmask=" 1486 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1487 PRIx32 "\n", 1488 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1489 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1490 1491 DPRINTF("kp.p_sigmask=" 1492 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1493 PRIx32 "\n", 1494 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1495 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1496 1497 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask, 1498 SIGTRAP)); 1499 } 1500 1501 if (ignored) { 1502 DPRINTF("kp_sigignore=" 1503 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1504 PRIx32 "\n", 1505 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1506 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1507 1508 DPRINTF("kp.p_sigignore=" 1509 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1510 PRIx32 "\n", 1511 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1512 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1513 1514 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore, 1515 SIGTRAP)); 1516 } 1517 1518 SYSCALL_REQUIRE( 1519 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 1520 if (strcmp(fn, "spawn") == 0) { 1521 ATF_REQUIRE_EQ( 1522 state.pe_report_event & PTRACE_POSIX_SPAWN, 1523 PTRACE_POSIX_SPAWN); 1524 } 1525 if (strcmp(fn, "fork") == 0) { 1526 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 1527 PTRACE_FORK); 1528 } 1529 if (strcmp(fn, "vfork") == 0) { 1530 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 1531 PTRACE_VFORK); 1532 } 1533 1534 ATF_REQUIRE_EQ(state.pe_other_pid, child); 1535 1536 DPRINTF("Before resuming the forkee process where it left off " 1537 "and without signal to be sent\n"); 1538 SYSCALL_REQUIRE( 1539 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 1540 1541 DPRINTF("Before resuming the child process where it left off " 1542 "and without signal to be sent\n"); 1543 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1544 } 1545 1546 if (strcmp(fn, "vforkdone") == 0) { 1547 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 1548 child); 1549 TWAIT_REQUIRE_SUCCESS( 1550 wpid = TWAIT_GENERIC(child, &status, 0), child); 1551 1552 validate_status_stopped(status, SIGTRAP); 1553 1554 name[3] = child; 1555 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1556 1557 /* 1558 * SIGCHLD is now pending in the signal queue and 1559 * the kernel presents it to userland as a masked signal. 1560 */ 1561 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 1562 1563 if (masked) { 1564 DPRINTF("kp_sigmask=" 1565 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1566 PRIx32 "\n", 1567 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1568 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1569 1570 DPRINTF("kp.p_sigmask=" 1571 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1572 PRIx32 "\n", 1573 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1574 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1575 1576 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask, 1577 SIGTRAP)); 1578 } 1579 1580 if (ignored) { 1581 DPRINTF("kp_sigignore=" 1582 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1583 PRIx32 "\n", 1584 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1585 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1586 1587 DPRINTF("kp.p_sigignore=" 1588 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 1589 PRIx32 "\n", 1590 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1591 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1592 1593 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore, 1594 SIGTRAP)); 1595 } 1596 1597 SYSCALL_REQUIRE( 1598 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1599 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 1600 1601 child2 = state.pe_other_pid; 1602 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 1603 child2); 1604 1605 DPRINTF("Before resuming the child process where it left off " 1606 "and without signal to be sent\n"); 1607 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1608 } 1609 1610 if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || 1611 strcmp(fn, "vfork") == 0) { 1612 DPRINTF("Before calling %s() for the forkee - expected exited" 1613 "\n", TWAIT_FNAME); 1614 TWAIT_REQUIRE_SUCCESS( 1615 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 1616 1617 validate_status_exited(status, exitval2); 1618 1619 DPRINTF("Before calling %s() for the forkee - expected no " 1620 "process\n", TWAIT_FNAME); 1621 TWAIT_REQUIRE_FAILURE(ECHILD, 1622 wpid = TWAIT_GENERIC(child2, &status, 0)); 1623 } 1624 1625 DPRINTF("Before calling %s() for the child - expected exited\n", 1626 TWAIT_FNAME); 1627 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1628 1629 validate_status_exited(status, exitval); 1630 1631 DPRINTF("Before calling %s() for the child - expected no process\n", 1632 TWAIT_FNAME); 1633 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1634 } 1635 1636 #define FORK2_TEST(name,fn,masked,ignored) \ 1637 ATF_TC(name); \ 1638 ATF_TC_HEAD(name, tc) \ 1639 { \ 1640 atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught " \ 1641 "regardless of signal %s%s", \ 1642 masked ? "masked" : "", ignored ? "ignored" : ""); \ 1643 } \ 1644 \ 1645 ATF_TC_BODY(name, tc) \ 1646 { \ 1647 \ 1648 fork2_body(fn, masked, ignored); \ 1649 } 1650 1651 FORK2_TEST(posix_spawn_signalmasked, "spawn", true, false) 1652 FORK2_TEST(posix_spawn_signalignored, "spawn", false, true) 1653 FORK2_TEST(fork_signalmasked, "fork", true, false) 1654 FORK2_TEST(fork_signalignored, "fork", false, true) 1655 FORK2_TEST(vfork_signalmasked, "vfork", true, false) 1656 FORK2_TEST(vfork_signalignored, "vfork", false, true) 1657 FORK2_TEST(vforkdone_signalmasked, "vforkdone", true, false) 1658 FORK2_TEST(vforkdone_signalignored, "vforkdone", false, true) 1659 #endif 1660 1661 #define ATF_TP_ADD_TCS_PTRACE_WAIT_FORK() \ 1662 ATF_TP_ADD_TC(tp, fork1); \ 1663 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); \ 1664 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); \ 1665 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); \ 1666 ATF_TP_ADD_TC(tp, fork5); \ 1667 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); \ 1668 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); \ 1669 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); \ 1670 ATF_TP_ADD_TC(tp, fork9); \ 1671 ATF_TP_ADD_TC_HAVE_PID(tp, fork10); \ 1672 ATF_TP_ADD_TC_HAVE_PID(tp, fork11); \ 1673 ATF_TP_ADD_TC_HAVE_PID(tp, fork12); \ 1674 ATF_TP_ADD_TC(tp, fork13); \ 1675 ATF_TP_ADD_TC_HAVE_PID(tp, fork14); \ 1676 ATF_TP_ADD_TC_HAVE_PID(tp, fork15); \ 1677 ATF_TP_ADD_TC_HAVE_PID(tp, fork16); \ 1678 ATF_TP_ADD_TC_HAVE_PID(tp, fork_setpgid); \ 1679 ATF_TP_ADD_TC(tp, vfork1); \ 1680 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); \ 1681 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); \ 1682 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); \ 1683 ATF_TP_ADD_TC(tp, vfork5); \ 1684 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); \ 1685 ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); \ 1686 ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); \ 1687 ATF_TP_ADD_TC(tp, vfork9); \ 1688 ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); \ 1689 ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); \ 1690 ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); \ 1691 ATF_TP_ADD_TC(tp, vfork13); \ 1692 ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); \ 1693 ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); \ 1694 ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); \ 1695 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_setpgid); \ 1696 ATF_TP_ADD_TC(tp, posix_spawn1); \ 1697 ATF_TP_ADD_TC(tp, posix_spawn2); \ 1698 ATF_TP_ADD_TC(tp, posix_spawn3); \ 1699 ATF_TP_ADD_TC(tp, posix_spawn4); \ 1700 ATF_TP_ADD_TC(tp, posix_spawn5); \ 1701 ATF_TP_ADD_TC(tp, posix_spawn6); \ 1702 ATF_TP_ADD_TC(tp, posix_spawn7); \ 1703 ATF_TP_ADD_TC(tp, posix_spawn8); \ 1704 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); \ 1705 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); \ 1706 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); \ 1707 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); \ 1708 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); \ 1709 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); \ 1710 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); \ 1711 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); \ 1712 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_setpgid); \ 1713 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1); \ 1714 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2); \ 1715 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3); \ 1716 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4); \ 1717 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5); \ 1718 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6); \ 1719 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7); \ 1720 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8); \ 1721 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9); \ 1722 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10); \ 1723 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11); \ 1724 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12); \ 1725 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13); \ 1726 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14); \ 1727 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15); \ 1728 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16); \ 1729 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_setpgid); \ 1730 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1); \ 1731 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2); \ 1732 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3); \ 1733 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4); \ 1734 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5); \ 1735 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6); \ 1736 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7); \ 1737 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8); \ 1738 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9); \ 1739 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10); \ 1740 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11); \ 1741 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12); \ 1742 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13); \ 1743 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14); \ 1744 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15); \ 1745 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16); \ 1746 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_setpgid); \ 1747 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1); \ 1748 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2); \ 1749 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3); \ 1750 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4); \ 1751 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5); \ 1752 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6); \ 1753 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7); \ 1754 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8); \ 1755 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9); \ 1756 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10); \ 1757 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11); \ 1758 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12); \ 1759 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13); \ 1760 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14); \ 1761 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15); \ 1762 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16); \ 1763 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_setpgid); \ 1764 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); \ 1765 ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); \ 1766 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); \ 1767 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); \ 1768 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); \ 1769 ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); \ 1770 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); \ 1771 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); \ 1772 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner); \ 1773 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker); \ 1774 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker); \ 1775 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone); \ 1776 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner); \ 1777 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker); \ 1778 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker); \ 1779 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone); \ 1780 ATF_TP_ADD_TC(tp, traceme_vfork_fork); \ 1781 ATF_TP_ADD_TC(tp, traceme_vfork_vfork); \ 1782 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalmasked); \ 1783 ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalignored); \ 1784 ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalmasked); \ 1785 ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalignored); \ 1786 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalmasked); \ 1787 ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalignored); \ 1788 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalmasked); \ 1789 ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalignored); 1790