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