t_ptrace_fork_wait.h revision 1.8 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