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