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