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