t_ptrace_clone_wait.h revision 1.1 1 /* $NetBSD: t_ptrace_clone_wait.h,v 1.1 2020/05/04 22:15:23 kamil Exp $ */
2
3 /*-
4 * Copyright (c) 2016, 2017, 2018, 2019 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 clone_body(int flags, bool trackfork, bool trackvfork,
32 bool trackvforkdone)
33 {
34 const int exitval = 5;
35 const int exitval2 = 15;
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 const size_t stack_size = 1024 * 1024;
47 void *stack, *stack_base;
48
49 stack = malloc(stack_size);
50 ATF_REQUIRE(stack != NULL);
51
52 #ifdef __MACHINE_STACK_GROWS_UP
53 stack_base = stack;
54 #else
55 stack_base = (char *)stack + stack_size;
56 #endif
57
58 DPRINTF("Before forking process PID=%d\n", getpid());
59 SYSCALL_REQUIRE((child = fork()) != -1);
60 if (child == 0) {
61 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63
64 DPRINTF("Before raising %s from child\n", strsignal(sigval));
65 FORKEE_ASSERT(raise(sigval) == 0);
66
67 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
68 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
69
70 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
71 child2);
72
73 // XXX WALLSIG?
74 FORKEE_REQUIRE_SUCCESS
75 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
76
77 forkee_status_exited(status, exitval2);
78
79 DPRINTF("Before exiting of the child process\n");
80 _exit(exitval);
81 }
82 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
83
84 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
85 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
86
87 validate_status_stopped(status, sigval);
88
89 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
90 trackfork ? "|PTRACE_FORK" : "",
91 trackvfork ? "|PTRACE_VFORK" : "",
92 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
93 event.pe_set_event = 0;
94 if (trackfork)
95 event.pe_set_event |= PTRACE_FORK;
96 if (trackvfork)
97 event.pe_set_event |= PTRACE_VFORK;
98 if (trackvforkdone)
99 event.pe_set_event |= PTRACE_VFORK_DONE;
100 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
101
102 DPRINTF("Before resuming the child process where it left off and "
103 "without signal to be sent\n");
104 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
105
106 #if defined(TWAIT_HAVE_PID)
107 if ((trackfork && !(flags & CLONE_VFORK)) ||
108 (trackvfork && (flags & CLONE_VFORK))) {
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 (trackfork && !(flags & CLONE_VFORK)) {
119 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
120 PTRACE_FORK);
121 }
122 if (trackvfork && (flags & CLONE_VFORK)) {
123 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
124 PTRACE_VFORK);
125 }
126
127 child2 = state.pe_other_pid;
128 DPRINTF("Reported ptrace event with forkee %d\n", child2);
129
130 DPRINTF("Before calling %s() for the forkee %d of the child "
131 "%d\n", TWAIT_FNAME, child2, child);
132 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
133 child2);
134
135 validate_status_stopped(status, SIGTRAP);
136
137 SYSCALL_REQUIRE(
138 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
139 if (trackfork && !(flags & CLONE_VFORK)) {
140 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
141 PTRACE_FORK);
142 }
143 if (trackvfork && (flags & CLONE_VFORK)) {
144 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
145 PTRACE_VFORK);
146 }
147
148 ATF_REQUIRE_EQ(state.pe_other_pid, child);
149
150 DPRINTF("Before resuming the forkee process where it left off "
151 "and without signal to be sent\n");
152 SYSCALL_REQUIRE(
153 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
154
155 DPRINTF("Before resuming the child process where it left off "
156 "and without signal to be sent\n");
157 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
158 }
159 #endif
160
161 if (trackvforkdone && (flags & CLONE_VFORK)) {
162 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
163 child);
164 TWAIT_REQUIRE_SUCCESS(
165 wpid = TWAIT_GENERIC(child, &status, 0), child);
166
167 validate_status_stopped(status, SIGTRAP);
168
169 SYSCALL_REQUIRE(
170 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
171 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
172
173 child2 = state.pe_other_pid;
174 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
175 child2);
176
177 DPRINTF("Before resuming the child process where it left off "
178 "and without signal to be sent\n");
179 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
180 }
181
182 #if defined(TWAIT_HAVE_PID)
183 if ((trackfork && !(flags & CLONE_VFORK)) ||
184 (trackvfork && (flags & CLONE_VFORK))) {
185 DPRINTF("Before calling %s() for the forkee - expected exited"
186 "\n", TWAIT_FNAME);
187 TWAIT_REQUIRE_SUCCESS(
188 wpid = TWAIT_GENERIC(child2, &status, 0), child2);
189
190 validate_status_exited(status, exitval2);
191
192 DPRINTF("Before calling %s() for the forkee - expected no "
193 "process\n", TWAIT_FNAME);
194 TWAIT_REQUIRE_FAILURE(ECHILD,
195 wpid = TWAIT_GENERIC(child2, &status, 0));
196 }
197 #endif
198
199 DPRINTF("Before calling %s() for the child - expected stopped "
200 "SIGCHLD\n", TWAIT_FNAME);
201 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
202
203 validate_status_stopped(status, SIGCHLD);
204
205 DPRINTF("Before resuming the child process where it left off and "
206 "without signal to be sent\n");
207 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
208
209 DPRINTF("Before calling %s() for the child - expected exited\n",
210 TWAIT_FNAME);
211 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
212
213 validate_status_exited(status, exitval);
214
215 DPRINTF("Before calling %s() for the child - expected no process\n",
216 TWAIT_FNAME);
217 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
218 }
219
220 #define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \
221 ATF_TC(name); \
222 ATF_TC_HEAD(name, tc) \
223 { \
224 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \
225 "called with 0%s%s%s in EVENT_MASK", \
226 #flags, \
227 tfork ? "|PTRACE_FORK" : "", \
228 tvfork ? "|PTRACE_VFORK" : "", \
229 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \
230 } \
231 \
232 ATF_TC_BODY(name, tc) \
233 { \
234 \
235 clone_body(flags, tfork, tvfork, tvforkdone); \
236 }
237
238 CLONE_TEST(clone1, 0, false, false, false)
239 #if defined(TWAIT_HAVE_PID)
240 CLONE_TEST(clone2, 0, true, false, false)
241 CLONE_TEST(clone3, 0, false, true, false)
242 CLONE_TEST(clone4, 0, true, true, false)
243 #endif
244 CLONE_TEST(clone5, 0, false, false, true)
245 #if defined(TWAIT_HAVE_PID)
246 CLONE_TEST(clone6, 0, true, false, true)
247 CLONE_TEST(clone7, 0, false, true, true)
248 CLONE_TEST(clone8, 0, true, true, true)
249 #endif
250
251 CLONE_TEST(clone_vm1, CLONE_VM, false, false, false)
252 #if defined(TWAIT_HAVE_PID)
253 CLONE_TEST(clone_vm2, CLONE_VM, true, false, false)
254 CLONE_TEST(clone_vm3, CLONE_VM, false, true, false)
255 CLONE_TEST(clone_vm4, CLONE_VM, true, true, false)
256 #endif
257 CLONE_TEST(clone_vm5, CLONE_VM, false, false, true)
258 #if defined(TWAIT_HAVE_PID)
259 CLONE_TEST(clone_vm6, CLONE_VM, true, false, true)
260 CLONE_TEST(clone_vm7, CLONE_VM, false, true, true)
261 CLONE_TEST(clone_vm8, CLONE_VM, true, true, true)
262 #endif
263
264 CLONE_TEST(clone_fs1, CLONE_FS, false, false, false)
265 #if defined(TWAIT_HAVE_PID)
266 CLONE_TEST(clone_fs2, CLONE_FS, true, false, false)
267 CLONE_TEST(clone_fs3, CLONE_FS, false, true, false)
268 CLONE_TEST(clone_fs4, CLONE_FS, true, true, false)
269 #endif
270 CLONE_TEST(clone_fs5, CLONE_FS, false, false, true)
271 #if defined(TWAIT_HAVE_PID)
272 CLONE_TEST(clone_fs6, CLONE_FS, true, false, true)
273 CLONE_TEST(clone_fs7, CLONE_FS, false, true, true)
274 CLONE_TEST(clone_fs8, CLONE_FS, true, true, true)
275 #endif
276
277 CLONE_TEST(clone_files1, CLONE_FILES, false, false, false)
278 #if defined(TWAIT_HAVE_PID)
279 CLONE_TEST(clone_files2, CLONE_FILES, true, false, false)
280 CLONE_TEST(clone_files3, CLONE_FILES, false, true, false)
281 CLONE_TEST(clone_files4, CLONE_FILES, true, true, false)
282 #endif
283 CLONE_TEST(clone_files5, CLONE_FILES, false, false, true)
284 #if defined(TWAIT_HAVE_PID)
285 CLONE_TEST(clone_files6, CLONE_FILES, true, false, true)
286 CLONE_TEST(clone_files7, CLONE_FILES, false, true, true)
287 CLONE_TEST(clone_files8, CLONE_FILES, true, true, true)
288 #endif
289
290 //CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false)
291 #if defined(TWAIT_HAVE_PID)
292 //CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false)
293 //CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false)
294 //CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false)
295 #endif
296 //CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true)
297 #if defined(TWAIT_HAVE_PID)
298 //CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true)
299 //CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true)
300 //CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true)
301 #endif
302
303 CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false)
304 #if defined(TWAIT_HAVE_PID)
305 CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false)
306 CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false)
307 CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false)
308 #endif
309 CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true)
310 #if defined(TWAIT_HAVE_PID)
311 CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true)
312 CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true)
313 CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true)
314 #endif
315
316 /// ----------------------------------------------------------------------------
317
318 #if defined(TWAIT_HAVE_PID)
319 static void
320 clone_body2(int flags, bool masked, bool ignored)
321 {
322 const int exitval = 5;
323 const int exitval2 = 15;
324 const int sigval = SIGSTOP;
325 pid_t child, child2 = 0, wpid;
326 #if defined(TWAIT_HAVE_STATUS)
327 int status;
328 #endif
329 ptrace_state_t state;
330 const int slen = sizeof(state);
331 ptrace_event_t event;
332 const int elen = sizeof(event);
333 struct sigaction sa;
334 struct ptrace_siginfo info;
335 sigset_t intmask;
336 struct kinfo_proc2 kp;
337 size_t len = sizeof(kp);
338
339 int name[6];
340 const size_t namelen = __arraycount(name);
341 ki_sigset_t kp_sigmask;
342 ki_sigset_t kp_sigignore;
343
344 const size_t stack_size = 1024 * 1024;
345 void *stack, *stack_base;
346
347 stack = malloc(stack_size);
348 ATF_REQUIRE(stack != NULL);
349
350 #ifdef __MACHINE_STACK_GROWS_UP
351 stack_base = stack;
352 #else
353 stack_base = (char *)stack + stack_size;
354 #endif
355
356 SYSCALL_REQUIRE((child = fork()) != -1);
357 if (child == 0) {
358 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
359 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
360
361 if (masked) {
362 sigemptyset(&intmask);
363 sigaddset(&intmask, SIGTRAP);
364 sigprocmask(SIG_BLOCK, &intmask, NULL);
365 }
366
367 if (ignored) {
368 memset(&sa, 0, sizeof(sa));
369 sa.sa_handler = SIG_IGN;
370 sigemptyset(&sa.sa_mask);
371 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
372 }
373 DPRINTF("Before raising %s from child\n", strsignal(sigval));
374 FORKEE_ASSERT(raise(sigval) == 0);
375
376 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
377 flags);
378 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
379 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
380
381 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
382 child2);
383
384 // XXX WALLSIG?
385 FORKEE_REQUIRE_SUCCESS
386 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
387
388 forkee_status_exited(status, exitval2);
389
390 DPRINTF("Before exiting of the child process\n");
391 _exit(exitval);
392 }
393 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
394
395 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
396 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
397
398 validate_status_stopped(status, sigval);
399
400 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
401 SYSCALL_REQUIRE(
402 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
403
404 DPRINTF("Before checking siginfo_t\n");
405 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
406 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
407
408 name[0] = CTL_KERN,
409 name[1] = KERN_PROC2,
410 name[2] = KERN_PROC_PID;
411 name[3] = child;
412 name[4] = sizeof(kp);
413 name[5] = 1;
414
415 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
416
417 if (masked)
418 kp_sigmask = kp.p_sigmask;
419
420 if (ignored)
421 kp_sigignore = kp.p_sigignore;
422
423 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in "
424 "EVENT_MASK for the child %d\n", child);
425 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE;
426 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
427
428 DPRINTF("Before resuming the child process where it left off and "
429 "without signal to be sent\n");
430 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
431
432 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
433 child);
434 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
435 child);
436
437 validate_status_stopped(status, SIGTRAP);
438
439 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
440
441 if (masked) {
442 DPRINTF("kp_sigmask="
443 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
444 PRIx32 "\n",
445 kp_sigmask.__bits[0], kp_sigmask.__bits[1],
446 kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
447
448 DPRINTF("kp.p_sigmask="
449 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
450 PRIx32 "\n",
451 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
452 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
453
454 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
455 sizeof(kp_sigmask)));
456 }
457
458 if (ignored) {
459 DPRINTF("kp_sigignore="
460 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
461 PRIx32 "\n",
462 kp_sigignore.__bits[0], kp_sigignore.__bits[1],
463 kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
464
465 DPRINTF("kp.p_sigignore="
466 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
467 PRIx32 "\n",
468 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
469 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
470
471 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
472 sizeof(kp_sigignore)));
473 }
474
475 SYSCALL_REQUIRE(
476 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
477 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event,
478 child2);
479 if (!(flags & CLONE_VFORK)) {
480 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
481 PTRACE_FORK);
482 } else {
483 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
484 PTRACE_VFORK);
485 }
486
487 child2 = state.pe_other_pid;
488 DPRINTF("Reported ptrace event with forkee %d\n", child2);
489
490 DPRINTF("Before calling %s() for the forkee %d of the child "
491 "%d\n", TWAIT_FNAME, child2, child);
492 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
493 child2);
494
495 validate_status_stopped(status, SIGTRAP);
496
497 name[3] = child2;
498 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
499
500 if (masked) {
501 DPRINTF("kp_sigmask="
502 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
503 PRIx32 "\n",
504 kp_sigmask.__bits[0], kp_sigmask.__bits[1],
505 kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
506
507 DPRINTF("kp.p_sigmask="
508 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
509 PRIx32 "\n",
510 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
511 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
512
513 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
514 sizeof(kp_sigmask)));
515 }
516
517 if (ignored) {
518 DPRINTF("kp_sigignore="
519 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
520 PRIx32 "\n",
521 kp_sigignore.__bits[0], kp_sigignore.__bits[1],
522 kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
523
524 DPRINTF("kp.p_sigignore="
525 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
526 PRIx32 "\n",
527 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
528 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
529
530 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
531 sizeof(kp_sigignore)));
532 }
533
534 SYSCALL_REQUIRE(
535 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
536 if (!(flags & CLONE_VFORK)) {
537 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
538 PTRACE_FORK);
539 } else {
540 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
541 PTRACE_VFORK);
542 }
543
544 ATF_REQUIRE_EQ(state.pe_other_pid, child);
545
546 DPRINTF("Before resuming the forkee process where it left off "
547 "and without signal to be sent\n");
548 SYSCALL_REQUIRE(
549 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
550
551 DPRINTF("Before resuming the child process where it left off "
552 "and without signal to be sent\n");
553 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
554
555 if (flags & CLONE_VFORK) {
556 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
557 child);
558 TWAIT_REQUIRE_SUCCESS(
559 wpid = TWAIT_GENERIC(child, &status, 0), child);
560
561 validate_status_stopped(status, SIGTRAP);
562
563 name[3] = child;
564 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
565
566 /*
567 * SIGCHLD is now pending in the signal queue and
568 * the kernel presents it to userland as a masked signal.
569 */
570 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
571
572 if (masked) {
573 DPRINTF("kp_sigmask="
574 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
575 PRIx32 "\n",
576 kp_sigmask.__bits[0], kp_sigmask.__bits[1],
577 kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
578
579 DPRINTF("kp.p_sigmask="
580 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
581 PRIx32 "\n",
582 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
583 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
584
585 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
586 sizeof(kp_sigmask)));
587 }
588
589 if (ignored) {
590 DPRINTF("kp_sigignore="
591 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
592 PRIx32 "\n",
593 kp_sigignore.__bits[0], kp_sigignore.__bits[1],
594 kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
595
596 DPRINTF("kp.p_sigignore="
597 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
598 PRIx32 "\n",
599 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
600 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
601
602 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
603 sizeof(kp_sigignore)));
604 }
605
606 SYSCALL_REQUIRE(
607 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
608 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
609
610 child2 = state.pe_other_pid;
611 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
612 child2);
613
614 DPRINTF("Before resuming the child process where it left off "
615 "and without signal to be sent\n");
616 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
617 }
618
619 DPRINTF("Before calling %s() for the forkee - expected exited"
620 "\n", TWAIT_FNAME);
621 TWAIT_REQUIRE_SUCCESS(
622 wpid = TWAIT_GENERIC(child2, &status, 0), child2);
623
624 validate_status_exited(status, exitval2);
625
626 DPRINTF("Before calling %s() for the forkee - expected no "
627 "process\n", TWAIT_FNAME);
628 TWAIT_REQUIRE_FAILURE(ECHILD,
629 wpid = TWAIT_GENERIC(child2, &status, 0));
630
631 DPRINTF("Before calling %s() for the child - expected stopped "
632 "SIGCHLD\n", TWAIT_FNAME);
633 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
634
635 validate_status_stopped(status, SIGCHLD);
636
637 DPRINTF("Before resuming the child process where it left off and "
638 "without signal to be sent\n");
639 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
640
641 DPRINTF("Before calling %s() for the child - expected exited\n",
642 TWAIT_FNAME);
643 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
644
645 validate_status_exited(status, exitval);
646
647 DPRINTF("Before calling %s() for the child - expected no process\n",
648 TWAIT_FNAME);
649 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
650 }
651
652 #define CLONE_TEST2(name,flags,masked,ignored) \
653 ATF_TC(name); \
654 ATF_TC_HEAD(name, tc) \
655 { \
656 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\
657 " regardless of signal %s%s", \
658 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \
659 } \
660 \
661 ATF_TC_BODY(name, tc) \
662 { \
663 \
664 clone_body2(flags, masked, ignored); \
665 }
666
667 CLONE_TEST2(clone_signalignored, 0, true, false)
668 CLONE_TEST2(clone_signalmasked, 0, false, true)
669 CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false)
670 CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true)
671 CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false)
672 CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true)
673 CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false)
674 CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true)
675 //CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX
676 //CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX
677 CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false)
678 CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true)
679 #endif
680
681 /// ----------------------------------------------------------------------------
682
683 #if defined(TWAIT_HAVE_PID)
684 static void
685 traceme_vfork_clone_body(int flags)
686 {
687 const int exitval = 5;
688 const int exitval2 = 15;
689 pid_t child, child2 = 0, wpid;
690 #if defined(TWAIT_HAVE_STATUS)
691 int status;
692 #endif
693
694 const size_t stack_size = 1024 * 1024;
695 void *stack, *stack_base;
696
697 stack = malloc(stack_size);
698 ATF_REQUIRE(stack != NULL);
699
700 #ifdef __MACHINE_STACK_GROWS_UP
701 stack_base = stack;
702 #else
703 stack_base = (char *)stack + stack_size;
704 #endif
705
706 SYSCALL_REQUIRE((child = vfork()) != -1);
707 if (child == 0) {
708 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
709 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
710
711 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
712 flags);
713 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
714 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
715
716 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
717 child2);
718
719 // XXX WALLSIG?
720 FORKEE_REQUIRE_SUCCESS
721 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
722
723 forkee_status_exited(status, exitval2);
724
725 DPRINTF("Before exiting of the child process\n");
726 _exit(exitval);
727 }
728 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
729
730 DPRINTF("Before calling %s() for the child - expected exited\n",
731 TWAIT_FNAME);
732 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
733
734 validate_status_exited(status, exitval);
735
736 DPRINTF("Before calling %s() for the child - expected no process\n",
737 TWAIT_FNAME);
738 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
739 }
740
741 #define TRACEME_VFORK_CLONE_TEST(name,flags) \
742 ATF_TC(name); \
743 ATF_TC_HEAD(name, tc) \
744 { \
745 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \
746 "handled correctly with vfork(2)ed tracer", \
747 #flags); \
748 } \
749 \
750 ATF_TC_BODY(name, tc) \
751 { \
752 \
753 traceme_vfork_clone_body(flags); \
754 }
755
756 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0)
757 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM)
758 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS)
759 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES)
760 //TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX
761 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK)
762 #endif
763
764 #define ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE() \
765 ATF_TP_ADD_TC(tp, clone1); \
766 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); \
767 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); \
768 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); \
769 ATF_TP_ADD_TC(tp, clone5); \
770 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); \
771 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); \
772 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); \
773 ATF_TP_ADD_TC(tp, clone_vm1); \
774 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); \
775 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); \
776 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); \
777 ATF_TP_ADD_TC(tp, clone_vm5); \
778 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); \
779 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); \
780 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); \
781 ATF_TP_ADD_TC(tp, clone_fs1); \
782 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); \
783 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); \
784 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); \
785 ATF_TP_ADD_TC(tp, clone_fs5); \
786 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); \
787 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); \
788 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); \
789 ATF_TP_ADD_TC(tp, clone_files1); \
790 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); \
791 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); \
792 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); \
793 ATF_TP_ADD_TC(tp, clone_files5); \
794 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); \
795 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); \
796 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); \
797 ATF_TP_ADD_TC(tp, clone_vfork1); \
798 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); \
799 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); \
800 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); \
801 ATF_TP_ADD_TC(tp, clone_vfork5); \
802 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); \
803 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); \
804 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); \
805 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); \
806 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); \
807 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); \
808 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); \
809 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); \
810 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); \
811 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); \
812 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); \
813 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); \
814 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); \
815 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); \
816 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); \
817 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); \
818 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); \
819 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork);
820
821 // ATF_TP_ADD_TC(tp, clone_sighand1); // XXX
822 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX
823 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX
824 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX
825 // ATF_TP_ADD_TC(tp, clone_sighand5); // XXX
826 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX
827 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX
828 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX
829
830 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX
831 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX
832
833 // ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX
834