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